Skip to content

Commit

Permalink
fix: remove user_id from API requests in Dashboards and Filters (#918)
Browse files Browse the repository at this point in the history
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}
  • Loading branch information
nikhilsinhaparseable authored Sep 10, 2024
1 parent 4154fc2 commit 75cda6b
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 127 deletions.
96 changes: 44 additions & 52 deletions server/src/handlers/http/modal/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,72 +197,64 @@ impl Server {
pub fn get_dashboards_webscope() -> Scope {
web::scope("/dashboards")
.service(
web::resource("").route(
web::post()
.to(dashboards::post)
.authorize(Action::CreateDashboard),
),
)
.service(
web::scope("/dashboard").service(
web::resource("/{dashboard_id}")
.route(
web::get()
.to(dashboards::get)
.authorize(Action::GetDashboard),
)
.route(
web::delete()
.to(dashboards::delete)
.authorize(Action::DeleteDashboard),
)
.route(
web::put()
.to(dashboards::update)
.authorize(Action::CreateDashboard),
),
),
)
.service(
web::scope("/{user_id}").service(
web::resource("").route(
web::resource("")
.route(
web::post()
.to(dashboards::post)
.authorize(Action::CreateDashboard),
)
.route(
web::get()
.to(dashboards::list)
.authorize(Action::ListDashboard),
),
),
)
.service(
web::resource("/{dashboard_id}")
.route(
web::get()
.to(dashboards::get)
.authorize(Action::GetDashboard),
)
.route(
web::delete()
.to(dashboards::delete)
.authorize(Action::DeleteDashboard),
)
.route(
web::put()
.to(dashboards::update)
.authorize(Action::CreateDashboard),
),
)
}

// get the filters web scope
pub fn get_filters_webscope() -> Scope {
web::scope("/filters")
.service(
web::resource("").route(
web::post()
.to(filters::post)
.authorize(Action::CreateFilter),
),
web::resource("")
.route(
web::post()
.to(filters::post)
.authorize(Action::CreateFilter),
)
.route(web::get().to(filters::list).authorize(Action::ListFilter)),
)
.service(
web::scope("/filter").service(
web::resource("/{filter_id}")
.route(web::get().to(filters::get).authorize(Action::GetFilter))
.route(
web::delete()
.to(filters::delete)
.authorize(Action::DeleteFilter),
)
.route(
web::put()
.to(filters::update)
.authorize(Action::CreateFilter),
),
),
web::resource("/{filter_id}")
.route(web::get().to(filters::get).authorize(Action::GetFilter))
.route(
web::delete()
.to(filters::delete)
.authorize(Action::DeleteFilter),
)
.route(
web::put()
.to(filters::update)
.authorize(Action::CreateFilter),
),
)
.service(web::scope("/{user_id}").service(
web::resource("").route(web::get().to(filters::list).authorize(Action::ListFilter)),
))
}

// get the query factory
Expand Down
65 changes: 33 additions & 32 deletions server/src/handlers/http/users/dashboards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
*/

use crate::{
handlers::http::ingest::PostError,
handlers::http::rbac::RBACError,
option::CONFIG,
storage::{object_storage::dashboard_path, ObjectStorageError},
users::dashboards::{Dashboard, CURRENT_DASHBOARD_VERSION, DASHBOARDS},
utils::{get_hash, get_user_from_request},
};
use actix_web::{http::header::ContentType, web, HttpRequest, HttpResponse, Responder};
use bytes::Bytes;
Expand All @@ -30,43 +31,39 @@ use http::StatusCode;
use serde_json::Error as SerdeError;

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

Ok((web::Json(dashboards), StatusCode::OK))
}

pub async fn get(req: HttpRequest) -> Result<impl Responder, DashboardError> {
let user_id = get_user_from_request(&req)?;
let dashboard_id = req
.match_info()
.get("dashboard_id")
.ok_or(DashboardError::Metadata("No Dashboard Id Provided"))?;

if let Some(dashboard) = DASHBOARDS.get_dashboard(dashboard_id) {
if let Some(dashboard) = DASHBOARDS.get_dashboard(dashboard_id, &get_hash(&user_id)) {
return Ok((web::Json(dashboard), StatusCode::OK));
}

Err(DashboardError::Metadata("Dashboard does not exist"))
}

pub async fn post(body: Bytes) -> Result<impl Responder, PostError> {
pub async fn post(req: HttpRequest, body: Bytes) -> Result<impl Responder, DashboardError> {
let user_id = get_user_from_request(&req)?;
let mut dashboard: Dashboard = serde_json::from_slice(&body)?;
let dashboard_id = format!("{}.{}", &dashboard.user_id, Utc::now().timestamp_millis());
let dashboard_id = get_hash(Utc::now().timestamp_micros().to_string().as_str());
dashboard.dashboard_id = Some(dashboard_id.clone());
dashboard.version = Some(CURRENT_DASHBOARD_VERSION.to_string());
dashboard.user_id = Some(get_hash(&user_id));
for tile in dashboard.tiles.iter_mut() {
tile.tile_id = Some(format!(
"{}.{}",
&dashboard.user_id,
Utc::now().timestamp_micros()
));
tile.tile_id = Some(get_hash(Utc::now().timestamp_micros().to_string().as_str()));
}
DASHBOARDS.update(&dashboard);

let path = dashboard_path(&dashboard.user_id, &format!("{}.json", dashboard_id));
let path = dashboard_path(&user_id, &format!("{}.json", dashboard_id));

let store = CONFIG.storage().get_object_store();
let dashboard_bytes = serde_json::to_vec(&dashboard)?;
Expand All @@ -77,31 +74,29 @@ pub async fn post(body: Bytes) -> Result<impl Responder, PostError> {
Ok((web::Json(dashboard), StatusCode::OK))
}

pub async fn update(req: HttpRequest, body: Bytes) -> Result<impl Responder, PostError> {
pub async fn update(req: HttpRequest, body: Bytes) -> Result<impl Responder, DashboardError> {
let user_id = get_user_from_request(&req)?;
let dashboard_id = req
.match_info()
.get("dashboard_id")
.ok_or(DashboardError::Metadata("No Dashboard Id Provided"))?;
if DASHBOARDS.get_dashboard(dashboard_id).is_none() {
return Err(PostError::DashboardError(DashboardError::Metadata(
"Dashboard does not exist",
)));
if DASHBOARDS
.get_dashboard(dashboard_id, &get_hash(&user_id))
.is_none()
{
return Err(DashboardError::Metadata("Dashboard does not exist"));
}
let mut dashboard: Dashboard = serde_json::from_slice(&body)?;
dashboard.dashboard_id = Some(dashboard_id.to_string());
dashboard.version = Some(CURRENT_DASHBOARD_VERSION.to_string());
for tile in dashboard.tiles.iter_mut() {
if tile.tile_id.is_none() {
tile.tile_id = Some(format!(
"{}.{}",
&dashboard.user_id,
Utc::now().timestamp_micros()
));
tile.tile_id = Some(get_hash(Utc::now().timestamp_micros().to_string().as_str()));
}
}
DASHBOARDS.update(&dashboard);

let path = dashboard_path(&dashboard.user_id, &format!("{}.json", dashboard_id));
let path = dashboard_path(&user_id, &format!("{}.json", dashboard_id));

let store = CONFIG.storage().get_object_store();
let dashboard_bytes = serde_json::to_vec(&dashboard)?;
Expand All @@ -112,16 +107,19 @@ pub async fn update(req: HttpRequest, body: Bytes) -> Result<impl Responder, Pos
Ok((web::Json(dashboard), StatusCode::OK))
}

pub async fn delete(req: HttpRequest) -> Result<HttpResponse, PostError> {
pub async fn delete(req: HttpRequest) -> Result<HttpResponse, DashboardError> {
let user_id = get_user_from_request(&req)?;
let dashboard_id = req
.match_info()
.get("dashboard_id")
.ok_or(DashboardError::Metadata("No Dashboard Id Provided"))?;
let dashboard = DASHBOARDS
.get_dashboard(dashboard_id)
.ok_or(DashboardError::Metadata("Dashboard does not exist"))?;

let path = dashboard_path(&dashboard.user_id, &format!("{}.json", dashboard_id));
if DASHBOARDS
.get_dashboard(dashboard_id, &get_hash(&user_id))
.is_none()
{
return Err(DashboardError::Metadata("Dashboard does not exist"));
}
let path = dashboard_path(&user_id, &format!("{}.json", dashboard_id));
let store = CONFIG.storage().get_object_store();
store.delete_object(&path).await?;

Expand All @@ -138,6 +136,8 @@ pub enum DashboardError {
Serde(#[from] SerdeError),
#[error("Cannot perform this operation: {0}")]
Metadata(&'static str),
#[error("User does not exist")]
UserDoesNotExist(#[from] RBACError),
}

impl actix_web::ResponseError for DashboardError {
Expand All @@ -146,6 +146,7 @@ impl actix_web::ResponseError for DashboardError {
Self::ObjectStorage(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::Serde(_) => StatusCode::BAD_REQUEST,
Self::Metadata(_) => StatusCode::BAD_REQUEST,
Self::UserDoesNotExist(_) => StatusCode::NOT_FOUND,
}
}

Expand Down
Loading

0 comments on commit 75cda6b

Please sign in to comment.