ids.rs

  1use crate::Result;
  2use rpc::proto;
  3use sea_orm::{entity::prelude::*, DbErr};
  4use serde::{Deserialize, Serialize};
  5
  6#[macro_export]
  7macro_rules! id_type {
  8    ($name:ident) => {
  9        #[derive(
 10            Clone,
 11            Copy,
 12            Debug,
 13            Default,
 14            PartialEq,
 15            Eq,
 16            PartialOrd,
 17            Ord,
 18            Hash,
 19            Serialize,
 20            Deserialize,
 21            DeriveValueType,
 22        )]
 23        #[allow(missing_docs)]
 24        #[serde(transparent)]
 25        pub struct $name(pub i32);
 26
 27        impl $name {
 28            #[allow(unused)]
 29            #[allow(missing_docs)]
 30            pub const MAX: Self = Self(i32::MAX);
 31
 32            #[allow(unused)]
 33            #[allow(missing_docs)]
 34            pub fn from_proto(value: u64) -> Self {
 35                Self(value as i32)
 36            }
 37
 38            #[allow(unused)]
 39            #[allow(missing_docs)]
 40            pub fn to_proto(self) -> u64 {
 41                self.0 as u64
 42            }
 43        }
 44
 45        impl std::fmt::Display for $name {
 46            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
 47                self.0.fmt(f)
 48            }
 49        }
 50
 51        impl sea_orm::TryFromU64 for $name {
 52            fn try_from_u64(n: u64) -> Result<Self, DbErr> {
 53                Ok(Self(n.try_into().map_err(|_| {
 54                    DbErr::ConvertFromU64(concat!(
 55                        "error converting ",
 56                        stringify!($name),
 57                        " to u64"
 58                    ))
 59                })?))
 60            }
 61        }
 62
 63        impl sea_orm::sea_query::Nullable for $name {
 64            fn null() -> Value {
 65                Value::Int(None)
 66            }
 67        }
 68    };
 69}
 70
 71id_type!(AccessTokenId);
 72id_type!(BillingCustomerId);
 73id_type!(BillingSubscriptionId);
 74id_type!(BufferId);
 75id_type!(ChannelBufferCollaboratorId);
 76id_type!(ChannelChatParticipantId);
 77id_type!(ChannelId);
 78id_type!(ChannelMemberId);
 79id_type!(ContactId);
 80id_type!(DevServerId);
 81id_type!(ExtensionId);
 82id_type!(FlagId);
 83id_type!(FollowerId);
 84id_type!(HostedProjectId);
 85id_type!(MessageId);
 86id_type!(NotificationId);
 87id_type!(NotificationKindId);
 88id_type!(ProjectCollaboratorId);
 89id_type!(ProjectId);
 90id_type!(DevServerProjectId);
 91id_type!(ReplicaId);
 92id_type!(RoomId);
 93id_type!(RoomParticipantId);
 94id_type!(ServerId);
 95id_type!(SignupId);
 96id_type!(UserId);
 97
 98/// ChannelRole gives you permissions for both channels and calls.
 99#[derive(
