use actix_web::{get, http::header::ContentType, post, web, HttpResponse, Responder}; use gamenight_database::{ location_owner::{grant_permission, location_permissions, revoke_permission, LocationOwner}, user::Role, DbPool, GetConnection, }; use uuid::Uuid; use crate::{ models::{ authorize_location_request_body::{ AuthorizeLocationRequestBody, Op::{Grant, Revoke}, }, location_id::LocationId, user_id::UserId, }, request::{authorization::AuthUser, error::ApiError}, }; impl<'a> TryFrom<&'a AuthorizeLocationRequestBody> for LocationOwner { type Error = ApiError; fn try_from(value: &'a AuthorizeLocationRequestBody) -> Result { Ok(LocationOwner { location_id: Uuid::parse_str(&value.location_id)?, user_id: Uuid::parse_str(&value.user_id)?, }) } } #[post("/location_authorize")] pub async fn post_location_authorize( pool: web::Data, user: AuthUser, auth_data: web::Json, ) -> Result { let mut conn = pool.get_conn(); let inner_auth_data = &auth_data.into_inner(); let location_owner: LocationOwner = inner_auth_data.try_into()?; let authorized = location_permissions(&mut conn, location_owner.location_id)?; if user.0.role != Role::Admin && !authorized.contains(&user.0.id) { Ok(HttpResponse::Unauthorized()) } else { match inner_auth_data.op { Grant => grant_permission(&mut conn, location_owner)?, Revoke => revoke_permission(&mut conn, location_owner)?, }; Ok(HttpResponse::Ok()) } } impl From for UserId { fn from(value: Uuid) -> Self { Self { user_id: value.to_string(), } } } #[get("/authorized_location_user_ids")] pub async fn get_authorized_location_user_ids( pool: web::Data, _user: AuthUser, location_id: web::Json, ) -> Result { let mut conn = pool.get_conn(); let permissions = location_permissions(&mut conn, Uuid::parse_str(&location_id.0.location_id)?)?; let model: Vec = permissions.into_iter().map(Into::into).collect(); Ok(HttpResponse::Ok() .content_type(ContentType::json()) .body(serde_json::to_string(&model)?)) }