Skip to content

Commit 3e24e08

Browse files
committed
feat: Introduce resources
- Introduce resource types (stream, llm, all) for privileges
1 parent b5d1fac commit 3e24e08

File tree

6 files changed

+115
-135
lines changed

6 files changed

+115
-135
lines changed

src/handlers/http/modal/query/querier_rbac.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::{
3131
rbac::RBACError,
3232
},
3333
rbac::{
34-
map::{mut_users, roles, write_user_groups},
34+
map::{roles, write_user_groups},
3535
user, Users,
3636
},
3737
validator,
@@ -127,22 +127,6 @@ pub async fn delete_user(username: web::Path<String>) -> Result<impl Responder,
127127
};
128128
}
129129

130-
// ensure that the users remove the user group from their map
131-
[&username]
132-
.iter()
133-
.map(|user| {
134-
if let Some(user) = mut_users().get_mut(*user) {
135-
for group in groups_to_update.iter() {
136-
user.user_groups.remove(&group.name);
137-
}
138-
139-
metadata.users.retain(|u| u.username() != user.username());
140-
metadata.users.push(user.clone());
141-
}
142-
})
143-
.for_each(drop);
144-
put_metadata(&metadata).await?;
145-
146130
// update in metadata user group
147131
metadata
148132
.user_groups

src/handlers/http/rbac.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::collections::{HashMap, HashSet};
2121
use crate::{
2222
rbac::{
2323
self,
24-
map::{mut_users, read_user_groups, roles, write_user_groups},
24+
map::{read_user_groups, roles, write_user_groups},
2525
role::model::DefaultPrivilege,
2626
user,
2727
utils::to_prism_user,
@@ -250,22 +250,6 @@ pub async fn delete_user(username: web::Path<String>) -> Result<impl Responder,
250250
};
251251
}
252252

253-
// ensure that the users remove the user group from their map
254-
[&username]
255-
.iter()
256-
.map(|user| {
257-
if let Some(user) = mut_users().get_mut(*user) {
258-
for group in groups_to_update.iter() {
259-
user.user_groups.remove(&group.name);
260-
}
261-
262-
metadata.users.retain(|u| u.username() != user.username());
263-
metadata.users.push(user.clone());
264-
}
265-
})
266-
.for_each(drop);
267-
put_metadata(&metadata).await?;
268-
269253
// update in metadata user groups
270254
metadata
271255
.user_groups

src/migration/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ pub async fn run_metadata_migration(
6262
.and_then(|version| version.as_str())
6363
}
6464

