ids.rs

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