headless_lms_server/domain/
authorization.rs1use crate::prelude::*;
4use actix_web::{HttpRequest, Responder};
5
6pub use headless_lms_authorization::error::{AuthorizationError, AuthorizationErrorType};
7pub use headless_lms_authorization::{
8 Action, ActionOnResource, AuthorizationToken, Resource, authorize, authorize_access_to_chatbot,
9 authorize_access_to_course_material, authorize_with_fetched_list_of_roles,
10 can_user_view_chapter, is_permitted, is_user_global_admin, skip_authorize,
11};
12
13#[derive(Copy, Clone)]
16pub struct AuthorizedResponse<T> {
17 pub data: T,
18}
19
20impl<T: Responder> Responder for AuthorizedResponse<T> {
21 type Body = T::Body;
22
23 fn respond_to(self, req: &HttpRequest) -> actix_web::HttpResponse<Self::Body> {
24 T::respond_to(self.data, req)
25 }
26}
27
28pub trait AuthorizedOk {
32 fn authorized_ok<T>(self, t: T) -> ControllerResult<T>;
33}
34
35impl AuthorizedOk for AuthorizationToken {
36 fn authorized_ok<T>(self, t: T) -> ControllerResult<T> {
37 Ok(AuthorizedResponse { data: t })
38 }
39}
40
41#[cfg(test)]
42mod test {
43 use super::*;
44 use crate::insert_data;
47 use crate::test_helper::*;
48 use headless_lms_models::*;
49 use models::roles::{RoleDomain, UserRole};
50
51 #[actix_web::test]
52 async fn test_authorization() {
53 let mut conn = Conn::init().await;
54 let mut tx = conn.begin().await;
55
56 let user = users::insert(
57 tx.as_mut(),
58 PKeyPolicy::Generate,
59 "auth@example.com",
60 None,
61 None,
62 )
63 .await
64 .unwrap();
65 let org = organizations::insert(
66 tx.as_mut(),
67 PKeyPolicy::Generate,
68 "auth",
69 "auth",
70 Some("auth"),
71 false,
72 )
73 .await
74 .unwrap();
75
76 authorize(
77 tx.as_mut(),
78 Action::Edit,
79 Some(user),
80 Resource::Organization(org),
81 )
82 .await
83 .unwrap_err();
84
85 roles::insert(
86 tx.as_mut(),
87 user,
88 UserRole::Teacher,
89 RoleDomain::Organization(org),
90 )
91 .await
92 .unwrap();
93
94 authorize(
95 tx.as_mut(),
96 Action::Edit,
97 Some(user),
98 Resource::Organization(org),
99 )
100 .await
101 .unwrap();
102 }
103
104 #[actix_web::test]
105 async fn course_role_chapter_resource() {
106 insert_data!(:tx, :user, :org, :course, instance: _instance, :course_module, :chapter);
107
108 authorize(
109 tx.as_mut(),
110 Action::Edit,
111 Some(user),
112 Resource::Chapter(chapter),
113 )
114 .await
115 .unwrap_err();
116
117 roles::insert(
118 tx.as_mut(),
119 user,
120 UserRole::Teacher,
121 RoleDomain::Course(course),
122 )
123 .await
124 .unwrap();
125
126 authorize(
127 tx.as_mut(),
128 Action::Edit,
129 Some(user),
130 Resource::Chapter(chapter),
131 )
132 .await
133 .unwrap();
134 }
135
136 #[actix_web::test]
137 async fn anonymous_user_can_view_open_course() {
138 insert_data!(:tx, :user, :org, :course);
139
140 authorize(tx.as_mut(), Action::View, None, Resource::Course(course))
141 .await
142 .unwrap();
143 }
144}