Skip to content

Commit 35674fc

Browse files
fix: remove user_id from API requests in Dashboards and Filters
Fetch session key from HttpRequest then fetch username from the session updated all APIs, removed user_id from API requests while saving the json, generate hash for user_id Dashboard API changes: GET /dashboards/{user_id} -> GET /dashboards this fetches all dashboards for user fetched from HttpRequest GET /dashboards/dashboard/{dashboard_id} -> GET /dashboards/{dashboard_id} DELETE /dashboards/dashboard/{dashboard_id} -> DELETE /dashboards/{dashboard_id} PUT /dashboards/dashboard/{dashboard_id} -> PUT /dashboards/{dashboard_id} Filter API changes: GET /filters/{user_id} -> GET /filters this fetches all filters for user fetched from HttpRequest GET /filters/filter/{filter_id} -> GET /filters/{filter_id} DELETE /filters/filter/{filter_id} -> DELETE /filters/{filter_id} PUT /filters/filter/{filter_id} -> PUT /filters/{filter_id}
1 parent 974929a commit 35674fc

File tree

8 files changed

+120
-111
lines changed

8 files changed

+120
-111
lines changed

server/src/handlers/http/modal/server.rs

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -197,72 +197,64 @@ impl Server {
197197
pub fn get_dashboards_webscope() -> Scope {
198198
web::scope("/dashboards")
199199
.service(
200-
web::resource("").route(
201-
web::post()
202-
.to(dashboards::post)
203-
.authorize(Action::CreateDashboard),
204-
),
205-
)
206-
.service(
207-
web::scope("/dashboard").service(
208-
web::resource("/{dashboard_id}")
209-
.route(
210-
web::get()
211-
.to(dashboards::get)
212-
.authorize(Action::GetDashboard),
213-
)
214-
.route(
215-
web::delete()
216-
.to(dashboards::delete)
217-
.authorize(Action::DeleteDashboard),
218-
)
219-
.route(
220-
web::put()
221-
.to(dashboards::update)
222-
.authorize(Action::CreateDashboard),
223-
),
224-
),
225-
)
226-
.service(
227-
web::scope("/{user_id}").service(
228-
web::resource("").route(
200+
web::resource("")
201+
.route(
202+
web::post()
203+
.to(dashboards::post)
204+
.authorize(Action::CreateDashboard),
205+
)
206+
.route(
229207
web::get()
230208
.to(dashboards::list)
231209
.authorize(Action::ListDashboard),
232210
),
233-
),
211+
)
212+
.service(
213+
web::resource("/{dashboard_id}")
214+
.route(
215+
web::get()
216+
.to(dashboards::get)
217+
.authorize(Action::GetDashboard),
218+
)
219+
.route(
220+
web::delete()
221+
.to(dashboards::delete)
222+
.authorize(Action::DeleteDashboard),
223+
)
224+
.route(
225+
web::put()
226+
.to(dashboards::update)
227+
.authorize(Action::CreateDashboard),
228+
),
234229
)
235230
}
236231

237232
// get the filters web scope
238233
pub fn get_filters_webscope() -> Scope {
239234
web::scope("/filters")
240235
.service(
241-
web::resource("").route(
242-
web::post()
243-
.to(filters::post)
244-
.authorize(Action::CreateFilter),
245-
),
236+
web::resource("")
237+
.route(
238+
web::post()
239+
.to(filters::post)
240+
.authorize(Action::CreateFilter),
241+
)
242+
.route(web::get().to(filters::list).authorize(Action::ListFilter)),
246243
)
247244
.service(
248-
web::scope("/filter").service(
249-
web::resource("/{filter_id}")
250-
.route(web::get().to(filters::get).authorize(Action::GetFilter))
251-
.route(
252-
web::delete()
253-
.to(filters::delete)
254-
.authorize(Action::DeleteFilter),
255-
)
256-
.route(
257-
web::put()
258-
.to(filters::update)
259-
.authorize(Action::CreateFilter),
260-
),
261-
),
245+
web::resource("/{filter_id}")
246+
.route(web::get().to(filters::get).authorize(Action::GetFilter))
247+
.route(
248+
web::delete()
249+
.to(filters::delete)
250+
.authorize(Action::DeleteFilter),
251+
)
252+
.route(
253+
web::put()
254+
.to(filters::update)
255+
.authorize(Action::CreateFilter),
256+
),
262257
)
263-
.service(web::scope("/{user_id}").service(
264-
web::resource("").route(web::get().to(filters::list).authorize(Action::ListFilter)),
265-
))
266258
}
267259

268260
// get the query factory

server/src/handlers/http/users/dashboards.rs

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@
1717
*/
1818

1919
use crate::{
20-
handlers::http::ingest::PostError,
20+
handlers::http::rbac::RBACError,
2121
option::CONFIG,
2222
storage::{object_storage::dashboard_path, ObjectStorageError},
2323
users::dashboards::{Dashboard, CURRENT_DASHBOARD_VERSION, DASHBOARDS},
24+
utils::{get_hash, get_user_from_request},
2425
};
2526
use actix_web::{http::header::ContentType, web, HttpRequest, HttpResponse, Responder};
2627
use bytes::Bytes;
@@ -30,11 +31,8 @@ use http::StatusCode;
3031
use serde_json::Error as SerdeError;
3132

3233
pub async fn list(req: HttpRequest) -> Result<impl Responder, DashboardError> {
33-
let user_id = req
34-
.match_info()
35-
.get("user_id")
36-
.ok_or(DashboardError::Metadata("No User Id Provided"))?;
37-
let dashboards = DASHBOARDS.list_dashboards_by_user(user_id);
34+
let user_id = get_user_from_request(&req)?;
35+
let dashboards = DASHBOARDS.list_dashboards_by_user(&get_hash(&user_id));
3836

3937
Ok((web::Json(dashboards), StatusCode::OK))
4038
}
@@ -52,21 +50,19 @@ pub async fn get(req: HttpRequest) -> Result<impl Responder, DashboardError> {
5250
Err(DashboardError::Metadata("Dashboard does not exist"))
5351
}
5452

55-
pub async fn post(body: Bytes) -> Result<impl Responder, PostError> {
53+
pub async fn post(req: HttpRequest, body: Bytes) -> Result<impl Responder, DashboardError> {
54+
let user_id = get_user_from_request(&req)?;
5655
let mut dashboard: Dashboard = serde_json::from_slice(&body)?;
57-
let dashboard_id = format!("{}.{}", &dashboard.user_id, Utc::now().timestamp_millis());
56+
let dashboard_id = get_hash(Utc::now().timestamp_micros().to_string().as_str());
5857
dashboard.dashboard_id = Some(dashboard_id.clone());
5958
dashboard.version = Some(CURRENT_DASHBOARD_VERSION.to_string());
59+
dashboard.user_id = Some(get_hash(&user_id));
6060
for tile in dashboard.tiles.iter_mut() {
61-
tile.tile_id = Some(format!(
62-
"{}.{}",
63-
&dashboard.user_id,
64-
Utc::now().timestamp_micros()
65-
));
61+
tile.tile_id = Some(get_hash(Utc::now().timestamp_micros().to_string().as_str()));
6662
}
6763
DASHBOARDS.update(&dashboard);
6864

69-
let path = dashboard_path(&dashboard.user_id, &format!("{}.json", dashboard_id));
65+
let path = dashboard_path(&user_id, &format!("{}.json", dashboard_id));
7066

7167
let store = CONFIG.storage().get_object_store();
7268
let dashboard_bytes = serde_json::to_vec(&dashboard)?;
@@ -77,31 +73,26 @@ pub async fn post(body: Bytes) -> Result<impl Responder, PostError> {
7773
Ok((web::Json(dashboard), StatusCode::OK))
7874
}
7975

80-
pub async fn update(req: HttpRequest, body: Bytes) -> Result<impl Responder, PostError> {
76+
pub async fn update(req: HttpRequest, body: Bytes) -> Result<impl Responder, DashboardError> {
77+
let user_id = get_user_from_request(&req)?;
8178
let dashboard_id = req
8279
.match_info()
8380
.get("dashboard_id")
8481
.ok_or(DashboardError::Metadata("No Dashboard Id Provided"))?;
8582
if DASHBOARDS.get_dashboard(dashboard_id).is_none() {
86-
return Err(PostError::DashboardError(DashboardError::Metadata(
87-
"Dashboard does not exist",
88-
)));
83+
return Err(DashboardError::Metadata("Dashboard does not exist"));
8984
}
9085
let mut dashboard: Dashboard = serde_json::from_slice(&body)?;
9186
dashboard.dashboard_id = Some(dashboard_id.to_string());
9287
dashboard.version = Some(CURRENT_DASHBOARD_VERSION.to_string());
9388
for tile in dashboard.tiles.iter_mut() {
9489
if tile.tile_id.is_none() {
95-
tile.tile_id = Some(format!(
96-
"{}.{}",
97-
&dashboard.user_id,
98-
Utc::now().timestamp_micros()
99-
));
90+
tile.tile_id = Some(get_hash(Utc::now().timestamp_micros().to_string().as_str()));
10091
}
10192
}
10293
DASHBOARDS.update(&dashboard);
10394

104-
let path = dashboard_path(&dashboard.user_id, &format!("{}.json", dashboard_id));
95+
let path = dashboard_path(&user_id, &format!("{}.json", dashboard_id));
10596

10697
let store = CONFIG.storage().get_object_store();
10798
let dashboard_bytes = serde_json::to_vec(&dashboard)?;
@@ -112,16 +103,13 @@ pub async fn update(req: HttpRequest, body: Bytes) -> Result<impl Responder, Pos
112103
Ok((web::Json(dashboard), StatusCode::OK))
113104
}
114105

115-
pub async fn delete(req: HttpRequest) -> Result<HttpResponse, PostError> {
106+
pub async fn delete(req: HttpRequest) -> Result<HttpResponse, DashboardError> {
107+
let user_id = get_user_from_request(&req)?;
116108
let dashboard_id = req
117109
.match_info()
118110
.get("dashboard_id")
119111
.ok_or(DashboardError::Metadata("No Dashboard Id Provided"))?;
120-
let dashboard = DASHBOARDS
121-
.get_dashboard(dashboard_id)
122-
.ok_or(DashboardError::Metadata("Dashboard does not exist"))?;
123-
124-
let path = dashboard_path(&dashboard.user_id, &format!("{}.json", dashboard_id));
112+
let path = dashboard_path(&user_id, &format!("{}.json", dashboard_id));
125113
let store = CONFIG.storage().get_object_store();
126114
store.delete_object(&path).await?;
127115

@@ -138,6 +126,8 @@ pub enum DashboardError {
138126
Serde(#[from] SerdeError),
139127
#[error("Cannot perform this operation: {0}")]
140128
Metadata(&'static str),
129+
#[error("User does not exist")]
130+
UserDoesNotExist(#[from] RBACError),
141131
}
142132

143133
impl actix_web::ResponseError for DashboardError {
@@ -146,6 +136,7 @@ impl actix_web::ResponseError for DashboardError {
146136
Self::ObjectStorage(_) => StatusCode::INTERNAL_SERVER_ERROR,
147137
Self::Serde(_) => StatusCode::BAD_REQUEST,
148138
Self::Metadata(_) => StatusCode::BAD_REQUEST,
139+
Self::UserDoesNotExist(_) => StatusCode::NOT_FOUND,
149140
}
150141
}
151142

server/src/handlers/http/users/filters.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@
1717
*/
1818

1919
use crate::{
20-
handlers::http::ingest::PostError,
20+
handlers::http::rbac::RBACError,
2121
option::CONFIG,
2222
storage::{object_storage::filter_path, ObjectStorageError},
2323
users::filters::{Filter, CURRENT_FILTER_VERSION, FILTERS},
24+
utils::{get_hash, get_user_from_request},
2425
};
2526
use actix_web::{http::header::ContentType, web, HttpRequest, HttpResponse, Responder};
2627
use bytes::Bytes;
@@ -29,12 +30,8 @@ use http::StatusCode;
2930
use serde_json::Error as SerdeError;
3031

3132
pub async fn list(req: HttpRequest) -> Result<impl Responder, FiltersError> {
32-
let user_id = req
33-
.match_info()
34-
.get("user_id")
35-
.ok_or(FiltersError::Metadata("No User Id Provided"))?;
36-
let filters = FILTERS.list_filters_by_user(user_id);
37-
33+
let user_id = get_user_from_request(&req)?;
34+
let filters = FILTERS.list_filters_by_user(&get_hash(&user_id));
3835
Ok((web::Json(filters), StatusCode::OK))
3936
}
4037

@@ -51,20 +48,17 @@ pub async fn get(req: HttpRequest) -> Result<impl Responder, FiltersError> {
5148
Err(FiltersError::Metadata("Filter does not exist"))
5249
}
5350

54-
pub async fn post(body: Bytes) -> Result<impl Responder, PostError> {
51+
pub async fn post(req: HttpRequest, body: Bytes) -> Result<impl Responder, FiltersError> {
52+
let user_id = get_user_from_request(&req)?;
5553
let mut filter: Filter = serde_json::from_slice(&body)?;
56-
let filter_id = format!(
57-
"{}.{}.{}",
58-
&filter.user_id,
59-
&filter.stream_name,
60-
Utc::now().timestamp_millis()
61-
);
54+
let filter_id = get_hash(Utc::now().timestamp_micros().to_string().as_str());
6255
filter.filter_id = Some(filter_id.clone());
56+
filter.user_id = Some(get_hash(&user_id));
6357
filter.version = Some(CURRENT_FILTER_VERSION.to_string());
6458
FILTERS.update(&filter);
6559

6660
let path = filter_path(
67-
&filter.user_id,
61+
&user_id,
6862
&filter.stream_name,
6963
&format!("{}.json", filter_id),
7064
);
@@ -76,23 +70,22 @@ pub async fn post(body: Bytes) -> Result<impl Responder, PostError> {
7670
Ok((web::Json(filter), StatusCode::OK))
7771
}
7872

79-
pub async fn update(req: HttpRequest, body: Bytes) -> Result<HttpResponse, PostError> {
73+
pub async fn update(req: HttpRequest, body: Bytes) -> Result<HttpResponse, FiltersError> {
74+
let user_id = get_user_from_request(&req)?;
8075
let filter_id = req
8176
.match_info()
8277
.get("filter_id")
8378
.ok_or(FiltersError::Metadata("No Filter Id Provided"))?;
8479
if FILTERS.get_filter(filter_id).is_none() {
85-
return Err(PostError::FiltersError(FiltersError::Metadata(
86-
"Filter does not exist",
87-
)));
80+
return Err(FiltersError::Metadata("Filter does not exist"));
8881
}
8982
let mut filter: Filter = serde_json::from_slice(&body)?;
9083
filter.filter_id = Some(filter_id.to_string());
9184
filter.version = Some(CURRENT_FILTER_VERSION.to_string());
9285
FILTERS.update(&filter);
9386

9487
let path = filter_path(
95-
&filter.user_id,
88+
&user_id,
9689
&filter.stream_name,
9790
&format!("{}.json", filter_id),
9891
);
@@ -104,7 +97,8 @@ pub async fn update(req: HttpRequest, body: Bytes) -> Result<HttpResponse, PostE
10497
Ok(HttpResponse::Ok().finish())
10598
}
10699

107-
pub async fn delete(req: HttpRequest) -> Result<HttpResponse, PostError> {
100+
pub async fn delete(req: HttpRequest) -> Result<HttpResponse, FiltersError> {
101+
let user_id = get_user_from_request(&req)?;
108102
let filter_id = req
109103
.match_info()
110104
.get("filter_id")
@@ -114,7 +108,7 @@ pub async fn delete(req: HttpRequest) -> Result<HttpResponse, PostError> {
114108
.ok_or(FiltersError::Metadata("Filter does not exist"))?;
115109

116110
let path = filter_path(
117-
&filter.user_id,
111+
&user_id,
118112
&filter.stream_name,
119113
&format!("{}.json", filter_id),
120114
);
@@ -134,6 +128,8 @@ pub enum FiltersError {
134128
Serde(#[from] SerdeError),
135129
#[error("Operation cannot be performed: {0}")]
136130
Metadata(&'static str),
131+
#[error("User does not exist")]
132+
UserDoesNotExist(#[from] RBACError),
137133
}
138134

139135
impl actix_web::ResponseError for FiltersError {
@@ -142,6 +138,7 @@ impl actix_web::ResponseError for FiltersError {
142138
Self::ObjectStorage(_) => StatusCode::INTERNAL_SERVER_ERROR,
143139
Self::Serde(_) => StatusCode::BAD_REQUEST,
144140
Self::Metadata(_) => StatusCode::BAD_REQUEST,
141+
Self::UserDoesNotExist(_) => StatusCode::NOT_FOUND,
145142
}
146143
}
147144

server/src/rbac.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ impl Users {
168168

169169
Response::UnAuthorized
170170
}
171+
172+
pub fn get_username_from_session(&self, session: &SessionKey) -> Option<String> {
173+
sessions().get_username(session).cloned()
174+
}
171175
}
172176

173177
fn roles_to_permission(roles: Vec<String>) -> Vec<Permission> {

server/src/rbac/map.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ impl Sessions {
224224
})
225225
})
226226
}
227+
228+
pub fn get_username(&self, key: &SessionKey) -> Option<&String> {
229+
self.active_sessions.get(key).map(|(username, _)| username)
230+
}
227231
}
228232

229233
// UserMap is a map of [username --> User]

0 commit comments

Comments
 (0)