mirror of
				https://github.com/dani-garcia/vaultwarden.git
				synced 2025-10-26 07:50:02 +02:00 
			
		
		
		
	Implement request guards for organization
This commit is contained in:
		| @@ -6,7 +6,7 @@ use db::DbConn; | ||||
| use db::models::*; | ||||
|  | ||||
| use api::{PasswordData, JsonResult, EmptyResult, NumberOrString}; | ||||
| use auth::Headers; | ||||
| use auth::{Headers, AdminHeaders, OwnerHeaders}; | ||||
|  | ||||
|  | ||||
| #[derive(Deserialize)] | ||||
| @@ -82,11 +82,7 @@ fn delete_organization(org_id: String, data: Json<PasswordData>, headers: Header | ||||
| } | ||||
|  | ||||
| #[get("/organizations/<org_id>")] | ||||
| fn get_organization(org_id: String, headers: Headers, conn: DbConn) -> JsonResult { | ||||
|     if UserOrganization::find_by_user_and_org( &headers.user.uuid, &org_id, &conn).is_none() { | ||||
|         err!("User not in Organization or Organization doesn't exist") | ||||
|     } | ||||
|  | ||||
| fn get_organization(org_id: String, headers: OwnerHeaders, conn: DbConn) -> JsonResult { | ||||
|     match Organization::find_by_uuid(&org_id, &conn) { | ||||
|         Some(organization) => Ok(Json(organization.to_json())), | ||||
|         None => err!("Can't find organization details") | ||||
| @@ -132,7 +128,7 @@ fn get_user_collections(headers: Headers, conn: DbConn) -> JsonResult { | ||||
| } | ||||
|  | ||||
| #[get("/organizations/<org_id>/collections")] | ||||
| fn get_org_collections(org_id: String, headers: Headers, conn: DbConn) -> JsonResult { | ||||
| fn get_org_collections(org_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult { | ||||
|     Ok(Json(json!({ | ||||
|         "Data": | ||||
|             Collection::find_by_organization(&org_id, &conn) | ||||
| @@ -226,7 +222,7 @@ fn post_organization_collection_delete(org_id: String, col_id: String, headers: | ||||
| } | ||||
|  | ||||
| #[get("/organizations/<org_id>/collections/<coll_id>/details")] | ||||
| fn get_org_collection_detail(org_id: String, coll_id: String, headers: Headers, conn: DbConn) -> JsonResult { | ||||
| fn get_org_collection_detail(org_id: String, coll_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult { | ||||
|     match Collection::find_by_uuid_and_user(&coll_id, &headers.user.uuid, &conn) { | ||||
|         None => err!("Collection not found"), | ||||
|         Some(collection) => Ok(Json(collection.to_json())) | ||||
| @@ -234,7 +230,7 @@ fn get_org_collection_detail(org_id: String, coll_id: String, headers: Headers, | ||||
| } | ||||
|  | ||||
| #[get("/organizations/<org_id>/collections/<coll_id>/users")] | ||||
| fn get_collection_users(org_id: String, coll_id: String, headers: Headers, conn: DbConn) -> JsonResult { | ||||
| fn get_collection_users(org_id: String, coll_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult { | ||||
|     // Get org and collection, check that collection is from org | ||||
|  | ||||
|     // Get the users from collection | ||||
| @@ -278,7 +274,7 @@ fn get_org_details(data: OrgIdData, headers: Headers, conn: DbConn) -> JsonResul | ||||
| } | ||||
|  | ||||
| #[get("/organizations/<org_id>/users")] | ||||
| fn get_org_users(org_id: String, headers: Headers, conn: DbConn) -> JsonResult { | ||||
| fn get_org_users(org_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult { | ||||
|     match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { | ||||
|         Some(_) => (), | ||||
|         None => err!("User isn't member of organization") | ||||
| @@ -408,13 +404,7 @@ fn confirm_invite(org_id: String, user_id: String, data: Json<Value>, headers: H | ||||
| } | ||||
|  | ||||
| #[get("/organizations/<org_id>/users/<user_id>")] | ||||
| fn get_user(org_id: String, user_id: String, headers: Headers, conn: DbConn) -> JsonResult { | ||||
|     let current_user = match UserOrganization::find_by_user_and_org( | ||||
|         &headers.user.uuid, &org_id, &conn) { | ||||
|         Some(user) => user, | ||||
|         None => err!("The current user isn't member of the organization") | ||||
|     }; | ||||
|  | ||||
| fn get_user(org_id: String, user_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult { | ||||
|     let user = match UserOrganization::find_by_uuid(&user_id, &conn) { | ||||
|         Some(user) => user, | ||||
|         None => err!("The specified user isn't member of the organization") | ||||
|   | ||||
							
								
								
									
										102
									
								
								src/auth.rs
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								src/auth.rs
									
									
									
									
									
								
							| @@ -94,7 +94,7 @@ use rocket::Outcome; | ||||
| use rocket::request::{self, Request, FromRequest}; | ||||
|  | ||||
| use db::DbConn; | ||||
| use db::models::{User, Device}; | ||||
| use db::models::{User, UserOrganization, UserOrgType, Device}; | ||||
|  | ||||
| pub struct Headers { | ||||
|     pub host: String, | ||||
| @@ -155,4 +155,104 @@ impl<'a, 'r> FromRequest<'a, 'r> for Headers { | ||||
|  | ||||
|         Outcome::Success(Headers { host, device, user }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub struct OrgHeaders { | ||||
|     pub host: String, | ||||
|     pub device: Device, | ||||
|     pub user: User, | ||||
|     pub org_user_type: i32, | ||||
| } | ||||
|  | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for OrgHeaders { | ||||
|     type Error = &'static str; | ||||
|  | ||||
|     fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         match request.guard::<Headers>() { | ||||
|             Outcome::Forward(f) => Outcome::Forward(f), | ||||
|             Outcome::Failure(f) => Outcome::Failure(f), | ||||
|             Outcome::Success(headers) => { | ||||
|                 // org_id is expected to be the first dynamic param | ||||
|                 match request.get_param::<String>(0) { | ||||
|                     Err(_) => err_handler!("Error getting the organization id"), | ||||
|                     Ok(org_id) => { | ||||
|                         let conn = match request.guard::<DbConn>() { | ||||
|                             Outcome::Success(conn) => conn, | ||||
|                             _ => err_handler!("Error getting DB") | ||||
|                         }; | ||||
|  | ||||
|                         let org_user = match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { | ||||
|                             Some(user) => user, | ||||
|                             None => err_handler!("The current user isn't member of the organization") | ||||
|                         }; | ||||
|  | ||||
|                         Outcome::Success(Self{ | ||||
|                             host: headers.host, | ||||
|                             device: headers.device, | ||||
|                             user: headers.user, | ||||
|                             org_user_type: org_user.type_, | ||||
|                         }) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub struct AdminHeaders { | ||||
|     pub host: String, | ||||
|     pub device: Device, | ||||
|     pub user: User, | ||||
|     pub org_user_type: i32, | ||||
| } | ||||
|  | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for AdminHeaders { | ||||
|     type Error = &'static str; | ||||
|  | ||||
|     fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         match request.guard::<OrgHeaders>() { | ||||
|             Outcome::Forward(f) => Outcome::Forward(f), | ||||
|             Outcome::Failure(f) => Outcome::Failure(f), | ||||
|             Outcome::Success(headers) => { | ||||
|                 if headers.org_user_type > UserOrgType::Admin as i32 { | ||||
|                     err_handler!("You need to be Admin or Owner to call this endpoint") | ||||
|                 } else { | ||||
|                     Outcome::Success(Self{ | ||||
|                         host: headers.host, | ||||
|                         device: headers.device, | ||||
|                         user: headers.user, | ||||
|                         org_user_type: headers.org_user_type, | ||||
|                     }) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub struct OwnerHeaders { | ||||
|     pub host: String, | ||||
|     pub device: Device, | ||||
|     pub user: User, | ||||
| } | ||||
|  | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for OwnerHeaders { | ||||
|     type Error = &'static str; | ||||
|  | ||||
|     fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         match request.guard::<OrgHeaders>() { | ||||
|             Outcome::Forward(f) => Outcome::Forward(f), | ||||
|             Outcome::Failure(f) => Outcome::Failure(f), | ||||
|             Outcome::Success(headers) => { | ||||
|                 if headers.org_user_type > UserOrgType::Owner as i32 { | ||||
|                     err_handler!("You need to be Owner to call this endpoint") | ||||
|                 } else { | ||||
|                     Outcome::Success(Self{ | ||||
|                         host: headers.host, | ||||
|                         device: headers.device, | ||||
|                         user: headers.user, | ||||
|                     }) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user