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