aboutsummaryrefslogtreecommitdiff
path: root/src/api/admin.rs
diff options
context:
space:
mode:
authorBlackDex <[email protected]>2022-11-20 19:15:45 +0100
committerDaniel GarcĂ­a <[email protected]>2022-12-01 22:38:59 +0100
commit7035700c8d2454b190ce860bb28b3098e73dcf65 (patch)
tree11266819455ff76bf574f48969fb080053179ac0 /src/api/admin.rs
parent0aa33a2cb48ee5dbf31a6f448effb41e7467e417 (diff)
downloadvaultwarden-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.rs44
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
}