create_rust_app/auth/permissions/
mod.rs1mod role_permission;
2mod user_permission;
3mod user_role;
4
5pub use role_permission::{RolePermission, RolePermissionChangeset};
6use std::hash::{Hash, Hasher};
7pub use user_permission::{UserPermission, UserPermissionChangeset};
8pub use user_role::{UserRole, UserRoleChangeset};
9
10use crate::database::Connection;
11use anyhow::Result;
12use diesel::{
13 sql_query,
14 sql_types::{Integer, Text},
15 RunQueryDsl,
16};
17use serde::{Deserialize, Serialize};
18
19use crate::auth::ID;
20
21pub struct Role;
22
23#[derive(Debug, Serialize, Deserialize, QueryableByName, Clone)]
24struct RoleQueryRow {
25 #[diesel(sql_type=Text)]
26 role: String,
27}
28
29impl Role {
30 pub fn assign(db: &mut Connection, user_id: ID, role: &str) -> Result<bool> {
39 let assigned = UserRole::create(
40 db,
41 &UserRoleChangeset {
42 user_id,
43 role: role.to_string(),
44 },
45 );
46
47 Ok(assigned.is_ok())
48 }
49
50 pub fn assign_many(db: &mut Connection, user_id: ID, roles: Vec<String>) -> Result<bool> {
59 let assigned = UserRole::create_many(
60 db,
61 roles
62 .into_iter()
63 .map(|r| UserRoleChangeset { user_id, role: r })
64 .collect::<Vec<_>>(),
65 );
66
67 Ok(assigned.is_ok())
68 }
69
70 pub fn unassign(db: &mut Connection, user_id: ID, role: &str) -> Result<bool> {
79 let unassigned = UserRole::delete(db, user_id, role.to_string());
80
81 Ok(unassigned.is_ok())
82 }
83
84 pub fn unassign_many(db: &mut Connection, user_id: ID, roles: Vec<String>) -> Result<bool> {
93 let unassigned = UserRole::delete_many(db, user_id, roles);
94
95 Ok(unassigned.is_ok())
96 }
97
98 pub fn fetch_all(db: &mut Connection, user_id: ID) -> Result<Vec<String>> {
103 let roles = sql_query("SELECT role FROM user_roles WHERE user_id = $1");
104
105 let roles = roles
106 .bind::<Integer, _>(user_id)
107 .get_results::<RoleQueryRow>(db)?;
108
109 let roles = roles.into_iter().map(|r| r.role).collect();
110
111 Ok(roles)
112 }
113}
114
115#[tsync::tsync]
116#[derive(Debug, Serialize, Deserialize, QueryableByName, Clone)]
117pub struct Permission {
118 #[diesel(sql_type=Text)]
119 pub from_role: String,
121
122 #[diesel(sql_type=Text)]
123 pub permission: String,
125}
126
127impl Hash for Permission {
128 fn hash<H: Hasher>(&self, state: &mut H) {
129 self.permission.as_str().hash(state);
130 }
131}
132
133impl PartialEq for Permission {
134 fn eq(&self, other: &Self) -> bool {
135 self.permission.eq(&other.permission)
136 }
137}
138impl Eq for Permission {}
139
140impl Permission {
141 pub fn grant_to_user(db: &mut Connection, user_id: ID, permission: &str) -> Result<()> {
155 let _granted = UserPermission::create(
156 db,
157 &UserPermissionChangeset {
158 permission: permission.to_string(),
159 user_id,
160 },
161 )?;
162
163 Ok(())
164 }
165
166 pub fn grant_to_role(db: &mut Connection, role: &str, permission: &str) -> Result<()> {
173 let _granted = RolePermission::create(
174 db,
175 &RolePermissionChangeset {
176 permission: permission.to_string(),
177 role: role.to_string(),
178 },
179 )?;
180
181 Ok(())
182 }
183
184 pub fn grant_many_to_role(
191 db: &mut Connection,
192 role: String,
193 permissions: Vec<String>,
194 ) -> Result<()> {
195 let _granted = RolePermission::create_many(
196 db,
197 permissions
198 .into_iter()
199 .map(|permission| RolePermissionChangeset {
200 permission,
201 role: role.clone(),
202 })
203 .collect::<Vec<_>>(),
204 )?;
205
206 Ok(())
207 }
208
209 pub fn grant_many_to_user(
216 db: &mut Connection,
217 user_id: i32,
218 permissions: Vec<String>,
219 ) -> Result<()> {
220 let _granted = UserPermission::create_many(
221 db,
222 permissions
223 .into_iter()
224 .map(|permission| UserPermissionChangeset {
225 user_id,
226 permission,
227 })
228 .collect::<Vec<_>>(),
229 )?;
230
231 Ok(())
232 }
233
234 pub fn revoke_from_user(db: &mut Connection, user_id: ID, permission: &str) -> Result<()> {
241 let _deleted = UserPermission::delete(db, user_id, permission.to_string())?;
242
243 Ok(())
244 }
245
246 pub fn revoke_from_role(db: &mut Connection, role: String, permission: String) -> Result<()> {
255 let _deleted = RolePermission::delete(db, role, permission)?;
256
257 Ok(())
258 }
259
260 pub fn revoke_many_from_user(
267 db: &mut Connection,
268 user_id: ID,
269 permissions: Vec<String>,
270 ) -> Result<()> {
271 let _deleted = UserPermission::delete_many(db, user_id, permissions)?;
272
273 Ok(())
274 }
275
276 pub fn revoke_many_from_role(
283 db: &mut Connection,
284 role: String,
285 permissions: Vec<String>,
286 ) -> Result<()> {
287 let _deleted = RolePermission::delete_many(db, role, permissions)?;
288
289 Ok(())
290 }
291
292 pub fn revoke_all_from_role(db: &mut Connection, role: &str) -> Result<()> {
299 let _deleted = RolePermission::delete_all(db, role)?;
300
301 Ok(())
302 }
303
304 pub fn revoke_all_from_user(db: &mut Connection, user_id: i32) -> Result<()> {
311 let _deleted = UserPermission::delete_all(db, user_id)?;
312
313 Ok(())
314 }
315
316 pub fn fetch_all(db: &mut Connection, user_id: ID) -> Result<Vec<Self>> {
321 let permissions = sql_query(
322 r"
323 SELECT
324 permission AS permission,
325 NULL AS from_role
326 FROM user_permissions
327 WHERE user_permissions.user_id = $1
328
329 UNION
330
331 SELECT
332 permission AS permission,
333 user_roles.role AS form_role
334 FROM user_roles
335 INNER JOIN role_permissions ON user_roles.role = role_permissions.role
336 WHERE user_roles.user_id = $1
337 ",
338 );
339
340 let permissions = permissions
341 .bind::<Integer, _>(user_id)
342 .get_results::<Self>(db)?;
343
344 Ok(permissions)
345 }
346}