65-
warn!(verion=?get_version(storage_metadata.as_ref().unwrap()));
6665
// if storage metadata is none do nothing
6766
if let Some(storage_metadata) = storage_metadata {
6867
match get_version(&storage_metadata) {

src/rbac/map.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*
1717
*/
1818

19+
use crate::rbac::role::ParseableResourceType;
1920
use crate::rbac::user::{User, UserGroup};
2021
use crate::{parseable::PARSEABLE, storage::StorageMetadata};
2122
use std::collections::HashSet;
@@ -221,7 +222,7 @@ impl Sessions {
221222
&self,
222223
key: &SessionKey,
223224
required_action: Action,
224-
context_stream: Option<&str>,
225+
context_resource: Option<&str>,
225226
context_user: Option<&str>,
226227
) -> Option<Response> {
227228
self.active_sessions.get(key).map(|(username, perms)| {
@@ -256,15 +257,23 @@ impl Sessions {
256257
match *user_perm {
257258
// if any action is ALL then we we authorize
258259
Permission::Unit(action) => action == required_action || action == Action::All,
259-
Permission::Stream(action, ref stream)
260-
| Permission::StreamWithTag(action, ref stream, _) => {
261-
let ok_stream = if let Some(context_stream) = context_stream {
262-
stream == context_stream || stream == "*"
263-
} else {
264-
// if no stream to match then stream check is not needed
265-
true
266-
};
267-
(action == required_action || action == Action::All) && ok_stream
260+
Permission::Resource(action, ref resource_type) => {
261+
match resource_type {
262+
ParseableResourceType::Stream(resource_id)
263+
| ParseableResourceType::Llm(resource_id) => {
264+
let ok_resource = if let Some(context_resource_id) = context_resource {
265+
resource_id == context_resource_id || resource_id == "*"
266+
} else {
267+
// if no resource to match then resource check is not needed
268+
// WHEN IS THIS VALID??
269+
true
270+
};
271+
(action == required_action || action == Action::All) && ok_resource
272+
}
273+
ParseableResourceType::All => {
274+
action == required_action || action == Action::All
275+
},
276+
}
268277
}
269278
Permission::SelfUser if required_action == Action::GetUserRoles => {
270279
context_user.map(|x| x == username).unwrap_or_default()

src/rbac/role.rs

Lines changed: 84 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -77,52 +77,67 @@ pub enum Action {
7777
PutCorrelation,
7878
}
7979

80+
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
81+
pub enum ParseableResourceType {
82+
#[serde(rename="stream")]
83+
Stream(String),
84+
#[serde(rename="llm")]
85+
Llm(String),
86+
#[serde(rename="all")]
87+
All
88+
}
89+
8090
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8191
pub enum Permission {
8292
Unit(Action),
83-
Stream(Action, String),
84-
StreamWithTag(Action, String, Option<String>),
85-
Resource(Action, Option<String>, Option<String>),
93+
// Stream(Action, String),
94+
// StreamWithTag(Action, String, Option<String>),
95+
Resource(Action, ParseableResourceType),
8696
SelfUser,
8797
}
8898

8999
// Currently Roles are tied to one stream
90100
#[derive(Debug, Default)]
91101
pub struct RoleBuilder {
92102
actions: Vec<Action>,
93-
stream: Option<String>,
94-
tag: Option<String>,
95-
resource_id: Option<String>,
96-
resource_type: Option<String>,
103+
// stream: Option<String>,
104+
// tag: Option<String>,
105+
// resource_id: Option<String>,
106+
resource_type: Option<ParseableResourceType>,
97107
}
98108

99109
// R x P
100110
impl RoleBuilder {
101-
pub fn with_stream(mut self, stream: String) -> Self {
102-
self.stream = Some(stream);
111+
pub fn with_resource(
112+
mut self,
113+
resource_type: ParseableResourceType,
114+
// resource_id: String,
115+
) -> Self {
116+
self.resource_type = Some(resource_type);
117+
// self.resource_id = Some(resource_id);
103118
self
104119
}
105120

106-
pub fn with_tag(mut self, tag: String) -> Self {
107-
self.tag = Some(tag);
108-
self
109-
}
121+
// pub fn with_stream(mut self, stream: String) -> Self {
122+
// self.stream = Some(stream);
123+
// self
124+
// }
110125

111-
pub fn with_resource(mut self, resource_id: String, resource_type: String) -> Self {
112-
self.resource_id = Some(resource_id);
113-
self.resource_type = Some(resource_type);
114-
self
115-
}
126+
// pub fn with_tag(mut self, tag: String) -> Self {
127+
// self.tag = Some(tag);
128+
// self
129+
// }
130+
131+
// pub fn with_resource(mut self, resource_id: String, resource_type: ParseableResourceType) -> Self {
132+
// self.resource_id = Some(resource_id);
133+
// self.resource_type = Some(resource_type);
134+
// self
135+
// }
116136

117137
pub fn build(self) -> Vec<Permission> {
118138
let mut perms = Vec::new();
119139
for action in self.actions {
120140
let perm = match action {
121-
Action::Query => Permission::StreamWithTag(
122-
action,
123-
self.stream.clone().unwrap(),
124-
self.tag.clone(),
125-
),
126141
Action::Login
127142
| Action::Metrics
128143
| Action::PutUser
@@ -164,23 +179,24 @@ impl RoleBuilder {
164179
| Action::DeleteUserGroup
165180
| Action::ModifyUserGroup
166181
| Action::GetAnalytics => Permission::Unit(action),
167-
Action::QueryLLM
182+
Action::Query
183+
| Action::QueryLLM
168184
| Action::AddLLM
169185
| Action::DeleteLLM
170186
| Action::GetLLM
171-
| Action::ListLLM => Permission::Resource(
172-
action,
173-
self.resource_type.clone(),
174-
self.resource_id.clone(),
175-
),
176-
Action::Ingest
187+
| Action::ListLLM
188+
| Action::Ingest
177189
| Action::ListStream
178190
| Action::GetSchema
179191
| Action::DetectSchema
180192
| Action::GetStats
181193
| Action::GetRetention
182194
| Action::PutRetention
183-
| Action::All => Permission::Stream(action, self.stream.clone().unwrap()),
195+
| Action::All => Permission::Resource(
196+
action,
197+
self.resource_type.clone().unwrap(),
198+
// self.resource_id.clone().unwrap(),
199+
),
184200
};
185201
perms.push(perm);
186202
}
@@ -193,26 +209,25 @@ impl RoleBuilder {
193209
// we can put same model in the backend
194210
// user -> Vec<DefaultRoles>
195211
pub mod model {
212+
use crate::rbac::role::ParseableResourceType;
213+
196214
use super::{Action, RoleBuilder};
197215

198216
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)]
199-
#[serde(tag = "privilege", content = "resource", rename_all = "lowercase")]
217+
#[serde(tag = "privilege", rename_all = "lowercase")]
200218
pub enum DefaultPrivilege {
201219
Admin,
202220
Editor,
203221
Writer {
204-
stream: String,
222+
resource: ParseableResourceType,
223+
// resource_id: String,
205224
},
206225
Ingestor {
207-
stream: String,
226+
resource: ParseableResourceType,
208227
},
209228
Reader {
210-
stream: String,
211-
tag: Option<String>,
212-
},
213-
Resource {
214-
resource_id: String,
215-
resource_type: String,
229+
resource: ParseableResourceType,
230+
// resource_id: String,
216231
},
217232
}
218233

@@ -221,35 +236,29 @@ pub mod model {
221236
match value {
222237
DefaultPrivilege::Admin => admin_perm_builder(),
223238
DefaultPrivilege::Editor => editor_perm_builder(),
224-
DefaultPrivilege::Writer { stream } => {
225-
writer_perm_builder().with_stream(stream.to_owned())
226-
}
227-
DefaultPrivilege::Reader { stream, tag } => {
228-
let mut reader = reader_perm_builder().with_stream(stream.to_owned());
229-
if let Some(tag) = tag {
230-
reader = reader.with_tag(tag.to_owned())
231-
}
232-
reader
233-
}
234-
DefaultPrivilege::Ingestor { stream } => {
235-
ingest_perm_builder().with_stream(stream.to_owned())
236-
}
237-
DefaultPrivilege::Resource {
238-
resource_id,
239-
resource_type,
240-
} => resource_perm_builder()
241-
.with_resource(resource_id.clone(), resource_type.clone()),
239+
DefaultPrivilege::Writer {
240+
resource,
241+
// resource_id,
242+
} => writer_perm_builder()
243+
.with_resource(resource.to_owned()),
244+
DefaultPrivilege::Reader {
245+
resource,
246+
// resource_id,
247+
} => reader_perm_builder()
248+
.with_resource(resource.to_owned()),
249+
DefaultPrivilege::Ingestor { resource } => ingest_perm_builder()
250+
.with_resource(resource.to_owned()),
242251
}
243252
}
244253
}
245254

246255
fn admin_perm_builder() -> RoleBuilder {
247256
RoleBuilder {
248257
actions: vec![Action::All],
249-
stream: Some("*".to_string()),
250-
tag: None,
251-
resource_type: Some("*".to_string()),
252-
resource_id: Some("*".to_string()),
258+
// stream: Some("*".to_string()),
259+
// tag: None,
260+
resource_type: Some(ParseableResourceType::All),
261+
// resource_id: Some("*".to_string()),
253262
}
254263
}
255264

@@ -295,10 +304,10 @@ pub mod model {
295304
Action::DeleteDashboard,
296305
Action::GetUserRoles,
297306
],
298-
stream: Some("*".to_string()),
299-
tag: None,
300-
resource_id: None,
301-
resource_type: None,
307+
// stream: Some("*".to_string()),
308+
// tag: None,
309+
// resource_id: Some("*".to_string()),
310+
resource_type: Some(ParseableResourceType::All),
302311
}
303312
}
304313

@@ -338,9 +347,9 @@ pub mod model {
338347
Action::DeleteFilter,
339348
Action::GetUserRoles,
340349
],
341-
stream: None,
342-
tag: None,
343-
resource_id: None,
350+
// stream: None,
351+
// tag: None,
352+
// resource_id: None,
344353
resource_type: None,
345354
}
346355
}
@@ -374,29 +383,19 @@ pub mod model {
374383
Action::GetUserRoles,
375384
Action::GetAlert,
376385
],
377-
stream: None,
378-
tag: None,
379-
resource_id: None,
380-
resource_type: None,
381-
}
382-
}
383-
384-
fn resource_perm_builder() -> RoleBuilder {
385-
RoleBuilder {
386-
actions: vec![Action::GetLLM, Action::ListLLM, Action::QueryLLM],
387-
stream: None,
388-
tag: None,
389-
resource_id: None,
386+
// stream: None,
387+
// tag: None,
388+
// resource_id: None,
390389
resource_type: None,
391390
}
392391
}
393392

394393
fn ingest_perm_builder() -> RoleBuilder {
395394
RoleBuilder {
396395
actions: vec![Action::Ingest],
397-
stream: None,
398-
tag: None,
399-
resource_id: None,
396+
// stream: None,
397+
// tag: None,
398+
// resource_id: None,
400399
resource_type: None,
401400
}
402401
}

0 commit comments

Comments
 (0)