@ -73,6 +73,8 @@ impl UserOrgType { 
			
		
	
		
		
			
				
					             "1"   |   "Admin"   = >   Some ( UserOrgType ::Admin ) ,              "1"   |   "Admin"   = >   Some ( UserOrgType ::Admin ) ,  
			
		
	
		
		
			
				
					             "2"   |   "User"   = >   Some ( UserOrgType ::User ) ,              "2"   |   "User"   = >   Some ( UserOrgType ::User ) ,  
			
		
	
		
		
			
				
					             "3"   |   "Manager"   = >   Some ( UserOrgType ::Manager ) ,              "3"   |   "Manager"   = >   Some ( UserOrgType ::Manager ) ,  
			
		
	
		
		
			
				
					             // HACK: We convert the custom role to a manager role
  
			
		
	
		
		
			
				
					             "4"   |   "Custom"   = >   Some ( UserOrgType ::Manager ) ,  
			
		
	
		
		
			
				
					             _   = >   None ,              _   = >   None ,  
			
		
	
		
		
			
				
					         }          }  
			
		
	
		
		
			
				
					     }      }  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -85,7 +87,7 @@ impl Ord for UserOrgType { 
			
		
	
		
		
			
				
					             3 ,   // Owner
              3 ,   // Owner
  
			
		
	
		
		
			
				
					             2 ,   // Admin
              2 ,   // Admin
  
			
		
	
		
		
			
				
					             0 ,   // User
              0 ,   // User
  
			
		
	
		
		
			
				
					
					             1 ,   // Manager
              1 ,   // Manager && Custom 
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					         ] ;          ] ;  
			
		
	
		
		
			
				
					         ACCESS_LEVEL [ * self   as   usize ] . cmp ( & ACCESS_LEVEL [ * other   as   usize ] )          ACCESS_LEVEL [ * self   as   usize ] . cmp ( & ACCESS_LEVEL [ * other   as   usize ] )  
			
		
	
		
		
			
				
					     }      }  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -158,33 +160,46 @@ impl Organization { 
			
		
	
		
		
			
				
					     pub   fn  to_json ( & self )   -> Value   {      pub   fn  to_json ( & self )   -> Value   {  
			
		
	
		
		
			
				
					         json ! ( {          json ! ( {  
			
		
	
		
		
			
				
					             "id" : self . uuid ,              "id" : self . uuid ,  
			
		
	
		
		
			
				
					             "identifier" : null ,   // not supported by us
  
			
		
	
		
		
			
				
					             "name" : self . name ,              "name" : self . name ,  
			
		
	
		
		
			
				
					             "seats" : null ,              "seats" : null ,  
			
		
	
		
		
			
				
					             "maxCollections" : null ,              "maxCollections" : null ,  
			
		
	
		
		
			
				
					             "maxStorageGb" : i16 ::MAX ,   // The value doesn't matter, we don't check server-side
              "maxStorageGb" : i16 ::MAX ,   // The value doesn't matter, we don't check server-side
  
			
		
	
		
		
			
				
					             "use2fa" : true ,              "use2fa" : true ,  
			
		
	
		
		
			
				
					
					             "useCustomPermissions" : fals e,              "useCustomPermissions" : tru e,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "useDirectory" : false ,   // Is supported, but this value isn't checked anywhere (yet)
              "useDirectory" : false ,   // Is supported, but this value isn't checked anywhere (yet)
  
			
		
	
		
		
			
				
					             "useEvents" : CONFIG . org_events_enabled ( ) ,              "useEvents" : CONFIG . org_events_enabled ( ) ,  
			
		
	
		
		
			
				
					             "useGroups" : CONFIG . org_groups_enabled ( ) ,              "useGroups" : CONFIG . org_groups_enabled ( ) ,  
			
		
	
		
		
			
				
					             "useTotp" : true ,              "useTotp" : true ,  
			
		
	
		
		
			
				
					             "usePolicies" : true ,              "usePolicies" : true ,  
			
		
	
		
		
			
				
					
					             // "useScim": false,  // Not supported (Not AGPLv3 Licensed)
             "useScim" : false ,    
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "useSso" : false ,   // Not supported
              "useSso" : false ,   // Not supported
  
			
		
	
		
		
			
				
					
					             // "useKeyConnector": false, // Not supported
              "useKeyConnector" : false ,   // Not supported
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "usePasswordManager" : true ,  
			
		
	
		
		
			
				
					             "useSecretsManager" : false ,   // Not supported (Not AGPLv3 Licensed)
  
			
		
	
		
		
			
				
					             "selfHost" : true ,              "selfHost" : true ,  
			
		
	
		
		
			
				
					             "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" : true ,  
			
		
	
		
		
			
				
					             "limitCollectionCreation" : true ,  
			
		
	
		
		
			
				
					             "limitCollectionCreationDeletion" : true ,  
			
		
	
		
		
			
				
					             "limitCollectionDeletion" : true ,  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					             "businessName" : null ,              "businessName" : self . name ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "businessAddress1" : null ,              "businessAddress1" : null ,  
			
		
	
		
		
			
				
					             "businessAddress2" : null ,              "businessAddress2" : null ,  
			
		
	
		
		
			
				
					             "businessAddress3" : null ,              "businessAddress3" : null ,  
			
		
	
		
		
			
				
					             "businessCountry" : null ,              "businessCountry" : null ,  
			
		
	
		
		
			
				
					             "businessTaxNumber" : null ,              "businessTaxNumber" : null ,  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					             "maxAutoscaleSeats" : null ,  
			
		
	
		
		
			
				
					             "maxAutoscaleSmSeats" : null ,  
			
		
	
		
		
			
				
					             "maxAutoscaleSmServiceAccounts" : null ,  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					             "secretsManagerPlan" : null ,  
			
		
	
		
		
			
				
					             "smSeats" : null ,  
			
		
	
		
		
			
				
					             "smServiceAccounts" : null ,  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					             "billingEmail" : self . billing_email ,              "billingEmail" : self . billing_email ,  
			
		
	
		
		
			
				
					             "planType" : 6 ,   // Custom plan
              "planType" : 6 ,   // Custom plan
  
			
		
	
		
		
			
				
					             "usersGetPremium" : true ,              "usersGetPremium" : true ,  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -252,6 +267,15 @@ impl UserOrganization { 
			
		
	
		
		
			
				
					         }          }  
			
		
	
		
		
			
				
					         false          false  
			
		
	
		
		
			
				
					     }      }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					     /// HACK: Convert the manager type to a custom type
  
			
		
	
		
		
			
				
					     /// It will be converted back on other locations
  
			
		
	
		
		
			
				
					     pub   fn  type_manager_as_custom ( & self )   -> i32  {  
			
		
	
		
		
			
				
					         match   self . atype   {  
			
		
	
		
		
			
				
					             3   = >   4 ,  
			
		
	
		
		
			
				
					             _   = >   self . atype ,  
			
		
	
		
		
			
				
					         }  
			
		
	
		
		
			
				
					     }  
			
		
	
		
		
			
				
					} }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					impl   OrganizationApiKey   { impl   OrganizationApiKey   {  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -356,17 +380,21 @@ impl UserOrganization { 
			
		
	
		
		
			
				
					     pub   async   fn  to_json ( & self ,   conn : & mut   DbConn )   -> Value   {      pub   async   fn  to_json ( & self ,   conn : & mut   DbConn )   -> Value   {  
			
		
	
		
		
			
				
					         let   org   =   Organization ::find_by_uuid ( & self . org_uuid ,   conn ) . await . unwrap ( ) ;          let   org   =   Organization ::find_by_uuid ( & self . org_uuid ,   conn ) . await . unwrap ( ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					         // HACK: Convert the manager type to a custom type
  
			
		
	
		
		
			
				
					         // It will be converted back on other locations
  
			
		
	
		
		
			
				
					         let   user_org_type   =   self . type_manager_as_custom ( ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					         let   permissions   =   json ! ( {          let   permissions   =   json ! ( {  
			
		
	
		
		
			
				
					
					                 // TODO: Add support for Custom User Roles
                  // TODO: Add full  support for Custom User Roles
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                 // See: https://bitwarden.com/help/article/user-types-access-control/#custom-role
                  // See: https://bitwarden.com/help/article/user-types-access-control/#custom-role
  
			
		
	
		
		
			
				
					                 // Currently we use the custom role as a manager role and link the 3 Collection roles to mimic the access_all permission
  
			
		
	
		
		
			
				
					                 "accessEventLogs" : false ,                  "accessEventLogs" : false ,  
			
		
	
		
		
			
				
					                 "accessImportExport" : false ,                  "accessImportExport" : false ,  
			
		
	
		
		
			
				
					                 "accessReports" : false ,                  "accessReports" : false ,  
			
		
	
		
		
			
				
					
					                 "createNewCollections" : false ,                  // If the following 3 Collection roles are set to true a custom user has access all permission
  
			
				
				
			
		
	
		
		
			
				
					
					                 "editAnyCollection" : false ,                  "createNewCollections" : user_org_type   = =   4   & &   self . access_all ,  
			
				
				
			
		
	
		
		
			
				
					
					                 "deleteAnyCollection" : false ,                  "editAnyCollection" : user_org_type   = =   4   & &   self . access_all ,  
			
				
				
			
		
	
		
		
			
				
					
					                 "editAssignedCollections" : false ,                  "deleteAnyCollection" : user_org_type   = =   4   & &   self . access_all ,  
			
				
				
			
		
	
		
		
			
				
					                 "deleteAssignedCollections" : false ,  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                 "manageGroups" : false ,                  "manageGroups" : false ,  
			
		
	
		
		
			
				
					                 "managePolicies" : false ,                  "managePolicies" : false ,  
			
		
	
		
		
			
				
					                 "manageSso" : false ,   // Not supported
                  "manageSso" : false ,   // Not supported
  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -398,9 +426,9 @@ impl UserOrganization { 
			
		
	
		
		
			
				
					             "ssoBound" : false ,   // Not supported
              "ssoBound" : false ,   // Not supported
  
			
		
	
		
		
			
				
					             "useSso" : false ,   // Not supported
              "useSso" : false ,   // Not supported
  
			
		
	
		
		
			
				
					             "useKeyConnector" : false ,              "useKeyConnector" : false ,  
			
		
	
		
		
			
				
					
					             "useSecretsManager" : false ,              "useSecretsManager" : false ,   // Not supported (Not AGPLv3 Licensed)
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "usePasswordManager" : true ,              "usePasswordManager" : true ,  
			
		
	
		
		
			
				
					
					             "useCustomPermissions" : fals e,              "useCustomPermissions" : tru e,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "useActivateAutofillPolicy" : false ,              "useActivateAutofillPolicy" : false ,  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					             "organizationUserId" : self . uuid ,              "organizationUserId" : self . uuid ,  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -417,9 +445,11 @@ impl UserOrganization { 
			
		
	
		
		
			
				
					             "familySponsorshipValidUntil" : null ,              "familySponsorshipValidUntil" : null ,  
			
		
	
		
		
			
				
					             "familySponsorshipToDelete" : null ,              "familySponsorshipToDelete" : null ,  
			
		
	
		
		
			
				
					             "accessSecretsManager" : false ,              "accessSecretsManager" : false ,  
			
		
	
		
		
			
				
					
					             "limitCollectionCreationDeletion" : false ,   // This should be set to true only when we can handle roles like createNewCollections
              "limitCollectionCreation" : true ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "limitCollectionCreationDeletion" : true ,  
			
		
	
		
		
			
				
					             "limitCollectionDeletion" : true ,  
			
		
	
		
		
			
				
					             "allowAdminAccessToAllCollectionItems" : true ,              "allowAdminAccessToAllCollectionItems" : true ,  
			
		
	
		
		
			
				
					
					             "flexibleCollections" : false ,              "userIsManagedByOrganization " : false ,   // Means not managed via the Members UI, like SSO
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					             "permissions" : permissions ,              "permissions" : permissions ,  
			
		
	
		
		
			
				
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -429,7 +459,7 @@ impl UserOrganization { 
			
		
	
		
		
			
				
					             "userId" : self . user_uuid ,              "userId" : self . user_uuid ,  
			
		
	
		
		
			
				
					             "key" : self . akey ,              "key" : self . akey ,  
			
		
	
		
		
			
				
					             "status" : self . status ,              "status" : self . status ,  
			
		
	
		
		
			
				
					
					             "type" : self . a type,              "type" : user_org_ type,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "enabled" : true ,              "enabled" : true ,  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					             "object" : "profileOrganization" ,              "object" : "profileOrganization" ,  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -516,24 +546,34 @@ impl UserOrganization { 
			
		
	
		
		
			
				
					             Vec ::with_capacity ( 0 )              Vec ::with_capacity ( 0 )  
			
		
	
		
		
			
				
					         } ;          } ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					         let   permissions   =   json ! ( {          // HACK: Convert the manager type to a custom type
  
			
				
				
			
		
	
		
		
			
				
					
					             // TODO: Add support for Custom User Roles
          // It will be converted back on other locations
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					         let   user_org_type   =   self . type_manager_as_custom ( ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					         // HACK: Only return permissions if the user is of type custom and has access_all
  
			
		
	
		
		
			
				
					         // Else Bitwarden will assume the defaults of all false
  
			
		
	
		
		
			
				
					         let   permissions   =   if   user_org_type   = =   4   & &   self . access_all   {  
			
		
	
		
		
			
				
					             json ! ( {  
			
		
	
		
		
			
				
					                 // TODO: Add full support for Custom User Roles
  
			
		
	
		
		
			
				
					                 // See: https://bitwarden.com/help/article/user-types-access-control/#custom-role
                  // See: https://bitwarden.com/help/article/user-types-access-control/#custom-role
  
			
		
	
		
		
			
				
					                 // Currently we use the custom role as a manager role and link the 3 Collection roles to mimic the access_all permission
  
			
		
	
		
		
			
				
					                 "accessEventLogs" : false ,                  "accessEventLogs" : false ,  
			
		
	
		
		
			
				
					                 "accessImportExport" : false ,                  "accessImportExport" : false ,  
			
		
	
		
		
			
				
					                 "accessReports" : false ,                  "accessReports" : false ,  
			
		
	
		
		
			
				
					
					             "createNewCollections" : false ,                  // If the following 3 Collection roles are set to true a custom user has access all permission
  
			
				
				
			
		
	
		
		
			
				
					
					             "editAnyCollection" : false ,                  "createNewCollections" : true ,  
			
				
				
			
		
	
		
		
			
				
					
					             "deleteAnyCollection" : false ,                  "editAnyCollection" : true ,  
			
				
				
			
		
	
		
		
			
				
					
					             "editAssignedCollections" : false ,                  "deleteAnyCollection" : true ,  
			
				
				
			
		
	
		
		
			
				
					             "deleteAssignedCollections" : false ,  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                 "manageGroups" : false ,                  "manageGroups" : false ,  
			
		
	
		
		
			
				
					                 "managePolicies" : false ,                  "managePolicies" : false ,  
			
		
	
		
		
			
				
					                 "manageSso" : false ,   // Not supported
                  "manageSso" : false ,   // Not supported
  
			
		
	
		
		
			
				
					                 "manageUsers" : false ,                  "manageUsers" : false ,  
			
		
	
		
		
			
				
					                 "manageResetPassword" : false ,                  "manageResetPassword" : false ,  
			
		
	
		
		
			
				
					                 "manageScim" : false   // Not supported (Not AGPLv3 Licensed)
                  "manageScim" : false   // Not supported (Not AGPLv3 Licensed)
  
			
		
	
		
		
			
				
					
					         } ) ;              } )  
			
				
				
			
		
	
		
		
	
		
		
			
				
					         }   else   {  
			
		
	
		
		
			
				
					             json ! ( null )  
			
		
	
		
		
			
				
					         } ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					         json ! ( {          json ! ( {  
			
		
	
		
		
			
				
					             "id" : self . uuid ,              "id" : self . uuid ,  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -546,7 +586,7 @@ impl UserOrganization { 
			
		
	
		
		
			
				
					             "collections" : collections ,              "collections" : collections ,  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					             "status" : status ,              "status" : status ,  
			
		
	
		
		
			
				
					
					             "type" : self . a type,              "type" : user_org_ type,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					             "accessAll" : self . access_all ,              "accessAll" : self . access_all ,  
			
		
	
		
		
			
				
					             "twoFactorEnabled" : twofactor_enabled ,              "twoFactorEnabled" : twofactor_enabled ,  
			
		
	
		
		
			
				
					             "resetPasswordEnrolled" : self . reset_password_key . is_some ( ) ,              "resetPasswordEnrolled" : self . reset_password_key . is_some ( ) ,  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -608,6 +648,29 @@ impl UserOrganization { 
			
		
	
		
		
			
				
					             "object" : "organizationUserDetails" ,              "object" : "organizationUserDetails" ,  
			
		
	
		
		
			
				
					         } )          } )  
			
		
	
		
		
			
				
					     }      }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					     pub   async   fn  to_json_mini_details ( & self ,   conn : & mut   DbConn )   -> Value   {  
			
		
	
		
		
			
				
					         let   user   =   User ::find_by_uuid ( & self . user_uuid ,   conn ) . await . unwrap ( ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					         // Because Bitwarden wants the status to be -1 for revoked users we need to catch that here.
  
			
		
	
		
		
			
				
					         // We subtract/add a number so we can restore/activate the user to it's previous state again.
  
			
		
	
		
		
			
				
					         let   status   =   if   self . status   <   UserOrgStatus ::Revoked   as   i32   {  
			
		
	
		
		
			
				
					             UserOrgStatus ::Revoked   as   i32  
			
		
	
		
		
			
				
					         }   else   {  
			
		
	
		
		
			
				
					             self . status  
			
		
	
		
		
			
				
					         } ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					         json ! ( {  
			
		
	
		
		
			
				
					             "id" : self . uuid ,  
			
		
	
		
		
			
				
					             "userId" : self . user_uuid ,  
			
		
	
		
		
			
				
					             "type" : self . type_manager_as_custom ( ) ,   // HACK: Convert the manager type to a custom type
  
			
		
	
		
		
			
				
					             "status" : status ,  
			
		
	
		
		
			
				
					             "name" : user . name ,  
			
		
	
		
		
			
				
					             "email" : user . email ,  
			
		
	
		
		
			
				
					             "object" : "organizationUserUserMiniDetails" ,  
			
		
	
		
		
			
				
					         } )  
			
		
	
		
		
			
				
					     }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					     pub   async   fn  save ( & self ,   conn : & mut   DbConn )   -> EmptyResult   {      pub   async   fn  save ( & self ,   conn : & mut   DbConn )   -> EmptyResult   {  
			
		
	
		
		
			
				
					         User ::update_uuid_revision ( & self . user_uuid ,   conn ) . await ;          User ::update_uuid_revision ( & self . user_uuid ,   conn ) . await ;  
			
		
	
		
		
			
				
					
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -1015,5 +1078,6 @@ mod tests { 
			
		
	
		
		
			
				
					         assert ! ( UserOrgType ::Owner   >   UserOrgType ::Admin ) ;          assert ! ( UserOrgType ::Owner   >   UserOrgType ::Admin ) ;  
			
		
	
		
		
			
				
					         assert ! ( UserOrgType ::Admin   >   UserOrgType ::Manager ) ;          assert ! ( UserOrgType ::Admin   >   UserOrgType ::Manager ) ;  
			
		
	
		
		
			
				
					         assert ! ( UserOrgType ::Manager   >   UserOrgType ::User ) ;          assert ! ( UserOrgType ::Manager   >   UserOrgType ::User ) ;  
			
		
	
		
		
			
				
					         assert ! ( UserOrgType ::Manager   = =   UserOrgType ::from_str ( "4" ) . unwrap ( ) ) ;  
			
		
	
		
		
			
				
					     }      }  
			
		
	
		
		
			
				
					} }