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