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!(BufferId);
 71id_type!(AccessTokenId);
 72id_type!(ChannelChatParticipantId);
 73id_type!(ChannelId);
 74id_type!(ChannelMemberId);
 75id_type!(MessageId);
 76id_type!(ContactId);
 77id_type!(FollowerId);
 78id_type!(RoomId);
 79id_type!(RoomParticipantId);
 80id_type!(ProjectId);
 81id_type!(ProjectCollaboratorId);
 82id_type!(ReplicaId);
 83id_type!(ServerId);
 84id_type!(SignupId);
 85id_type!(UserId);
 86id_type!(ChannelBufferCollaboratorId);
 87id_type!(FlagId);
 88id_type!(ExtensionId);
 89id_type!(NotificationId);
 90id_type!(NotificationKindId);
 91id_type!(HostedProjectId);
 92
 93/// ChannelRole gives you permissions for both channels and calls.
 94#[derive(
 95    Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash, Serialize,
 96)]
 97#[sea_orm(rs_type = "String", db_type = "String(None)")]
 98pub enum ChannelRole {
 99    /// Admin can read/write and change permissions.
100    #[sea_orm(string_value = "admin")]
101    Admin,
102    /// Member can read/write, but not change pemissions.
103    #[sea_orm(string_value = "member")]
104    #[default]
105    Member,
106    /// Talker can read, but not write.
107    /// They can use microphones and the channel chat
108    #[sea_orm(string_value = "talker")]
109    Talker,
110    /// Guest can read, but not write.
111    /// They can not use microphones but can use the chat.
112    #[sea_orm(string_value = "guest")]
113    Guest,
114    /// Banned may not read.
115    #[sea_orm(string_value = "banned")]
116    Banned,
117}
118
119impl ChannelRole {
120    /// Returns true if this role is more powerful than the other role.
121    pub fn should_override(&self, other: Self) -> bool {
122        use ChannelRole::*;
123        match self {
124            Admin => matches!(other, Member | Banned | Talker | Guest),
125            Member => matches!(other, Banned | Talker | Guest),
126            Talker => matches!(other, Guest),
127            Banned => matches!(other, Guest),
128            Guest => false,
129        }
130    }
131
132    /// Returns the maximal role between the two
133    pub fn max(&self, other: Self) -> Self {
134        if self.should_override(other) {
135            *self
136        } else {
137            other
138        }
139    }
140
141    pub fn can_see_channel(&self, visibility: ChannelVisibility) -> bool {
142        use ChannelRole::*;
143        match self {
144            Admin | Member => true,
145            Guest | Talker => visibility == ChannelVisibility::Public,
146            Banned => false,
147        }
148    }
149
150    /// True if the role allows access to all descendant channels
151    pub fn can_see_all_descendants(&self) -> bool {
152        use ChannelRole::*;
153        match self {
154            Admin | Member => true,
155            Guest | Talker | Banned => false,
156        }
157    }
158
159    /// True if the role only allows access to public descendant channels
160    pub fn can_only_see_public_descendants(&self) -> bool {
161        use ChannelRole::*;
162        match self {
163            Guest | Talker => true,
164            Admin | Member | Banned => false,
165        }
166    }
167
168    /// True if the role can share screen/microphone/projects into rooms.
169    pub fn can_use_microphone(&self) -> bool {
170        use ChannelRole::*;
171        match self {
172            Admin | Member | Talker => true,
173            Guest | Banned => false,
174        }
175    }
176
177    /// True if the role can edit shared projects.
178    pub fn can_edit_projects(&self) -> bool {
179        use ChannelRole::*;
180        match self {
181            Admin | Member => true,
182            Talker | Guest | Banned => false,
183        }
184    }
185
186    /// True if the role can read shared projects.
187    pub fn can_read_projects(&self) -> bool {
188        use ChannelRole::*;
189        match self {
190            Admin | Member | Guest | Talker => true,
191            Banned => false,
192        }
193    }
194
195    pub fn requires_cla(&self) -> bool {
196        use ChannelRole::*;
197        match self {
198            Admin | Member => true,
199            Banned | Guest | Talker => false,
200        }
201    }
202}
203
204impl From<proto::ChannelRole> for ChannelRole {
205    fn from(value: proto::ChannelRole) -> Self {
206        match value {
207            proto::ChannelRole::Admin => ChannelRole::Admin,
208            proto::ChannelRole::Member => ChannelRole::Member,
209            proto::ChannelRole::Talker => ChannelRole::Talker,
210            proto::ChannelRole::Guest => ChannelRole::Guest,
211            proto::ChannelRole::Banned => ChannelRole::Banned,
212        }
213    }
214}
215
216impl Into<proto::ChannelRole> for ChannelRole {
217    fn into(self) -> proto::ChannelRole {
218        match self {
219            ChannelRole::Admin => proto::ChannelRole::Admin,
220            ChannelRole::Member => proto::ChannelRole::Member,
221            ChannelRole::Talker => proto::ChannelRole::Talker,
222            ChannelRole::Guest => proto::ChannelRole::Guest,
223            ChannelRole::Banned => proto::ChannelRole::Banned,
224        }
225    }
226}
227
228impl Into<i32> for ChannelRole {
229    fn into(self) -> i32 {
230        let proto: proto::ChannelRole = self.into();
231        proto.into()
232    }
233}
234
235/// ChannelVisibility controls whether channels are public or private.
236#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash)]
237#[sea_orm(rs_type = "String", db_type = "String(None)")]
238pub enum ChannelVisibility {
239    /// Public channels are visible to anyone with the link. People join with the Guest role by default.
240    #[sea_orm(string_value = "public")]
241    Public,
242    /// Members channels are only visible to members of this channel or its parents.
243    #[sea_orm(string_value = "members")]
244    #[default]
245    Members,
246}
247
248impl From<proto::ChannelVisibility> for ChannelVisibility {
249    fn from(value: proto::ChannelVisibility) -> Self {
250        match value {
251            proto::ChannelVisibility::Public => ChannelVisibility::Public,
252            proto::ChannelVisibility::Members => ChannelVisibility::Members,
253        }
254    }
255}
256
257impl Into<proto::ChannelVisibility> for ChannelVisibility {
258    fn into(self) -> proto::ChannelVisibility {
259        match self {
260            ChannelVisibility::Public => proto::ChannelVisibility::Public,
261            ChannelVisibility::Members => proto::ChannelVisibility::Members,
262        }
263    }
264}
265
266impl Into<i32> for ChannelVisibility {
267    fn into(self) -> i32 {
268        let proto: proto::ChannelVisibility = self.into();
269        proto.into()
270    }
271}