100    Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash, Serialize,
101)]
102#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
103pub enum ChannelRole {
104    /// Admin can read/write and change permissions.
105    #[sea_orm(string_value = "admin")]
106    Admin,
107    /// Member can read/write, but not change pemissions.
108    #[sea_orm(string_value = "member")]
109    #[default]
110    Member,
111    /// Talker can read, but not write.
112    /// They can use microphones and the channel chat
113    #[sea_orm(string_value = "talker")]
114    Talker,
115    /// Guest can read, but not write.
116    /// They can not use microphones but can use the chat.
117    #[sea_orm(string_value = "guest")]
118    Guest,
119    /// Banned may not read.
120    #[sea_orm(string_value = "banned")]
121    Banned,
122}
123
124impl ChannelRole {
125    /// Returns true if this role is more powerful than the other role.
126    pub fn should_override(&self, other: Self) -> bool {
127        use ChannelRole::*;
128        match self {
129            Admin => matches!(other, Member | Banned | Talker | Guest),
130            Member => matches!(other, Banned | Talker | Guest),
131            Talker => matches!(other, Guest),
132            Banned => matches!(other, Guest),
133            Guest => false,
134        }
135    }
136
137    /// Returns the maximal role between the two
138    pub fn max(&self, other: Self) -> Self {
139        if self.should_override(other) {
140            *self
141        } else {
142            other
143        }
144    }
145
146    pub fn can_see_channel(&self, visibility: ChannelVisibility) -> bool {
147        use ChannelRole::*;
148        match self {
149            Admin | Member => true,
150            Guest | Talker => visibility == ChannelVisibility::Public,
151            Banned => false,
152        }
153    }
154
155    /// True if the role allows access to all descendant channels
156    pub fn can_see_all_descendants(&self) -> bool {
157        use ChannelRole::*;
158        match self {
159            Admin | Member => true,
160            Guest | Talker | Banned => false,
161        }
162    }
163
164    /// True if the role only allows access to public descendant channels
165    pub fn can_only_see_public_descendants(&self) -> bool {
166        use ChannelRole::*;
167        match self {
168            Guest | Talker => true,
169            Admin | Member | Banned => false,
170        }
171    }
172
173    /// True if the role can share screen/microphone/projects into rooms.
174    pub fn can_use_microphone(&self) -> bool {
175        use ChannelRole::*;
176        match self {
177            Admin | Member | Talker => true,
178            Guest | Banned => false,
179        }
180    }
181
182    /// True if the role can edit shared projects.
183    pub fn can_edit_projects(&self) -> bool {
184        use ChannelRole::*;
185        match self {
186            Admin | Member => true,
187            Talker | Guest | Banned => false,
188        }
189    }
190
191    /// True if the role can read shared projects.
192    pub fn can_read_projects(&self) -> bool {
193        use ChannelRole::*;
194        match self {
195            Admin | Member | Guest | Talker => true,
196            Banned => false,
197        }
198    }
199
200    pub fn requires_cla(&self) -> bool {
201        use ChannelRole::*;
202        match self {
203            Admin | Member => true,
204            Banned | Guest | Talker => false,
205        }
206    }
207}
208
209impl From<proto::ChannelRole> for ChannelRole {
210    fn from(value: proto::ChannelRole) -> Self {
211        match value {
212            proto::ChannelRole::Admin => ChannelRole::Admin,
213            proto::ChannelRole::Member => ChannelRole::Member,
214            proto::ChannelRole::Talker => ChannelRole::Talker,
215            proto::ChannelRole::Guest => ChannelRole::Guest,
216            proto::ChannelRole::Banned => ChannelRole::Banned,
217        }
218    }
219}
220
221impl Into<proto::ChannelRole> for ChannelRole {
222    fn into(self) -> proto::ChannelRole {
223        match self {
224            ChannelRole::Admin => proto::ChannelRole::Admin,
225            ChannelRole::Member => proto::ChannelRole::Member,
226            ChannelRole::Talker => proto::ChannelRole::Talker,
227            ChannelRole::Guest => proto::ChannelRole::Guest,
228            ChannelRole::Banned => proto::ChannelRole::Banned,
229        }
230    }
231}
232
233impl Into<i32> for ChannelRole {
234    fn into(self) -> i32 {
235        let proto: proto::ChannelRole = self.into();
236        proto.into()
237    }
238}
239
240/// ChannelVisibility controls whether channels are public or private.
241#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash)]
242#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
243pub enum ChannelVisibility {
244    /// Public channels are visible to anyone with the link. People join with the Guest role by default.
245    #[sea_orm(string_value = "public")]
246    Public,
247    /// Members channels are only visible to members of this channel or its parents.
248    #[sea_orm(string_value = "members")]
249    #[default]
250    Members,
251}
252
253impl From<proto::ChannelVisibility> for ChannelVisibility {
254    fn from(value: proto::ChannelVisibility) -> Self {
255        match value {
256            proto::ChannelVisibility::Public => ChannelVisibility::Public,
257            proto::ChannelVisibility::Members => ChannelVisibility::Members,
258        }
259    }
260}
261
262impl Into<proto::ChannelVisibility> for ChannelVisibility {
263    fn into(self) -> proto::ChannelVisibility {
264        match self {
265            ChannelVisibility::Public => proto::ChannelVisibility::Public,
266            ChannelVisibility::Members => proto::ChannelVisibility::Members,
267        }
268    }
269}
270
271impl Into<i32> for ChannelVisibility {
272    fn into(self) -> i32 {
273        let proto: proto::ChannelVisibility = self.into();
274        proto.into()
275    }
276}
277
278#[derive(Copy, Clone, Debug, Serialize, PartialEq)]
279pub enum PrincipalId {
280    UserId(UserId),
281    DevServerId(DevServerId),
282}
283
284/// Indicate whether a [Buffer] has permissions to edit.
285#[derive(PartialEq, Clone, Copy, Debug)]
286pub enum Capability {
287    /// The buffer is a mutable replica.
288    ReadWrite,
289    /// The buffer is a read-only replica.
290    ReadOnly,
291}