@ -5,11 +5,11 @@ use serde_json::Value;
use crate ::{
use crate ::{
api ::{
api ::{
core ::{ CipherSyncData, CipherSyncType } ,
core ::{ log_event, CipherSyncData, CipherSyncType } ,
ApiResult , EmptyResult , JsonResult , JsonUpcase , JsonUpcaseVec , JsonVec , Notify , NumberOrString , PasswordData ,
ApiResult , EmptyResult , JsonResult , JsonUpcase , JsonUpcaseVec , JsonVec , Notify , NumberOrString , PasswordData ,
UpdateType ,
UpdateType ,
} ,
} ,
auth ::{ decode_invite , AdminHeaders , Headers, ManagerHeaders , ManagerHeadersLoose , OwnerHeaders } ,
auth ::{ decode_invite , AdminHeaders , ClientIp, Headers, ManagerHeaders , ManagerHeadersLoose , OwnerHeaders } ,
db ::{ models ::* , DbConn } ,
db ::{ models ::* , DbConn } ,
error ::Error ,
error ::Error ,
mail ,
mail ,
@ -203,7 +203,7 @@ async fn post_delete_organization(
}
}
#[ post( " /organizations/<org_id>/leave " ) ]
#[ post( " /organizations/<org_id>/leave " ) ]
async fn leave_organization ( org_id : String , headers : Headers , mut conn : DbConn ) -> EmptyResult {
async fn leave_organization ( org_id : String , headers : Headers , mut conn : DbConn , ip : ClientIp ) -> EmptyResult {
match UserOrganization ::find_by_user_and_org ( & headers . user . uuid , & org_id , & mut conn ) . await {
match UserOrganization ::find_by_user_and_org ( & headers . user . uuid , & org_id , & mut conn ) . await {
None = > err ! ( "User not part of organization" ) ,
None = > err ! ( "User not part of organization" ) ,
Some ( user_org ) = > {
Some ( user_org ) = > {
@ -213,6 +213,17 @@ async fn leave_organization(org_id: String, headers: Headers, mut conn: DbConn)
err ! ( "The last owner can't leave" )
err ! ( "The last owner can't leave" )
}
}
log_event (
EventType ::OrganizationUserRemoved as i32 ,
& user_org . uuid ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
user_org . delete ( & mut conn ) . await
user_org . delete ( & mut conn ) . await
}
}
}
}
@ -232,16 +243,18 @@ async fn put_organization(
headers : OwnerHeaders ,
headers : OwnerHeaders ,
data : JsonUpcase < OrganizationUpdateData > ,
data : JsonUpcase < OrganizationUpdateData > ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
post_organization ( org_id , headers , data , conn ). await
post_organization ( org_id , headers , data , conn , ip ). await
}
}
#[ post( " /organizations/<org_id> " , data = " <data> " ) ]
#[ post( " /organizations/<org_id> " , data = " <data> " ) ]
async fn post_organization (
async fn post_organization (
org_id : String ,
org_id : String ,
_ headers: OwnerHeaders ,
headers: OwnerHeaders ,
data : JsonUpcase < OrganizationUpdateData > ,
data : JsonUpcase < OrganizationUpdateData > ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
let data : OrganizationUpdateData = data . into_inner ( ) . data ;
let data : OrganizationUpdateData = data . into_inner ( ) . data ;
@ -254,6 +267,18 @@ async fn post_organization(
org . billing_email = data . BillingEmail ;
org . billing_email = data . BillingEmail ;
org . save ( & mut conn ) . await ? ;
org . save ( & mut conn ) . await ? ;
log_event (
EventType ::OrganizationUpdated as i32 ,
& org_id ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
Ok ( Json ( org . to_json ( ) ) )
Ok ( Json ( org . to_json ( ) ) )
}
}
@ -290,6 +315,7 @@ async fn post_organization_collections(
headers : ManagerHeadersLoose ,
headers : ManagerHeadersLoose ,
data : JsonUpcase < NewCollectionData > ,
data : JsonUpcase < NewCollectionData > ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
let data : NewCollectionData = data . into_inner ( ) . data ;
let data : NewCollectionData = data . into_inner ( ) . data ;
@ -307,6 +333,17 @@ async fn post_organization_collections(
let collection = Collection ::new ( org . uuid , data . Name ) ;
let collection = Collection ::new ( org . uuid , data . Name ) ;
collection . save ( & mut conn ) . await ? ;
collection . save ( & mut conn ) . await ? ;
log_event (
EventType ::CollectionCreated as i32 ,
& collection . uuid ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
for group in data . Groups {
for group in data . Groups {
CollectionGroup ::new ( collection . uuid . clone ( ) , group . Id , group . ReadOnly , group . HidePasswords )
CollectionGroup ::new ( collection . uuid . clone ( ) , group . Id , group . ReadOnly , group . HidePasswords )
. save ( & mut conn )
. save ( & mut conn )
@ -330,17 +367,19 @@ async fn put_organization_collection_update(
headers : ManagerHeaders ,
headers : ManagerHeaders ,
data : JsonUpcase < NewCollectionData > ,
data : JsonUpcase < NewCollectionData > ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
post_organization_collection_update ( org_id , col_id , headers , data , conn ). await
post_organization_collection_update ( org_id , col_id , headers , data , conn , ip ). await
}
}
#[ post( " /organizations/<org_id>/collections/<col_id> " , data = " <data> " ) ]
#[ post( " /organizations/<org_id>/collections/<col_id> " , data = " <data> " ) ]
async fn post_organization_collection_update (
async fn post_organization_collection_update (
org_id : String ,
org_id : String ,
col_id : String ,
col_id : String ,
_ headers: ManagerHeaders ,
headers: ManagerHeaders ,
data : JsonUpcase < NewCollectionData > ,
data : JsonUpcase < NewCollectionData > ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
let data : NewCollectionData = data . into_inner ( ) . data ;
let data : NewCollectionData = data . into_inner ( ) . data ;
@ -361,6 +400,17 @@ async fn post_organization_collection_update(
collection . name = data . Name ;
collection . name = data . Name ;
collection . save ( & mut conn ) . await ? ;
collection . save ( & mut conn ) . await ? ;
log_event (
EventType ::CollectionUpdated as i32 ,
& collection . uuid ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
CollectionGroup ::delete_all_by_collection ( & col_id , & mut conn ) . await ? ;
CollectionGroup ::delete_all_by_collection ( & col_id , & mut conn ) . await ? ;
for group in data . Groups {
for group in data . Groups {
@ -415,13 +465,24 @@ async fn post_organization_collection_delete_user(
async fn delete_organization_collection (
async fn delete_organization_collection (
org_id : String ,
org_id : String ,
col_id : String ,
col_id : String ,
_ headers: ManagerHeaders ,
headers: ManagerHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
match Collection ::find_by_uuid ( & col_id , & mut conn ) . await {
match Collection ::find_by_uuid ( & col_id , & mut conn ) . await {
None = > err ! ( "Collection not found" ) ,
None = > err ! ( "Collection not found" ) ,
Some ( collection ) = > {
Some ( collection ) = > {
if collection . org_uuid = = org_id {
if collection . org_uuid = = org_id {
log_event (
EventType ::CollectionDeleted as i32 ,
& collection . uuid ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
collection . delete ( & mut conn ) . await
collection . delete ( & mut conn ) . await
} else {
} else {
err ! ( "Collection and Organization id do not match" )
err ! ( "Collection and Organization id do not match" )
@ -444,8 +505,9 @@ async fn post_organization_collection_delete(
headers : ManagerHeaders ,
headers : ManagerHeaders ,
_data : JsonUpcase < DeleteCollectionData > ,
_data : JsonUpcase < DeleteCollectionData > ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
delete_organization_collection ( org_id , col_id , headers , conn ). await
delete_organization_collection ( org_id , col_id , headers , conn , ip ). await
}
}
#[ get( " /organizations/<org_id>/collections/<coll_id>/details " ) ]
#[ get( " /organizations/<org_id>/collections/<coll_id>/details " ) ]
@ -632,6 +694,7 @@ async fn send_invite(
data : JsonUpcase < InviteData > ,
data : JsonUpcase < InviteData > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
let data : InviteData = data . into_inner ( ) . data ;
let data : InviteData = data . into_inner ( ) . data ;
@ -700,6 +763,17 @@ async fn send_invite(
new_user . save ( & mut conn ) . await ? ;
new_user . save ( & mut conn ) . await ? ;
log_event (
EventType ::OrganizationUserInvited as i32 ,
& new_user . uuid ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
if CONFIG . mail_enabled ( ) {
if CONFIG . mail_enabled ( ) {
let org_name = match Organization ::find_by_uuid ( & org_id , & mut conn ) . await {
let org_name = match Organization ::find_by_uuid ( & org_id , & mut conn ) . await {
Some ( org ) = > org . name ,
Some ( org ) = > org . name ,
@ -882,6 +956,7 @@ async fn bulk_confirm_invite(
data : JsonUpcase < Value > ,
data : JsonUpcase < Value > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> Json < Value > {
) -> Json < Value > {
let data = data . into_inner ( ) . data ;
let data = data . into_inner ( ) . data ;
@ -891,7 +966,7 @@ async fn bulk_confirm_invite(
for invite in keys {
for invite in keys {
let org_user_id = invite [ "Id" ] . as_str ( ) . unwrap_or_default ( ) ;
let org_user_id = invite [ "Id" ] . as_str ( ) . unwrap_or_default ( ) ;
let user_key = invite [ "Key" ] . as_str ( ) . unwrap_or_default ( ) ;
let user_key = invite [ "Key" ] . as_str ( ) . unwrap_or_default ( ) ;
let err_msg = match _confirm_invite ( & org_id , org_user_id , user_key , & headers , & mut conn ). await {
let err_msg = match _confirm_invite ( & org_id , org_user_id , user_key , & headers , & mut conn , & ip ). await {
Ok ( _ ) = > String ::new ( ) ,
Ok ( _ ) = > String ::new ( ) ,
Err ( e ) = > format! ( "{:?}" , e ) ,
Err ( e ) = > format! ( "{:?}" , e ) ,
} ;
} ;
@ -922,10 +997,11 @@ async fn confirm_invite(
data : JsonUpcase < Value > ,
data : JsonUpcase < Value > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
let data = data . into_inner ( ) . data ;
let data = data . into_inner ( ) . data ;
let user_key = data [ "Key" ] . as_str ( ) . unwrap_or_default ( ) ;
let user_key = data [ "Key" ] . as_str ( ) . unwrap_or_default ( ) ;
_confirm_invite ( & org_id , & org_user_id , user_key , & headers , & mut conn ). await
_confirm_invite ( & org_id , & org_user_id , user_key , & headers , & mut conn , & ip ). await
}
}
async fn _confirm_invite (
async fn _confirm_invite (
@ -934,6 +1010,7 @@ async fn _confirm_invite(
key : & str ,
key : & str ,
headers : & AdminHeaders ,
headers : & AdminHeaders ,
conn : & mut DbConn ,
conn : & mut DbConn ,
ip : & ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
if key . is_empty ( ) | | org_user_id . is_empty ( ) {
if key . is_empty ( ) | | org_user_id . is_empty ( ) {
err ! ( "Key or UserId is not set, unable to process request" ) ;
err ! ( "Key or UserId is not set, unable to process request" ) ;
@ -969,6 +1046,17 @@ async fn _confirm_invite(
user_to_confirm . status = UserOrgStatus ::Confirmed as i32 ;
user_to_confirm . status = UserOrgStatus ::Confirmed as i32 ;
user_to_confirm . akey = key . to_string ( ) ;
user_to_confirm . akey = key . to_string ( ) ;
log_event (
EventType ::OrganizationUserConfirmed as i32 ,
& user_to_confirm . uuid ,
String ::from ( org_id ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
conn ,
)
. await ;
if CONFIG . mail_enabled ( ) {
if CONFIG . mail_enabled ( ) {
let org_name = match Organization ::find_by_uuid ( org_id , conn ) . await {
let org_name = match Organization ::find_by_uuid ( org_id , conn ) . await {
Some ( org ) = > org . name ,
Some ( org ) = > org . name ,
@ -1009,8 +1097,9 @@ async fn put_organization_user(
data : JsonUpcase < EditUserData > ,
data : JsonUpcase < EditUserData > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
edit_user ( org_id , org_user_id , data , headers , conn ). await
edit_user ( org_id , org_user_id , data , headers , conn , ip ). await
}
}
#[ post( " /organizations/<org_id>/users/<org_user_id> " , data = " <data> " , rank = 1) ]
#[ post( " /organizations/<org_id>/users/<org_user_id> " , data = " <data> " , rank = 1) ]
@ -1020,6 +1109,7 @@ async fn edit_user(
data : JsonUpcase < EditUserData > ,
data : JsonUpcase < EditUserData > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
let data : EditUserData = data . into_inner ( ) . data ;
let data : EditUserData = data . into_inner ( ) . data ;
@ -1095,6 +1185,17 @@ async fn edit_user(
}
}
}
}
log_event (
EventType ::OrganizationUserUpdated as i32 ,
& user_to_edit . uuid ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
user_to_edit . save ( & mut conn ) . await
user_to_edit . save ( & mut conn ) . await
}
}
@ -1104,12 +1205,13 @@ async fn bulk_delete_user(
data : JsonUpcase < OrgBulkIds > ,
data : JsonUpcase < OrgBulkIds > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> Json < Value > {
) -> Json < Value > {
let data : OrgBulkIds = data . into_inner ( ) . data ;
let data : OrgBulkIds = data . into_inner ( ) . data ;
let mut bulk_response = Vec ::new ( ) ;
let mut bulk_response = Vec ::new ( ) ;
for org_user_id in data . Ids {
for org_user_id in data . Ids {
let err_msg = match _delete_user ( & org_id , & org_user_id , & headers , & mut conn ). await {
let err_msg = match _delete_user ( & org_id , & org_user_id , & headers , & mut conn , & ip ). await {
Ok ( _ ) = > String ::new ( ) ,
Ok ( _ ) = > String ::new ( ) ,
Err ( e ) = > format! ( "{:?}" , e ) ,
Err ( e ) = > format! ( "{:?}" , e ) ,
} ;
} ;
@ -1131,11 +1233,34 @@ async fn bulk_delete_user(
}
}
#[ delete( " /organizations/<org_id>/users/<org_user_id> " ) ]
#[ delete( " /organizations/<org_id>/users/<org_user_id> " ) ]
async fn delete_user ( org_id : String , org_user_id : String , headers : AdminHeaders , mut conn : DbConn ) -> EmptyResult {
async fn delete_user (
_delete_user ( & org_id , & org_user_id , & headers , & mut conn ) . await
org_id : String ,
org_user_id : String ,
headers : AdminHeaders ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
_delete_user ( & org_id , & org_user_id , & headers , & mut conn , & ip ) . await
}
#[ post( " /organizations/<org_id>/users/<org_user_id>/delete " ) ]
async fn post_delete_user (
org_id : String ,
org_user_id : String ,
headers : AdminHeaders ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
_delete_user ( & org_id , & org_user_id , & headers , & mut conn , & ip ) . await
}
}
async fn _delete_user ( org_id : & str , org_user_id : & str , headers : & AdminHeaders , conn : & mut DbConn ) -> EmptyResult {
async fn _delete_user (
org_id : & str ,
org_user_id : & str ,
headers : & AdminHeaders ,
conn : & mut DbConn ,
ip : & ClientIp ,
) -> EmptyResult {
let user_to_delete = match UserOrganization ::find_by_uuid_and_org ( org_user_id , org_id , conn ) . await {
let user_to_delete = match UserOrganization ::find_by_uuid_and_org ( org_user_id , org_id , conn ) . await {
Some ( user ) = > user ,
Some ( user ) = > user ,
None = > err ! ( "User to delete isn't member of the organization" ) ,
None = > err ! ( "User to delete isn't member of the organization" ) ,
@ -1152,12 +1277,18 @@ async fn _delete_user(org_id: &str, org_user_id: &str, headers: &AdminHeaders, c
}
}
}
}
user_to_delete . delete ( conn ) . await
log_event (
}
EventType ::OrganizationUserRemoved as i32 ,
& user_to_delete . uuid ,
String ::from ( org_id ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
conn ,
)
. await ;
#[ post( " /organizations/<org_id>/users/<org_user_id>/delete " ) ]
user_to_delete . delete ( conn ) . await
async fn post_delete_user ( org_id : String , org_user_id : String , headers : AdminHeaders , conn : DbConn ) -> EmptyResult {
delete_user ( org_id , org_user_id , headers , conn ) . await
}
}
#[ post( " /organizations/<org_id>/users/public-keys " , data = " <data> " ) ]
#[ post( " /organizations/<org_id>/users/public-keys " , data = " <data> " ) ]
@ -1223,6 +1354,7 @@ async fn post_org_import(
data : JsonUpcase < ImportData > ,
data : JsonUpcase < ImportData > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
nt : Notify < ' _ > ,
nt : Notify < ' _ > ,
) -> EmptyResult {
) -> EmptyResult {
let data : ImportData = data . into_inner ( ) . data ;
let data : ImportData = data . into_inner ( ) . data ;
@ -1249,7 +1381,9 @@ async fn post_org_import(
let mut ciphers = Vec ::new ( ) ;
let mut ciphers = Vec ::new ( ) ;
for cipher_data in data . Ciphers {
for cipher_data in data . Ciphers {
let mut cipher = Cipher ::new ( cipher_data . Type , cipher_data . Name . clone ( ) ) ;
let mut cipher = Cipher ::new ( cipher_data . Type , cipher_data . Name . clone ( ) ) ;
update_cipher_from_data ( & mut cipher , cipher_data , & headers , false , & mut conn , & nt , UpdateType ::None ) . await . ok ( ) ;
update_cipher_from_data ( & mut cipher , cipher_data , & headers , false , & mut conn , & ip , & nt , UpdateType ::None )
. await
. ok ( ) ;
ciphers . push ( cipher ) ;
ciphers . push ( cipher ) ;
}
}
@ -1333,8 +1467,9 @@ async fn put_policy(
org_id : String ,
org_id : String ,
pol_type : i32 ,
pol_type : i32 ,
data : Json < PolicyData > ,
data : Json < PolicyData > ,
_ headers: AdminHeaders ,
headers: AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
let data : PolicyData = data . into_inner ( ) ;
let data : PolicyData = data . into_inner ( ) ;
@ -1360,6 +1495,18 @@ async fn put_policy(
mail ::send_2fa_removed_from_org ( & user . email , & org . name ) . await ? ;
mail ::send_2fa_removed_from_org ( & user . email , & org . name ) . await ? ;
}
}
log_event (
EventType ::OrganizationUserRemoved as i32 ,
& member . uuid ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
member . delete ( & mut conn ) . await ? ;
member . delete ( & mut conn ) . await ? ;
}
}
}
}
@ -1382,6 +1529,18 @@ async fn put_policy(
mail ::send_single_org_removed_from_org ( & user . email , & org . name ) . await ? ;
mail ::send_single_org_removed_from_org ( & user . email , & org . name ) . await ? ;
}
}
log_event (
EventType ::OrganizationUserRemoved as i32 ,
& member . uuid ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
member . delete ( & mut conn ) . await ? ;
member . delete ( & mut conn ) . await ? ;
}
}
}
}
@ -1389,13 +1548,24 @@ async fn put_policy(
let mut policy = match OrgPolicy ::find_by_org_and_type ( & org_id , pol_type_enum , & mut conn ) . await {
let mut policy = match OrgPolicy ::find_by_org_and_type ( & org_id , pol_type_enum , & mut conn ) . await {
Some ( p ) = > p ,
Some ( p ) = > p ,
None = > OrgPolicy ::new ( org_id , pol_type_enum , "{}" . to_string ( ) ) ,
None = > OrgPolicy ::new ( org_id .clone ( ) , pol_type_enum , "{}" . to_string ( ) ) ,
} ;
} ;
policy . enabled = data . enabled ;
policy . enabled = data . enabled ;
policy . data = serde_json ::to_string ( & data . data ) ? ;
policy . data = serde_json ::to_string ( & data . data ) ? ;
policy . save ( & mut conn ) . await ? ;
policy . save ( & mut conn ) . await ? ;
log_event (
EventType ::PolicyUpdated as i32 ,
& policy . uuid ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
Ok ( Json ( policy . to_json ( ) ) )
Ok ( Json ( policy . to_json ( ) ) )
}
}
@ -1467,7 +1637,13 @@ struct OrgImportData {
}
}
#[ post( " /organizations/<org_id>/import " , data = " <data> " ) ]
#[ post( " /organizations/<org_id>/import " , data = " <data> " ) ]
async fn import ( org_id : String , data : JsonUpcase < OrgImportData > , headers : Headers , mut conn : DbConn ) -> EmptyResult {
async fn import (
org_id : String ,
data : JsonUpcase < OrgImportData > ,
headers : Headers ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
let data = data . into_inner ( ) . data ;
let data = data . into_inner ( ) . data ;
// TODO: Currently we aren't storing the externalId's anywhere, so we also don't have a way
// TODO: Currently we aren't storing the externalId's anywhere, so we also don't have a way
@ -1487,6 +1663,17 @@ async fn import(org_id: String, data: JsonUpcase<OrgImportData>, headers: Header
// If user is marked for deletion and it exists, delete it
// If user is marked for deletion and it exists, delete it
if let Some ( user_org ) = UserOrganization ::find_by_email_and_org ( & user_data . Email , & org_id , & mut conn ) . await
if let Some ( user_org ) = UserOrganization ::find_by_email_and_org ( & user_data . Email , & org_id , & mut conn ) . await
{
{
log_event (
EventType ::OrganizationUserRemoved as i32 ,
& user_org . uuid ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
user_org . delete ( & mut conn ) . await ? ;
user_org . delete ( & mut conn ) . await ? ;
}
}
@ -1506,6 +1693,17 @@ async fn import(org_id: String, data: JsonUpcase<OrgImportData>, headers: Header
new_org_user . save ( & mut conn ) . await ? ;
new_org_user . save ( & mut conn ) . await ? ;
log_event (
EventType ::OrganizationUserInvited as i32 ,
& new_org_user . uuid ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
if CONFIG . mail_enabled ( ) {
if CONFIG . mail_enabled ( ) {
let org_name = match Organization ::find_by_uuid ( & org_id , & mut conn ) . await {
let org_name = match Organization ::find_by_uuid ( & org_id , & mut conn ) . await {
Some ( org ) = > org . name ,
Some ( org ) = > org . name ,
@ -1531,6 +1729,17 @@ async fn import(org_id: String, data: JsonUpcase<OrgImportData>, headers: Header
for user_org in UserOrganization ::find_by_org_and_type ( & org_id , UserOrgType ::User , & mut conn ) . await {
for user_org in UserOrganization ::find_by_org_and_type ( & org_id , UserOrgType ::User , & mut conn ) . await {
if let Some ( user_email ) = User ::find_by_uuid ( & user_org . user_uuid , & mut conn ) . await . map ( | u | u . email ) {
if let Some ( user_email ) = User ::find_by_uuid ( & user_org . user_uuid , & mut conn ) . await . map ( | u | u . email ) {
if ! data . Users . iter ( ) . any ( | u | u . Email = = user_email ) {
if ! data . Users . iter ( ) . any ( | u | u . Email = = user_email ) {
log_event (
EventType ::OrganizationUserRemoved as i32 ,
& user_org . uuid ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
user_org . delete ( & mut conn ) . await ? ;
user_org . delete ( & mut conn ) . await ? ;
}
}
}
}
@ -1547,8 +1756,9 @@ async fn deactivate_organization_user(
org_user_id : String ,
org_user_id : String ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
_revoke_organization_user ( & org_id , & org_user_id , & headers , & mut conn ). await
_revoke_organization_user ( & org_id , & org_user_id , & headers , & mut conn , & ip ). await
}
}
// Pre web-vault v2022.9.x endpoint
// Pre web-vault v2022.9.x endpoint
@ -1558,8 +1768,9 @@ async fn bulk_deactivate_organization_user(
data : JsonUpcase < Value > ,
data : JsonUpcase < Value > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> Json < Value > {
) -> Json < Value > {
bulk_revoke_organization_user ( org_id , data , headers , conn ). await
bulk_revoke_organization_user ( org_id , data , headers , conn , ip ). await
}
}
#[ put( " /organizations/<org_id>/users/<org_user_id>/revoke " ) ]
#[ put( " /organizations/<org_id>/users/<org_user_id>/revoke " ) ]
@ -1568,8 +1779,9 @@ async fn revoke_organization_user(
org_user_id : String ,
org_user_id : String ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
_revoke_organization_user ( & org_id , & org_user_id , & headers , & mut conn ). await
_revoke_organization_user ( & org_id , & org_user_id , & headers , & mut conn , & ip ). await
}
}
#[ put( " /organizations/<org_id>/users/revoke " , data = " <data> " ) ]
#[ put( " /organizations/<org_id>/users/revoke " , data = " <data> " ) ]
@ -1578,6 +1790,7 @@ async fn bulk_revoke_organization_user(
data : JsonUpcase < Value > ,
data : JsonUpcase < Value > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> Json < Value > {
) -> Json < Value > {
let data = data . into_inner ( ) . data ;
let data = data . into_inner ( ) . data ;
@ -1586,7 +1799,7 @@ async fn bulk_revoke_organization_user(
Some ( org_users ) = > {
Some ( org_users ) = > {
for org_user_id in org_users {
for org_user_id in org_users {
let org_user_id = org_user_id . as_str ( ) . unwrap_or_default ( ) ;
let org_user_id = org_user_id . as_str ( ) . unwrap_or_default ( ) ;
let err_msg = match _revoke_organization_user ( & org_id , org_user_id , & headers , & mut conn ). await {
let err_msg = match _revoke_organization_user ( & org_id , org_user_id , & headers , & mut conn , & ip ). await {
Ok ( _ ) = > String ::new ( ) ,
Ok ( _ ) = > String ::new ( ) ,
Err ( e ) = > format! ( "{:?}" , e ) ,
Err ( e ) = > format! ( "{:?}" , e ) ,
} ;
} ;
@ -1615,6 +1828,7 @@ async fn _revoke_organization_user(
org_user_id : & str ,
org_user_id : & str ,
headers : & AdminHeaders ,
headers : & AdminHeaders ,
conn : & mut DbConn ,
conn : & mut DbConn ,
ip : & ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
match UserOrganization ::find_by_uuid_and_org ( org_user_id , org_id , conn ) . await {
match UserOrganization ::find_by_uuid_and_org ( org_user_id , org_id , conn ) . await {
Some ( mut user_org ) if user_org . status > UserOrgStatus ::Revoked as i32 = > {
Some ( mut user_org ) if user_org . status > UserOrgStatus ::Revoked as i32 = > {
@ -1632,6 +1846,17 @@ async fn _revoke_organization_user(
user_org . revoke ( ) ;
user_org . revoke ( ) ;
user_org . save ( conn ) . await ? ;
user_org . save ( conn ) . await ? ;
log_event (
EventType ::OrganizationUserRevoked as i32 ,
& user_org . uuid ,
org_id . to_string ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
conn ,
)
. await ;
}
}
Some ( _ ) = > err ! ( "User is already revoked" ) ,
Some ( _ ) = > err ! ( "User is already revoked" ) ,
None = > err ! ( "User not found in organization" ) ,
None = > err ! ( "User not found in organization" ) ,
@ -1646,8 +1871,9 @@ async fn activate_organization_user(
org_user_id : String ,
org_user_id : String ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
_restore_organization_user ( & org_id , & org_user_id , & headers , & mut conn ). await
_restore_organization_user ( & org_id , & org_user_id , & headers , & mut conn , & ip ). await
}
}
// Pre web-vault v2022.9.x endpoint
// Pre web-vault v2022.9.x endpoint
@ -1657,8 +1883,9 @@ async fn bulk_activate_organization_user(
data : JsonUpcase < Value > ,
data : JsonUpcase < Value > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> Json < Value > {
) -> Json < Value > {
bulk_restore_organization_user ( org_id , data , headers , conn ). await
bulk_restore_organization_user ( org_id , data , headers , conn , ip ). await
}
}
#[ put( " /organizations/<org_id>/users/<org_user_id>/restore " ) ]
#[ put( " /organizations/<org_id>/users/<org_user_id>/restore " ) ]
@ -1667,8 +1894,9 @@ async fn restore_organization_user(
org_user_id : String ,
org_user_id : String ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
_restore_organization_user ( & org_id , & org_user_id , & headers , & mut conn ). await
_restore_organization_user ( & org_id , & org_user_id , & headers , & mut conn , & ip ). await
}
}
#[ put( " /organizations/<org_id>/users/restore " , data = " <data> " ) ]
#[ put( " /organizations/<org_id>/users/restore " , data = " <data> " ) ]
@ -1677,6 +1905,7 @@ async fn bulk_restore_organization_user(
data : JsonUpcase < Value > ,
data : JsonUpcase < Value > ,
headers : AdminHeaders ,
headers : AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> Json < Value > {
) -> Json < Value > {
let data = data . into_inner ( ) . data ;
let data = data . into_inner ( ) . data ;
@ -1685,7 +1914,7 @@ async fn bulk_restore_organization_user(
Some ( org_users ) = > {
Some ( org_users ) = > {
for org_user_id in org_users {
for org_user_id in org_users {
let org_user_id = org_user_id . as_str ( ) . unwrap_or_default ( ) ;
let org_user_id = org_user_id . as_str ( ) . unwrap_or_default ( ) ;
let err_msg = match _restore_organization_user ( & org_id , org_user_id , & headers , & mut conn ). await {
let err_msg = match _restore_organization_user ( & org_id , org_user_id , & headers , & mut conn , & ip ). await {
Ok ( _ ) = > String ::new ( ) ,
Ok ( _ ) = > String ::new ( ) ,
Err ( e ) = > format! ( "{:?}" , e ) ,
Err ( e ) = > format! ( "{:?}" , e ) ,
} ;
} ;
@ -1714,6 +1943,7 @@ async fn _restore_organization_user(
org_user_id : & str ,
org_user_id : & str ,
headers : & AdminHeaders ,
headers : & AdminHeaders ,
conn : & mut DbConn ,
conn : & mut DbConn ,
ip : & ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
match UserOrganization ::find_by_uuid_and_org ( org_user_id , org_id , conn ) . await {
match UserOrganization ::find_by_uuid_and_org ( org_user_id , org_id , conn ) . await {
Some ( mut user_org ) if user_org . status < UserOrgStatus ::Accepted as i32 = > {
Some ( mut user_org ) if user_org . status < UserOrgStatus ::Accepted as i32 = > {
@ -1740,6 +1970,17 @@ async fn _restore_organization_user(
user_org . restore ( ) ;
user_org . restore ( ) ;
user_org . save ( conn ) . await ? ;
user_org . save ( conn ) . await ? ;
log_event (
EventType ::OrganizationUserRestored as i32 ,
& user_org . uuid ,
org_id . to_string ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
conn ,
)
. await ;
}
}
Some ( _ ) = > err ! ( "User is already active" ) ,
Some ( _ ) = > err ! ( "User is already active" ) ,
None = > err ! ( "User not found in organization" ) ,
None = > err ! ( "User not found in organization" ) ,
@ -1828,37 +2069,51 @@ impl SelectionReadOnly {
}
}
}
}
#[ post( " /organizations/< _ org_id>/groups/<group_id>" , data = " <data> " ) ]
#[ post( " /organizations/< org_id>/groups/<group_id>" , data = " <data> " ) ]
async fn post_group (
async fn post_group (
_ org_id: String ,
org_id: String ,
group_id : String ,
group_id : String ,
data : JsonUpcase < GroupRequest > ,
data : JsonUpcase < GroupRequest > ,
_ headers: AdminHeaders ,
headers: AdminHeaders ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
put_group ( _ org_id, group_id , data , _ headers, conn ) . await
put_group ( org_id, group_id , data , headers, conn , ip ) . await
}
}
#[ post( " /organizations/<org_id>/groups " , data = " <data> " ) ]
#[ post( " /organizations/<org_id>/groups " , data = " <data> " ) ]
async fn post_groups (
async fn post_groups (
org_id : String ,
org_id : String ,
_ headers: AdminHeaders ,
headers: AdminHeaders ,
data : JsonUpcase < GroupRequest > ,
data : JsonUpcase < GroupRequest > ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
let group_request = data . into_inner ( ) . data ;
let group_request = data . into_inner ( ) . data ;
let group = group_request . to_group ( & org_id ) ? ;
let group = group_request . to_group ( & org_id ) ? ;
log_event (
EventType ::GroupCreated as i32 ,
& group . uuid ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
add_update_group ( group , group_request . Collections , & mut conn ) . await
add_update_group ( group , group_request . Collections , & mut conn ) . await
}
}
#[ put( " /organizations/<_org_id>/groups/<group_id> " , data = " <data> " ) ]
#[ put( " /organizations/< org_id>/groups/<group_id>" , data = " <data> " ) ]
async fn put_group (
async fn put_group (
_org_id : String ,
org_id: String ,
group_id : String ,
group_id : String ,
data : JsonUpcase < GroupRequest > ,
data : JsonUpcase < GroupRequest > ,
_headers : AdminHeaders ,
headers: AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> JsonResult {
) -> JsonResult {
let group = match Group ::find_by_uuid ( & group_id , & mut conn ) . await {
let group = match Group ::find_by_uuid ( & group_id , & mut conn ) . await {
Some ( group ) = > group ,
Some ( group ) = > group ,
@ -1870,6 +2125,17 @@ async fn put_group(
CollectionGroup ::delete_all_by_group ( & group_id , & mut conn ) . await ? ;
CollectionGroup ::delete_all_by_group ( & group_id , & mut conn ) . await ? ;
log_event (
EventType ::GroupUpdated as i32 ,
& updated_group . uuid ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
add_update_group ( updated_group , group_request . Collections , & mut conn ) . await
add_update_group ( updated_group , group_request . Collections , & mut conn ) . await
}
}
@ -1915,17 +2181,40 @@ async fn get_group_details(_org_id: String, group_id: String, _headers: AdminHea
}
}
#[ post( " /organizations/<org_id>/groups/<group_id>/delete " ) ]
#[ post( " /organizations/<org_id>/groups/<group_id>/delete " ) ]
async fn post_delete_group ( org_id : String , group_id : String , _headers : AdminHeaders , conn : DbConn ) -> EmptyResult {
async fn post_delete_group (
delete_group ( org_id , group_id , _headers , conn ) . await
org_id : String ,
group_id : String ,
headers : AdminHeaders ,
conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
delete_group ( org_id , group_id , headers , conn , ip ) . await
}
}
#[ delete( " /organizations/<_org_id>/groups/<group_id> " ) ]
#[ delete( " /organizations/<org_id>/groups/<group_id> " ) ]
async fn delete_group ( _org_id : String , group_id : String , _headers : AdminHeaders , mut conn : DbConn ) -> EmptyResult {
async fn delete_group (
org_id : String ,
group_id : String ,
headers : AdminHeaders ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
let group = match Group ::find_by_uuid ( & group_id , & mut conn ) . await {
let group = match Group ::find_by_uuid ( & group_id , & mut conn ) . await {
Some ( group ) = > group ,
Some ( group ) = > group ,
_ = > err ! ( "Group not found" ) ,
_ = > err ! ( "Group not found" ) ,
} ;
} ;
log_event (
EventType ::GroupDeleted as i32 ,
& group . uuid ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
group . delete ( & mut conn ) . await
group . delete ( & mut conn ) . await
}
}
@ -1955,13 +2244,14 @@ async fn get_group_users(_org_id: String, group_id: String, _headers: AdminHeade
Ok ( Json ( json ! ( group_users ) ) )
Ok ( Json ( json ! ( group_users ) ) )
}
}
#[ put( " /organizations/< _ org_id>/groups/<group_id>/users" , data = " <data> " ) ]
#[ put( " /organizations/< org_id>/groups/<group_id>/users" , data = " <data> " ) ]
async fn put_group_users (
async fn put_group_users (
_ org_id: String ,
org_id: String ,
group_id : String ,
group_id : String ,
_ headers: AdminHeaders ,
headers: AdminHeaders ,
data : JsonVec < String > ,
data : JsonVec < String > ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
match Group ::find_by_uuid ( & group_id , & mut conn ) . await {
match Group ::find_by_uuid ( & group_id , & mut conn ) . await {
Some ( _ ) = > { /* Do nothing */ }
Some ( _ ) = > { /* Do nothing */ }
@ -1972,8 +2262,19 @@ async fn put_group_users(
let assigned_user_ids = data . into_inner ( ) ;
let assigned_user_ids = data . into_inner ( ) ;
for assigned_user_id in assigned_user_ids {
for assigned_user_id in assigned_user_ids {
let mut user_entry = GroupUser ::new ( group_id . clone ( ) , assigned_user_id );
let mut user_entry = GroupUser ::new ( group_id . clone ( ) , assigned_user_id .clone ( ) );
user_entry . save ( & mut conn ) . await ? ;
user_entry . save ( & mut conn ) . await ? ;
log_event (
EventType ::OrganizationUserUpdatedGroups as i32 ,
& assigned_user_id ,
org_id . clone ( ) ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
}
}
Ok ( ( ) )
Ok ( ( ) )
@ -1998,61 +2299,76 @@ struct OrganizationUserUpdateGroupsRequest {
GroupIds : Vec < String > ,
GroupIds : Vec < String > ,
}
}
#[ post( " /organizations/< _ org_id>/users/<user_id>/groups" , data = " <data> " ) ]
#[ post( " /organizations/< org_id>/users/<org_ user_id>/groups" , data = " <data> " ) ]
async fn post_user_groups (
async fn post_user_groups (
_ org_id: String ,
org_id: String ,
user_id: String ,
org_ user_id: String ,
data : JsonUpcase < OrganizationUserUpdateGroupsRequest > ,
data : JsonUpcase < OrganizationUserUpdateGroupsRequest > ,
_ headers: AdminHeaders ,
headers: AdminHeaders ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
put_user_groups ( _ org_id, user_id, data , _ headers, conn ) . await
put_user_groups ( org_id, org_ user_id, data , headers, conn , ip ) . await
}
}
#[ put( " /organizations/< _ org_id>/users/<user_id>/groups" , data = " <data> " ) ]
#[ put( " /organizations/< org_id>/users/<org_ user_id>/groups" , data = " <data> " ) ]
async fn put_user_groups (
async fn put_user_groups (
_ org_id: String ,
org_id: String ,
user_id: String ,
org_ user_id: String ,
data : JsonUpcase < OrganizationUserUpdateGroupsRequest > ,
data : JsonUpcase < OrganizationUserUpdateGroupsRequest > ,
_ headers: AdminHeaders ,
headers: AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
match UserOrganization ::find_by_uuid ( & user_id, & mut conn ) . await {
match UserOrganization ::find_by_uuid ( & org_ user_id, & mut conn ) . await {
Some ( _ ) = > { /* Do nothing */ }
Some ( _ ) = > { /* Do nothing */ }
_ = > err ! ( "User could not be found!" ) ,
_ = > err ! ( "User could not be found!" ) ,
} ;
} ;
GroupUser ::delete_all_by_user ( & user_id, & mut conn ) . await ? ;
GroupUser ::delete_all_by_user ( & org_ user_id, & mut conn ) . await ? ;
let assigned_group_ids = data . into_inner ( ) . data ;
let assigned_group_ids = data . into_inner ( ) . data ;
for assigned_group_id in assigned_group_ids . GroupIds {
for assigned_group_id in assigned_group_ids . GroupIds {
let mut group_user = GroupUser ::new ( assigned_group_id . clone ( ) , user_id. clone ( ) ) ;
let mut group_user = GroupUser ::new ( assigned_group_id . clone ( ) , org_ user_id. clone ( ) ) ;
group_user . save ( & mut conn ) . await ? ;
group_user . save ( & mut conn ) . await ? ;
}
}
log_event (
EventType ::OrganizationUserUpdatedGroups as i32 ,
& org_user_id ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
Ok ( ( ) )
Ok ( ( ) )
}
}
#[ post( " /organizations/<org_id>/groups/<group_id>/delete-user/<user_id> " ) ]
#[ post( " /organizations/<org_id>/groups/<group_id>/delete-user/< org_ user_id>" ) ]
async fn post_delete_group_user (
async fn post_delete_group_user (
org_id : String ,
org_id : String ,
group_id : String ,
group_id : String ,
user_id : String ,
org_ user_id: String ,
headers : AdminHeaders ,
headers : AdminHeaders ,
conn : DbConn ,
conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
delete_group_user ( org_id , group_id , user_id, headers , conn ) . await
delete_group_user ( org_id , group_id , org_ user_id, headers , conn , ip ) . await
}
}
#[ delete( " /organizations/< _ org_id>/groups/<group_id>/users/<user_id>" ) ]
#[ delete( " /organizations/< org_id>/groups/<group_id>/users/<org_ user_id>" ) ]
async fn delete_group_user (
async fn delete_group_user (
_ org_id: String ,
org_id: String ,
group_id : String ,
group_id : String ,
user_id: String ,
org_ user_id: String ,
_ headers: AdminHeaders ,
headers: AdminHeaders ,
mut conn : DbConn ,
mut conn : DbConn ,
ip : ClientIp ,
) -> EmptyResult {
) -> EmptyResult {
match UserOrganization ::find_by_uuid ( & user_id, & mut conn ) . await {
match UserOrganization ::find_by_uuid ( & org_ user_id, & mut conn ) . await {
Some ( _ ) = > { /* Do nothing */ }
Some ( _ ) = > { /* Do nothing */ }
_ = > err ! ( "User could not be found!" ) ,
_ = > err ! ( "User could not be found!" ) ,
} ;
} ;
@ -2062,7 +2378,18 @@ async fn delete_group_user(
_ = > err ! ( "Group could not be found!" ) ,
_ = > err ! ( "Group could not be found!" ) ,
} ;
} ;
GroupUser ::delete_by_group_id_and_user_id ( & group_id , & user_id , & mut conn ) . await
log_event (
EventType ::OrganizationUserUpdatedGroups as i32 ,
& org_user_id ,
org_id ,
headers . user . uuid . clone ( ) ,
headers . device . atype ,
& ip . ip ,
& mut conn ,
)
. await ;
GroupUser ::delete_by_group_id_and_user_id ( & group_id , & org_user_id , & mut conn ) . await
}
}
// This is a new function active since the v2022.9.x clients.
// This is a new function active since the v2022.9.x clients.