mirror of
				https://github.com/dani-garcia/vaultwarden.git
				synced 2025-10-30 17:58:19 +02:00 
			
		
		
		
	let invited members access OrgMemberHeaders (#5461)
This commit is contained in:
		
							
								
								
									
										53
									
								
								src/auth.rs
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								src/auth.rs
									
									
									
									
									
								
							| @@ -542,10 +542,29 @@ pub struct OrgHeaders { | ||||
|     pub device: Device, | ||||
|     pub user: User, | ||||
|     pub membership_type: MembershipType, | ||||
|     pub membership_status: MembershipStatus, | ||||
|     pub membership: Membership, | ||||
|     pub ip: ClientIp, | ||||
| } | ||||
|  | ||||
| impl OrgHeaders { | ||||
|     fn is_member(&self) -> bool { | ||||
|         // NOTE: we don't care about MembershipStatus at the moment because this is only used | ||||
|         // where an invited, accepted or confirmed user is expected if this ever changes or | ||||
|         // if from_i32 is changed to return Some(Revoked) this check needs to be changed accordingly | ||||
|         self.membership_type >= MembershipType::User | ||||
|     } | ||||
|     fn is_confirmed_and_admin(&self) -> bool { | ||||
|         self.membership_status == MembershipStatus::Confirmed && self.membership_type >= MembershipType::Admin | ||||
|     } | ||||
|     fn is_confirmed_and_manager(&self) -> bool { | ||||
|         self.membership_status == MembershipStatus::Confirmed && self.membership_type >= MembershipType::Manager | ||||
|     } | ||||
|     fn is_confirmed_and_owner(&self) -> bool { | ||||
|         self.membership_status == MembershipStatus::Confirmed && self.membership_type == MembershipType::Owner | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[rocket::async_trait] | ||||
| impl<'r> FromRequest<'r> for OrgHeaders { | ||||
|     type Error = &'static str; | ||||
| @@ -574,15 +593,8 @@ impl<'r> FromRequest<'r> for OrgHeaders { | ||||
|                 }; | ||||
|  | ||||
|                 let user = headers.user; | ||||
|                 let membership = match Membership::find_by_user_and_org(&user.uuid, &org_id, &mut conn).await { | ||||
|                     Some(member) => { | ||||
|                         if member.status == MembershipStatus::Confirmed as i32 { | ||||
|                             member | ||||
|                         } else { | ||||
|                             err_handler!("The current user isn't confirmed member of the organization") | ||||
|                         } | ||||
|                     } | ||||
|                     None => err_handler!("The current user isn't member of the organization"), | ||||
|                 let Some(membership) = Membership::find_by_user_and_org(&user.uuid, &org_id, &mut conn).await else { | ||||
|                     err_handler!("The current user isn't member of the organization"); | ||||
|                 }; | ||||
|  | ||||
|                 Outcome::Success(Self { | ||||
| @@ -590,13 +602,22 @@ impl<'r> FromRequest<'r> for OrgHeaders { | ||||
|                     device: headers.device, | ||||
|                     user, | ||||
|                     membership_type: { | ||||
|                         if let Some(org_usr_type) = MembershipType::from_i32(membership.atype) { | ||||
|                             org_usr_type | ||||
|                         if let Some(member_type) = MembershipType::from_i32(membership.atype) { | ||||
|                             member_type | ||||
|                         } else { | ||||
|                             // This should only happen if the DB is corrupted | ||||
|                             err_handler!("Unknown user type in the database") | ||||
|                         } | ||||
|                     }, | ||||
|                     membership_status: { | ||||
|                         if let Some(member_status) = MembershipStatus::from_i32(membership.status) { | ||||
|                             // NOTE: add additional check for revoked if from_i32 is ever changed | ||||
|                             // to return Revoked status. | ||||
|                             member_status | ||||
|                         } else { | ||||
|                             err_handler!("User status is either revoked or invalid.") | ||||
|                         } | ||||
|                     }, | ||||
|                     membership, | ||||
|                     ip: headers.ip, | ||||
|                 }) | ||||
| @@ -621,7 +642,7 @@ impl<'r> FromRequest<'r> for AdminHeaders { | ||||
|  | ||||
|     async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> { | ||||
|         let headers = try_outcome!(OrgHeaders::from_request(request).await); | ||||
|         if headers.membership_type >= MembershipType::Admin { | ||||
|         if headers.is_confirmed_and_admin() { | ||||
|             Outcome::Success(Self { | ||||
|                 host: headers.host, | ||||
|                 device: headers.device, | ||||
| @@ -683,7 +704,7 @@ impl<'r> FromRequest<'r> for ManagerHeaders { | ||||
|  | ||||
|     async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> { | ||||
|         let headers = try_outcome!(OrgHeaders::from_request(request).await); | ||||
|         if headers.membership_type >= MembershipType::Manager { | ||||
|         if headers.is_confirmed_and_manager() { | ||||
|             match get_col_id(request) { | ||||
|                 Some(col_id) => { | ||||
|                     let mut conn = match DbConn::from_request(request).await { | ||||
| @@ -738,7 +759,7 @@ impl<'r> FromRequest<'r> for ManagerHeadersLoose { | ||||
|  | ||||
|     async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> { | ||||
|         let headers = try_outcome!(OrgHeaders::from_request(request).await); | ||||
|         if headers.membership_type >= MembershipType::Manager { | ||||
|         if headers.is_confirmed_and_manager() { | ||||
|             Outcome::Success(Self { | ||||
|                 host: headers.host, | ||||
|                 device: headers.device, | ||||
| @@ -801,7 +822,7 @@ impl<'r> FromRequest<'r> for OwnerHeaders { | ||||
|  | ||||
|     async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> { | ||||
|         let headers = try_outcome!(OrgHeaders::from_request(request).await); | ||||
|         if headers.membership_type == MembershipType::Owner { | ||||
|         if headers.is_confirmed_and_owner() { | ||||
|             Outcome::Success(Self { | ||||
|                 device: headers.device, | ||||
|                 user: headers.user, | ||||
| @@ -826,7 +847,7 @@ impl<'r> FromRequest<'r> for OrgMemberHeaders { | ||||
|  | ||||
|     async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> { | ||||
|         let headers = try_outcome!(OrgHeaders::from_request(request).await); | ||||
|         if headers.membership_type >= MembershipType::User { | ||||
|         if headers.is_member() { | ||||
|             Outcome::Success(Self { | ||||
|                 host: headers.host, | ||||
|                 user: headers.user, | ||||
|   | ||||
| @@ -55,6 +55,7 @@ db_object! { | ||||
| } | ||||
|  | ||||
| // https://github.com/bitwarden/server/blob/b86a04cef9f1e1b82cf18e49fc94e017c641130c/src/Core/Enums/OrganizationUserStatusType.cs | ||||
| #[derive(PartialEq)] | ||||
| pub enum MembershipStatus { | ||||
|     Revoked = -1, | ||||
|     Invited = 0, | ||||
| @@ -62,6 +63,19 @@ pub enum MembershipStatus { | ||||
|     Confirmed = 2, | ||||
| } | ||||
|  | ||||
| impl MembershipStatus { | ||||
|     pub fn from_i32(status: i32) -> Option<Self> { | ||||
|         match status { | ||||
|             0 => Some(Self::Invited), | ||||
|             1 => Some(Self::Accepted), | ||||
|             2 => Some(Self::Confirmed), | ||||
|             // NOTE: we don't care about revoked members where this is used | ||||
|             // if this ever changes also adapt the OrgHeaders check. | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Copy, Clone, PartialEq, Eq, num_derive::FromPrimitive)] | ||||
| pub enum MembershipType { | ||||
|     Owner = 0, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user