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