Skip to content

Commit eb41a06

Browse files
committed
editoast: remove application roles
They will be added back with another implementation when we'll have an admin panel where admins will be able to configure them. Signed-off-by: Leo Valais <[email protected]>
1 parent 25b6a3a commit eb41a06

File tree

12 files changed

+61
-478
lines changed

12 files changed

+61
-478
lines changed

editoast/editoast_authz/src/authorizer.rs

+15-67
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
use itertools::Itertools as _;
2-
use std::{collections::HashSet, future::Future, sync::Arc};
1+
use std::{collections::HashSet, future::Future};
32

43
use tracing::debug;
54
use tracing::Level;
65

7-
use crate::roles::{BuiltinRoleSet, RoleConfig, RoleIdentifier};
6+
use crate::roles::BuiltinRoleSet;
87

98
pub type UserIdentity = String;
109
pub type UserName = String;
@@ -19,7 +18,6 @@ pub struct UserInfo {
1918
pub struct Authorizer<S: StorageDriver> {
2019
user: UserInfo,
2120
user_id: i64,
22-
pub roles_config: Arc<RoleConfig<S::BuiltinRole>>,
2321
user_roles: HashSet<S::BuiltinRole>,
2422
#[allow(unused)] // will be used soon
2523
storage: S,
@@ -45,58 +43,43 @@ pub trait StorageDriver: Clone {
4543
fn fetch_subject_roles(
4644
&self,
4745
subject_id: i64,
48-
roles_config: &RoleConfig<Self::BuiltinRole>,
4946
) -> impl Future<Output = Result<HashSet<Self::BuiltinRole>, Self::Error>> + Send;
5047

5148
fn ensure_subject_roles(
5249
&self,
5350
subject_id: i64,
54-
roles_config: &RoleConfig<Self::BuiltinRole>,
5551
roles: HashSet<Self::BuiltinRole>,
5652
) -> impl Future<Output = Result<(), Self::Error>> + Send;
5753

5854
fn remove_subject_roles(
5955
&self,
6056
subject_id: i64,
61-
roles_config: &RoleConfig<Self::BuiltinRole>,
6257
roles: HashSet<Self::BuiltinRole>,
6358
) -> impl Future<Output = Result<HashSet<Self::BuiltinRole>, Self::Error>> + Send;
6459
}
6560

6661
impl<S: StorageDriver> Authorizer<S> {
67-
#[tracing::instrument(skip_all, fields(%user, roles_config = %roles_config.as_ref()), err)]
68-
pub async fn try_initialize(
69-
user: UserInfo,
70-
roles_config: Arc<RoleConfig<S::BuiltinRole>>,
71-
storage_driver: S,
72-
) -> Result<Self, S::Error> {
62+
#[tracing::instrument(skip_all, fields(%user), err)]
63+
pub async fn try_initialize(user: UserInfo, storage_driver: S) -> Result<Self, S::Error> {
7364
let user_id = storage_driver.ensure_user(&user).await?;
7465
debug!(%user, %user_id, "user authenticated");
75-
let user_roles = storage_driver
76-
.fetch_subject_roles(user_id, roles_config.as_ref())
77-
.await?;
66+
let user_roles = storage_driver.fetch_subject_roles(user_id).await?;
7867
Ok(Self {
7968
user,
8069
user_id,
81-
roles_config,
8270
user_roles,
8371
storage: storage_driver,
8472
})
8573
}
8674

87-
pub fn new_superuser(roles_config: Arc<RoleConfig<S::BuiltinRole>>, storage_driver: S) -> Self {
88-
debug_assert!(
89-
roles_config.is_superuser(),
90-
"Authorizer::new_superuser requires a superuser role config"
91-
);
75+
pub fn new_superuser(storage_driver: S) -> Self {
9276
Self {
9377
user: UserInfo {
9478
identity: "superuser".to_string(),
9579
name: "Super User".to_string(),
9680
},
9781
user_id: -1,
98-
roles_config,
99-
user_roles: Default::default(),
82+
user_roles: HashSet::from([S::BuiltinRole::superuser()]),
10083
storage: storage_driver,
10184
}
10285
}
@@ -106,7 +89,7 @@ impl<S: StorageDriver> Authorizer<S> {
10689
}
10790

10891
pub fn is_superuser(&self) -> bool {
109-
self.roles_config.is_superuser() || self.user_roles.contains(&S::BuiltinRole::superuser())
92+
self.user_roles.contains(&S::BuiltinRole::superuser())
11093
}
11194

11295
/// Returns whether a user with some id exists
@@ -132,65 +115,37 @@ impl<S: StorageDriver> Authorizer<S> {
132115
Ok(required_roles.is_subset(&self.user_roles))
133116
}
134117

135-
#[tracing::instrument(skip_all, fields(user_id, auth_user = %self.user, user_roles = ?self.user_roles), ret(level = Level::DEBUG), err)]
136-
pub async fn infer_application_roles(
137-
&self,
138-
user_id: i64,
139-
) -> Result<Vec<RoleIdentifier>, S::Error> {
140-
if self.is_superuser() {
141-
return Ok(self.roles_config.application_roles().cloned().collect_vec());
142-
}
143-
144-
let resolved_roles = &self.roles_config.resolved_roles;
145-
let user_roles = self
146-
.storage
147-
.fetch_subject_roles(user_id, &self.roles_config)
148-
.await?;
149-
150-
let app_roles = resolved_roles
151-
.iter()
152-
.filter(|(_, builtins)| user_roles.is_superset(builtins))
153-
.map(|(app_role, _)| app_role)
154-
.cloned()
155-
.collect_vec();
156-
157-
Ok(app_roles)
158-
}
159-
160118
#[tracing::instrument(skip_all, fields(user_id, auth_user = %self.user, user_roles = ?self.user_roles), ret(level = Level::DEBUG), err)]
161119
pub async fn user_builtin_roles(
162120
&self,
163121
user_id: i64,
164122
) -> Result<HashSet<S::BuiltinRole>, S::Error> {
165-
let user_roles = self
166-
.storage
167-
.fetch_subject_roles(user_id, &self.roles_config)
168-
.await?;
123+
let user_roles = self.storage.fetch_subject_roles(user_id).await?;
169124
Ok(user_roles.clone())
170125
}
171126

172-
#[tracing::instrument(skip_all, fields(user_id, auth_user = %self.user, ?roles, role_config = ?self.roles_config), ret(level = Level::DEBUG), err)]
127+
#[tracing::instrument(skip_all, fields(user_id, auth_user = %self.user, ?roles), ret(level = Level::DEBUG), err)]
173128
pub async fn grant_roles(
174129
&mut self,
175130
user_id: i64,
176131
roles: HashSet<S::BuiltinRole>,
177132
) -> Result<(), S::Error> {
178133
self.storage
179-
.ensure_subject_roles(user_id, &self.roles_config, roles.clone())
134+
.ensure_subject_roles(user_id, roles.clone())
180135
.await?;
181136
self.user_roles.extend(roles);
182137
Ok(())
183138
}
184139

185-
#[tracing::instrument(skip_all, fields(user_id, auth_user = %self.user, ?roles, role_config = ?self.roles_config), ret(level = Level::DEBUG), err)]
140+
#[tracing::instrument(skip_all, fields(user_id, auth_user = %self.user, ?roles), ret(level = Level::DEBUG), err)]
186141
pub async fn strip_roles(
187142
&mut self,
188143
user_id: i64,
189144
roles: HashSet<S::BuiltinRole>,
190145
) -> Result<(), S::Error> {
191146
let removed_roles = self
192147
.storage
193-
.remove_subject_roles(user_id, &self.roles_config, roles.clone())
148+
.remove_subject_roles(user_id, roles.clone())
194149
.await?;
195150
tracing::debug!(?removed_roles, "removed roles");
196151
self.user_roles.retain(|r| !roles.contains(r));
@@ -203,7 +158,6 @@ impl<S: StorageDriver> std::fmt::Debug for Authorizer<S> {
203158
f.debug_struct("Authorizer")
204159
.field("user", &self.user)
205160
.field("user_id", &self.user_id)
206-
.field("roles_config", &self.roles_config)
207161
.field("user_roles", &self.user_roles)
208162
.finish()
209163
}
@@ -234,9 +188,8 @@ mod tests {
234188

235189
#[tokio::test]
236190
async fn superuser() {
237-
let config = RoleConfig::new_superuser();
238191
let storage = MockStorageDriver::default();
239-
let authorizer = Authorizer::new_superuser(config.into(), storage);
192+
let authorizer = Authorizer::new_superuser(storage);
240193
assert!(authorizer.is_superuser());
241194
// Check that the superuser has any role even if not explicitely granted
242195
assert_eq!(
@@ -249,7 +202,6 @@ mod tests {
249202

250203
#[tokio::test]
251204
async fn check_roles() {
252-
let config = default_test_config();
253205
let storage = MockStorageDriver::default();
254206

255207
// insert some mocked roles
@@ -270,7 +222,6 @@ mod tests {
270222
identity: "toto".to_owned(),
271223
name: "Sir Toto, the One and Only".to_owned(),
272224
},
273-
config.into(),
274225
storage,
275226
)
276227
.await
@@ -306,7 +257,7 @@ mod tests {
306257
.unwrap());
307258

308259
assert!(!authorizer
309-
.check_roles(HashSet::from([TestBuiltinRole::DocEdit,]))
260+
.check_roles(HashSet::from([TestBuiltinRole::DocEdit]))
310261
.await
311262
.unwrap());
312263
assert!(!authorizer
@@ -334,7 +285,6 @@ mod tests {
334285
async fn fetch_subject_roles(
335286
&self,
336287
subject_id: i64,
337-
_roles_config: &RoleConfig<Self::BuiltinRole>,
338288
) -> Result<HashSet<Self::BuiltinRole>, Self::Error> {
339289
let user_roles = self.user_roles.lock().unwrap();
340290
let roles = user_roles.get(&subject_id).cloned().expect("no user");
@@ -344,7 +294,6 @@ mod tests {
344294
async fn ensure_subject_roles(
345295
&self,
346296
subject_id: i64,
347-
_roles_config: &RoleConfig<Self::BuiltinRole>,
348297
roles: HashSet<Self::BuiltinRole>,
349298
) -> Result<(), Self::Error> {
350299
let mut user_roles = self.user_roles.lock().unwrap();
@@ -355,7 +304,6 @@ mod tests {
355304
async fn remove_subject_roles(
356305
&self,
357306
subject_id: i64,
358-
_roles_config: &RoleConfig<Self::BuiltinRole>,
359307
roles: HashSet<Self::BuiltinRole>,
360308
) -> Result<HashSet<Self::BuiltinRole>, Self::Error> {
361309
let mut user_roles = self.user_roles.lock().unwrap();

editoast/editoast_authz/src/lib.rs

+2-19
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub use builtin_role::BuiltinRole;
88
pub mod fixtures {
99
use strum::{AsRefStr, EnumString};
1010

11-
use crate::roles::{self, RoleConfig};
11+
use crate::roles::BuiltinRoleSet;
1212

1313
#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRefStr, EnumString)]
1414
#[strum(serialize_all = "snake_case")]
@@ -20,26 +20,9 @@ pub mod fixtures {
2020
UserBan,
2121
}
2222

23-
impl roles::BuiltinRoleSet for TestBuiltinRole {
23+
impl BuiltinRoleSet for TestBuiltinRole {
2424
fn superuser() -> Self {
2525
Self::UserBan
2626
}
2727
}
28-
29-
pub fn default_test_config() -> roles::RoleConfig<TestBuiltinRole> {
30-
const SOURCE: &str = r#"
31-
[roles.doc_reader]
32-
implies = ["doc_read"]
33-
34-
[roles.doc_provider]
35-
implies = ["doc_delete", "doc_edit", "doc_read"]
36-
37-
[roles.admin]
38-
implies = ["user_add", "user_ban"]
39-
40-
[roles.dev]
41-
implies = ["admin", "doc_provider"]
42-
"#;
43-
RoleConfig::load(SOURCE).expect("should parse successfully")
44-
}
4528
}

0 commit comments

Comments
 (0)