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}