Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2025-01-31 10:08:56 +01:00
let invited members access OrgMemberHeaders (#5461)
Dieser Commit ist enthalten in:
Ursprung
ecab7a50ea
Commit
2c549984c0
2 geänderte Dateien mit 51 neuen und 16 gelöschten Zeilen
53
src/auth.rs
53
src/auth.rs
|
@ -542,10 +542,29 @@ pub struct OrgHeaders {
|
||||||
pub device: Device,
|
pub device: Device,
|
||||||
pub user: User,
|
pub user: User,
|
||||||
pub membership_type: MembershipType,
|
pub membership_type: MembershipType,
|
||||||
|
pub membership_status: MembershipStatus,
|
||||||
pub membership: Membership,
|
pub membership: Membership,
|
||||||
pub ip: ClientIp,
|
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]
|
#[rocket::async_trait]
|
||||||
impl<'r> FromRequest<'r> for OrgHeaders {
|
impl<'r> FromRequest<'r> for OrgHeaders {
|
||||||
type Error = &'static str;
|
type Error = &'static str;
|
||||||
|
@ -574,15 +593,8 @@ impl<'r> FromRequest<'r> for OrgHeaders {
|
||||||
};
|
};
|
||||||
|
|
||||||
let user = headers.user;
|
let user = headers.user;
|
||||||
let membership = match Membership::find_by_user_and_org(&user.uuid, &org_id, &mut conn).await {
|
let Some(membership) = Membership::find_by_user_and_org(&user.uuid, &org_id, &mut conn).await else {
|
||||||
Some(member) => {
|
err_handler!("The current user isn't member of the organization");
|
||||||
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"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Outcome::Success(Self {
|
Outcome::Success(Self {
|
||||||
|
@ -590,13 +602,22 @@ impl<'r> FromRequest<'r> for OrgHeaders {
|
||||||
device: headers.device,
|
device: headers.device,
|
||||||
user,
|
user,
|
||||||
membership_type: {
|
membership_type: {
|
||||||
if let Some(org_usr_type) = MembershipType::from_i32(membership.atype) {
|
if let Some(member_type) = MembershipType::from_i32(membership.atype) {
|
||||||
org_usr_type
|
member_type
|
||||||
} else {
|
} else {
|
||||||
// This should only happen if the DB is corrupted
|
// This should only happen if the DB is corrupted
|
||||||
err_handler!("Unknown user type in the database")
|
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,
|
membership,
|
||||||
ip: headers.ip,
|
ip: headers.ip,
|
||||||
})
|
})
|
||||||
|
@ -621,7 +642,7 @@ impl<'r> FromRequest<'r> for AdminHeaders {
|
||||||
|
|
||||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
||||||
if headers.membership_type >= MembershipType::Admin {
|
if headers.is_confirmed_and_admin() {
|
||||||
Outcome::Success(Self {
|
Outcome::Success(Self {
|
||||||
host: headers.host,
|
host: headers.host,
|
||||||
device: headers.device,
|
device: headers.device,
|
||||||
|
@ -683,7 +704,7 @@ impl<'r> FromRequest<'r> for ManagerHeaders {
|
||||||
|
|
||||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
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) {
|
match get_col_id(request) {
|
||||||
Some(col_id) => {
|
Some(col_id) => {
|
||||||
let mut conn = match DbConn::from_request(request).await {
|
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> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
||||||
if headers.membership_type >= MembershipType::Manager {
|
if headers.is_confirmed_and_manager() {
|
||||||
Outcome::Success(Self {
|
Outcome::Success(Self {
|
||||||
host: headers.host,
|
host: headers.host,
|
||||||
device: headers.device,
|
device: headers.device,
|
||||||
|
@ -801,7 +822,7 @@ impl<'r> FromRequest<'r> for OwnerHeaders {
|
||||||
|
|
||||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
||||||
if headers.membership_type == MembershipType::Owner {
|
if headers.is_confirmed_and_owner() {
|
||||||
Outcome::Success(Self {
|
Outcome::Success(Self {
|
||||||
device: headers.device,
|
device: headers.device,
|
||||||
user: headers.user,
|
user: headers.user,
|
||||||
|
@ -826,7 +847,7 @@ impl<'r> FromRequest<'r> for OrgMemberHeaders {
|
||||||
|
|
||||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
let headers = try_outcome!(OrgHeaders::from_request(request).await);
|
||||||
if headers.membership_type >= MembershipType::User {
|
if headers.is_member() {
|
||||||
Outcome::Success(Self {
|
Outcome::Success(Self {
|
||||||
host: headers.host,
|
host: headers.host,
|
||||||
user: headers.user,
|
user: headers.user,
|
||||||
|
|
|
@ -55,6 +55,7 @@ db_object! {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/bitwarden/server/blob/b86a04cef9f1e1b82cf18e49fc94e017c641130c/src/Core/Enums/OrganizationUserStatusType.cs
|
// https://github.com/bitwarden/server/blob/b86a04cef9f1e1b82cf18e49fc94e017c641130c/src/Core/Enums/OrganizationUserStatusType.cs
|
||||||
|
#[derive(PartialEq)]
|
||||||
pub enum MembershipStatus {
|
pub enum MembershipStatus {
|
||||||
Revoked = -1,
|
Revoked = -1,
|
||||||
Invited = 0,
|
Invited = 0,
|
||||||
|
@ -62,6 +63,19 @@ pub enum MembershipStatus {
|
||||||
Confirmed = 2,
|
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)]
|
#[derive(Copy, Clone, PartialEq, Eq, num_derive::FromPrimitive)]
|
||||||
pub enum MembershipType {
|
pub enum MembershipType {
|
||||||
Owner = 0,
|
Owner = 0,
|
||||||
|
|
Laden …
Tabelle hinzufügen
In neuem Issue referenzieren