|
|
@ -5,15 +5,9 @@ use std::{ |
|
|
|
|
|
|
|
|
use chrono::{NaiveDateTime, Utc}; |
|
|
use chrono::{NaiveDateTime, Utc}; |
|
|
use derive_more::{AsRef, Deref, Display, From}; |
|
|
use derive_more::{AsRef, Deref, Display, From}; |
|
|
use diesel::{ |
|
|
use diesel::{deserialize::FromSql, prelude::*, serialize::ToSql, sql_types::SmallInt}; |
|
|
deserialize::FromSql, |
|
|
|
|
|
prelude::*, |
|
|
|
|
|
serialize::{IsNull, ToSql}, |
|
|
|
|
|
sql_types::SmallInt, |
|
|
|
|
|
}; |
|
|
|
|
|
use num_traits::FromPrimitive; |
|
|
use num_traits::FromPrimitive; |
|
|
#[cfg(feature = "sqlite")] |
|
|
#[cfg(feature = "sqlite")] |
|
|
use num_traits::ToPrimitive; |
|
|
|
|
|
use serde_json::Value; |
|
|
use serde_json::Value; |
|
|
|
|
|
|
|
|
use crate::{ |
|
|
use crate::{ |
|
|
@ -35,59 +29,39 @@ use super::{ |
|
|
OrgPolicyType, TwoFactor, User, UserId, |
|
|
OrgPolicyType, TwoFactor, User, UserId, |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#[repr(i16)] |
|
|
|
|
|
pub enum OrgCollectionSetting { |
|
|
|
|
|
AllowAdminAccessToAllCollectionItems = 0b1, |
|
|
|
|
|
LimitCollectionCreation = 0b10, |
|
|
|
|
|
LimitCollectionDeletion = 0b100, |
|
|
|
|
|
LimitItemDeletion = 0b1000, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, FromSqlRow, AsExpression)] |
|
|
#[derive(Debug, Clone, Copy, FromSqlRow, AsExpression)] |
|
|
#[diesel(sql_type = SmallInt)] |
|
|
#[diesel(sql_type = SmallInt)] |
|
|
#[allow(clippy::struct_excessive_bools)] |
|
|
pub struct OrganizationCollectionSettings(i16); |
|
|
pub struct OrganizationCollectionSettings { |
|
|
|
|
|
pub allow_admin_access_to_all_collection_items: bool, |
|
|
|
|
|
pub limit_collection_creation: bool, |
|
|
|
|
|
pub limit_collection_deletion: bool, |
|
|
|
|
|
pub limit_item_deletion: bool, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl From<&OrganizationCollectionSettings> for i16 { |
|
|
impl OrganizationCollectionSettings { |
|
|
fn from(value: &OrganizationCollectionSettings) -> Self { |
|
|
pub fn get_flag(self, flag: OrgCollectionSetting) -> bool { |
|
|
i16::from(value.allow_admin_access_to_all_collection_items) |
|
|
(self.0 | flag as i16) > 0 |
|
|
| (0b10 * i16::from(value.limit_collection_creation)) |
|
|
|
|
|
| (0b100 * i16::from(value.limit_collection_deletion)) |
|
|
|
|
|
| (0b1000 * i16::from(value.limit_item_deletion)) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "sqlite")] |
|
|
pub fn set_flag(&mut self, flag: OrgCollectionSetting, val: bool) { |
|
|
use diesel::sqlite::Sqlite; |
|
|
if val { |
|
|
#[cfg(feature = "sqlite")] |
|
|
self.0 |= flag as i16; |
|
|
impl ToSql<SmallInt, Sqlite> for OrganizationCollectionSettings |
|
|
} else { |
|
|
where |
|
|
self.0 &= i16::MAX - flag as i16; |
|
|
i16: ToSql<SmallInt, Sqlite>, |
|
|
|
|
|
{ |
|
|
|
|
|
fn to_sql<'b>(&'b self, out: &mut diesel::serialize::Output<'b, '_, Sqlite>) -> diesel::serialize::Result { |
|
|
|
|
|
out.set_value(i16::from(self).to_i32()); |
|
|
|
|
|
Ok(IsNull::No) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "postgresql")] |
|
|
|
|
|
use diesel::pg::Pg; |
|
|
|
|
|
#[cfg(feature = "postgresql")] |
|
|
|
|
|
impl ToSql<SmallInt, Pg> for OrganizationCollectionSettings |
|
|
|
|
|
where |
|
|
|
|
|
i16: ToSql<SmallInt, Pg>, |
|
|
|
|
|
{ |
|
|
|
|
|
fn to_sql<'b>(&'b self, out: &mut diesel::serialize::Output<'b, '_, Pg>) -> diesel::serialize::Result { |
|
|
|
|
|
<i16 as ToSql<SmallInt, Pg>>::to_sql(&i16::from(self), &mut out.reborrow()) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#[cfg(feature = "mysql")] |
|
|
impl<DB> ToSql<SmallInt, DB> for OrganizationCollectionSettings |
|
|
use diesel::mysql::Mysql; |
|
|
|
|
|
#[cfg(feature = "mysql")] |
|
|
|
|
|
impl ToSql<SmallInt, Mysql> for OrganizationCollectionSettings |
|
|
|
|
|
where |
|
|
where |
|
|
i16: ToSql<SmallInt, Mysql>, |
|
|
DB: diesel::backend::Backend, |
|
|
|
|
|
i16: ToSql<SmallInt, DB>, |
|
|
{ |
|
|
{ |
|
|
fn to_sql<'b>(&'b self, out: &mut diesel::serialize::Output<'b, '_, Mysql>) -> diesel::serialize::Result { |
|
|
fn to_sql<'b>(&'b self, out: &mut diesel::serialize::Output<'b, '_, DB>) -> diesel::serialize::Result { |
|
|
<i16 as ToSql<SmallInt, Mysql>>::to_sql(&i16::from(self), &mut out.reborrow()) |
|
|
self.0.to_sql(out) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -98,12 +72,7 @@ where |
|
|
{ |
|
|
{ |
|
|
fn from_sql(bytes: DB::RawValue<'_>) -> diesel::deserialize::Result<Self> { |
|
|
fn from_sql(bytes: DB::RawValue<'_>) -> diesel::deserialize::Result<Self> { |
|
|
let val = i16::from_sql(bytes)?; |
|
|
let val = i16::from_sql(bytes)?; |
|
|
Ok(Self { |
|
|
Ok(Self(val)) |
|
|
allow_admin_access_to_all_collection_items: (val & 0b1) != 0, |
|
|
|
|
|
limit_collection_creation: (val & 0b10) != 0, |
|
|
|
|
|
limit_collection_deletion: (val & 0b100) != 0, |
|
|
|
|
|
limit_item_deletion: (val & 0b1000) != 0, |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -274,12 +243,11 @@ impl Organization { |
|
|
billing_email, |
|
|
billing_email, |
|
|
private_key, |
|
|
private_key, |
|
|
public_key, |
|
|
public_key, |
|
|
collection_settings: OrganizationCollectionSettings { |
|
|
|
|
|
allow_admin_access_to_all_collection_items: true, |
|
|
// Collection Management Settings default to AllowAdminAccessToAllCollectionItems
|
|
|
limit_collection_creation: false, |
|
|
collection_settings: OrganizationCollectionSettings( |
|
|
limit_collection_deletion: false, |
|
|
OrgCollectionSetting::AllowAdminAccessToAllCollectionItems as i16, |
|
|
limit_item_deletion: false, |
|
|
), |
|
|
}, |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
// https://github.com/bitwarden/server/blob/9ebe16587175b1c0e9208f84397bb75d0d595510/src/Api/AdminConsole/Models/Response/Organizations/OrganizationResponseModel.cs
|
|
|
// https://github.com/bitwarden/server/blob/9ebe16587175b1c0e9208f84397bb75d0d595510/src/Api/AdminConsole/Models/Response/Organizations/OrganizationResponseModel.cs
|
|
|
@ -306,10 +274,10 @@ impl Organization { |
|
|
"useApi": true, |
|
|
"useApi": true, |
|
|
"hasPublicAndPrivateKeys": self.private_key.is_some() && self.public_key.is_some(), |
|
|
"hasPublicAndPrivateKeys": self.private_key.is_some() && self.public_key.is_some(), |
|
|
"useResetPassword": CONFIG.mail_enabled(), |
|
|
"useResetPassword": CONFIG.mail_enabled(), |
|
|
"allowAdminAccessToAllCollectionItems": self.collection_settings.allow_admin_access_to_all_collection_items, |
|
|
"allowAdminAccessToAllCollectionItems": self.collection_settings.get_flag(OrgCollectionSetting::AllowAdminAccessToAllCollectionItems), |
|
|
"limitCollectionCreation": self.collection_settings.limit_collection_creation, |
|
|
"limitCollectionCreation": self.collection_settings.get_flag(OrgCollectionSetting::LimitCollectionCreation), |
|
|
"limitCollectionDeletion": self.collection_settings.limit_collection_deletion, |
|
|
"limitCollectionDeletion": self.collection_settings.get_flag(OrgCollectionSetting::LimitCollectionDeletion), |
|
|
"limitItemDeletion": self.collection_settings.limit_item_deletion, |
|
|
"limitItemDeletion": self.collection_settings.get_flag(OrgCollectionSetting::LimitItemDeletion), |
|
|
|
|
|
|
|
|
"businessName": self.name, |
|
|
"businessName": self.name, |
|
|
"businessAddress1": null, |
|
|
"businessAddress1": null, |
|
|
@ -557,9 +525,9 @@ impl Membership { |
|
|
"accessImportExport": false, |
|
|
"accessImportExport": false, |
|
|
"accessReports": false, |
|
|
"accessReports": false, |
|
|
// If the following 3 Collection roles are set to true a custom user has access all permission
|
|
|
// If the following 3 Collection roles are set to true a custom user has access all permission
|
|
|
"createNewCollections": membership_type == 4 && self.access_all && !org.collection_settings.limit_collection_creation, |
|
|
"createNewCollections": membership_type == 4 && self.access_all && !org.collection_settings.get_flag(OrgCollectionSetting::LimitCollectionCreation), |
|
|
"editAnyCollection": membership_type == 4 && self.access_all, |
|
|
"editAnyCollection": membership_type == 4 && self.access_all, |
|
|
"deleteAnyCollection": membership_type == 4 && self.access_all && !org.collection_settings.limit_collection_deletion, |
|
|
"deleteAnyCollection": membership_type == 4 && self.access_all && !org.collection_settings.get_flag(OrgCollectionSetting::LimitCollectionCreation), |
|
|
"manageGroups": false, |
|
|
"manageGroups": false, |
|
|
"managePolicies": false, |
|
|
"managePolicies": false, |
|
|
"manageSso": false, // Not supported
|
|
|
"manageSso": false, // Not supported
|
|
|
@ -612,10 +580,10 @@ impl Membership { |
|
|
"familySponsorshipToDelete": null, |
|
|
"familySponsorshipToDelete": null, |
|
|
"accessSecretsManager": false, |
|
|
"accessSecretsManager": false, |
|
|
|
|
|
|
|
|
"allowAdminAccessToAllCollectionItems": org.collection_settings.allow_admin_access_to_all_collection_items, |
|
|
"allowAdminAccessToAllCollectionItems": org.collection_settings.get_flag(OrgCollectionSetting::AllowAdminAccessToAllCollectionItems), |
|
|
"limitCollectionCreation": org.collection_settings.limit_collection_creation, |
|
|
"limitCollectionCreation": org.collection_settings.get_flag(OrgCollectionSetting::LimitCollectionCreation), |
|
|
"limitCollectionDeletion": org.collection_settings.limit_collection_deletion, |
|
|
"limitCollectionDeletion": org.collection_settings.get_flag(OrgCollectionSetting::LimitCollectionDeletion), |
|
|
"limitItemDeletion": org.collection_settings.limit_item_deletion, |
|
|
"limitItemDeletion": org.collection_settings.get_flag(OrgCollectionSetting::LimitItemDeletion), |
|
|
|
|
|
|
|
|
"userIsManagedByOrganization": false, // Means not managed via the Members UI, like SSO
|
|
|
"userIsManagedByOrganization": false, // Means not managed via the Members UI, like SSO
|
|
|
"userIsClaimedByOrganization": false, // The new key instead of the obsolete userIsManagedByOrganization
|
|
|
"userIsClaimedByOrganization": false, // The new key instead of the obsolete userIsManagedByOrganization
|
|
|
|