diff options
author | BlackDex <[email protected]> | 2022-11-20 19:15:45 +0100 |
---|---|---|
committer | Daniel GarcĂa <[email protected]> | 2022-12-01 22:38:59 +0100 |
commit | 7035700c8d2454b190ce860bb28b3098e73dcf65 (patch) | |
tree | 11266819455ff76bf574f48969fb080053179ac0 /src/api/admin.rs | |
parent | 0aa33a2cb48ee5dbf31a6f448effb41e7467e417 (diff) | |
download | vaultwarden-7035700c8d2454b190ce860bb28b3098e73dcf65.tar.gz vaultwarden-7035700c8d2454b190ce860bb28b3098e73dcf65.zip |
Add Organizational event logging feature
This PR adds event/audit logging support for organizations.
By default this feature is disabled, since it does log a lot and adds
extra database transactions.
All events are touched except a few, since we do not support those
features (yet), like SSO for example.
This feature is tested with multiple clients and all database types.
Fixes #229
Diffstat (limited to 'src/api/admin.rs')
-rw-r--r-- | src/api/admin.rs | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/api/admin.rs b/src/api/admin.rs index 1900db2b..656f63bf 100644 --- a/src/api/admin.rs +++ b/src/api/admin.rs @@ -13,7 +13,7 @@ use rocket::{ }; use crate::{ - api::{ApiResult, EmptyResult, JsonResult, NumberOrString}, + api::{core::log_event, ApiResult, EmptyResult, JsonResult, NumberOrString}, auth::{decode_admin, encode_jwt, generate_admin_claims, ClientIp}, config::ConfigBuilder, db::{backup_database, get_sql_server_version, models::*, DbConn, DbConnType}, @@ -88,6 +88,8 @@ const DT_FMT: &str = "%Y-%m-%d %H:%M:%S %Z"; const BASE_TEMPLATE: &str = "admin/base"; +const ACTING_ADMIN_USER: &str = "vaultwarden-admin-00000-000000000000"; + fn admin_path() -> String { format!("{}{}", CONFIG.domain_path(), ADMIN_PATH) } @@ -354,9 +356,27 @@ async fn get_user_json(uuid: String, _token: AdminToken, mut conn: DbConn) -> Js } #[post("/users/<uuid>/delete")] -async fn delete_user(uuid: String, _token: AdminToken, mut conn: DbConn) -> EmptyResult { +async fn delete_user(uuid: String, _token: AdminToken, mut conn: DbConn, ip: ClientIp) -> EmptyResult { let user = get_user_or_404(&uuid, &mut conn).await?; - user.delete(&mut conn).await + + // Get the user_org records before deleting the actual user + let user_orgs = UserOrganization::find_any_state_by_user(&uuid, &mut conn).await; + let res = user.delete(&mut conn).await; + + for user_org in user_orgs { + log_event( + EventType::OrganizationUserRemoved as i32, + &user_org.uuid, + user_org.org_uuid, + String::from(ACTING_ADMIN_USER), + 14, // Use UnknownBrowser type + &ip.ip, + &mut conn, + ) + .await; + } + + res } #[post("/users/<uuid>/deauth")] @@ -402,7 +422,12 @@ struct UserOrgTypeData { } #[post("/users/org_type", data = "<data>")] -async fn update_user_org_type(data: Json<UserOrgTypeData>, _token: AdminToken, mut conn: DbConn) -> EmptyResult { +async fn update_user_org_type( + data: Json<UserOrgTypeData>, + _token: AdminToken, + mut conn: DbConn, + ip: ClientIp, +) -> EmptyResult { let data: UserOrgTypeData = data.into_inner(); let mut user_to_edit = @@ -437,6 +462,17 @@ async fn update_user_org_type(data: Json<UserOrgTypeData>, _token: AdminToken, m } } + log_event( + EventType::OrganizationUserUpdated as i32, + &user_to_edit.uuid, + data.org_uuid, + String::from(ACTING_ADMIN_USER), + 14, // Use UnknownBrowser type + &ip.ip, + &mut conn, + ) + .await; + user_to_edit.atype = new_type; user_to_edit.save(&mut conn).await } |