diff options
author | Daniel GarcĂa <[email protected]> | 2020-12-08 15:43:56 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-08 15:43:56 +0100 |
commit | 6ebc83c3b7ca33ef20a5e8d9bea31ff07407ee98 (patch) | |
tree | a833afa9a0de2a51bce8fd110a58822da85d5350 | |
parent | 99142c7552a0bb8f304e606d0e91ebb9a6866ffc (diff) | |
parent | b32f4451eecf3c2a6f7ff938c3343cb2f5bde6ef (diff) | |
download | vaultwarden-6ebc83c3b7ca33ef20a5e8d9bea31ff07407ee98.tar.gz vaultwarden-6ebc83c3b7ca33ef20a5e8d9bea31ff07407ee98.zip |
Merge pull request #1247 from janost/admin-disable-user
Implement admin ability to enable/disable users
-rw-r--r-- | migrations/mysql/2020-11-30-224000_add_user_enabled/down.sql | 0 | ||||
-rw-r--r-- | migrations/mysql/2020-11-30-224000_add_user_enabled/up.sql | 1 | ||||
-rw-r--r-- | migrations/postgresql/2020-11-30-224000_add_user_enabled/down.sql | 0 | ||||
-rw-r--r-- | migrations/postgresql/2020-11-30-224000_add_user_enabled/up.sql | 1 | ||||
-rw-r--r-- | migrations/sqlite/2020-11-30-224000_add_user_enabled/down.sql | 0 | ||||
-rw-r--r-- | migrations/sqlite/2020-11-30-224000_add_user_enabled/up.sql | 1 | ||||
-rw-r--r-- | src/api/admin.rs | 21 | ||||
-rw-r--r-- | src/api/identity.rs | 8 | ||||
-rw-r--r-- | src/db/models/user.rs | 2 | ||||
-rw-r--r-- | src/db/schemas/mysql/schema.rs | 1 | ||||
-rw-r--r-- | src/db/schemas/postgresql/schema.rs | 1 | ||||
-rw-r--r-- | src/db/schemas/sqlite/schema.rs | 1 | ||||
-rw-r--r-- | src/static/templates/admin/users.hbs | 26 |
13 files changed, 63 insertions, 0 deletions
diff --git a/migrations/mysql/2020-11-30-224000_add_user_enabled/down.sql b/migrations/mysql/2020-11-30-224000_add_user_enabled/down.sql new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/migrations/mysql/2020-11-30-224000_add_user_enabled/down.sql diff --git a/migrations/mysql/2020-11-30-224000_add_user_enabled/up.sql b/migrations/mysql/2020-11-30-224000_add_user_enabled/up.sql new file mode 100644 index 00000000..508cf101 --- /dev/null +++ b/migrations/mysql/2020-11-30-224000_add_user_enabled/up.sql @@ -0,0 +1 @@ +ALTER TABLE users ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT 1; diff --git a/migrations/postgresql/2020-11-30-224000_add_user_enabled/down.sql b/migrations/postgresql/2020-11-30-224000_add_user_enabled/down.sql new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/migrations/postgresql/2020-11-30-224000_add_user_enabled/down.sql diff --git a/migrations/postgresql/2020-11-30-224000_add_user_enabled/up.sql b/migrations/postgresql/2020-11-30-224000_add_user_enabled/up.sql new file mode 100644 index 00000000..1f13c203 --- /dev/null +++ b/migrations/postgresql/2020-11-30-224000_add_user_enabled/up.sql @@ -0,0 +1 @@ +ALTER TABLE users ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT true; diff --git a/migrations/sqlite/2020-11-30-224000_add_user_enabled/down.sql b/migrations/sqlite/2020-11-30-224000_add_user_enabled/down.sql new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/migrations/sqlite/2020-11-30-224000_add_user_enabled/down.sql diff --git a/migrations/sqlite/2020-11-30-224000_add_user_enabled/up.sql b/migrations/sqlite/2020-11-30-224000_add_user_enabled/up.sql new file mode 100644 index 00000000..508cf101 --- /dev/null +++ b/migrations/sqlite/2020-11-30-224000_add_user_enabled/up.sql @@ -0,0 +1 @@ +ALTER TABLE users ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT 1; diff --git a/src/api/admin.rs b/src/api/admin.rs index f30855e4..fe0405b3 100644 --- a/src/api/admin.rs +++ b/src/api/admin.rs @@ -36,6 +36,8 @@ pub fn routes() -> Vec<Route> { logout, delete_user, deauth_user, + disable_user, + enable_user, remove_2fa, update_revision_users, post_config, @@ -297,6 +299,7 @@ fn users_overview(_token: AdminToken, conn: DbConn) -> ApiResult<Html<String>> { usr["cipher_count"] = json!(Cipher::count_owned_by_user(&u.uuid, &conn)); usr["attachment_count"] = json!(Attachment::count_by_user(&u.uuid, &conn)); usr["attachment_size"] = json!(get_display_size(Attachment::size_by_user(&u.uuid, &conn) as i32)); + usr["user_enabled"] = json!(u.enabled); usr["created_at"] = json!(&u.created_at.format("%Y-%m-%d %H:%M:%S").to_string()); usr["last_active"] = match u.last_active(&conn) { Some(timestamp) => json!(timestamp.format("%Y-%m-%d %H:%M:%S").to_string()), @@ -324,6 +327,24 @@ fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { user.save(&conn) } +#[post("/users/<uuid>/disable")] +fn disable_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { + let mut user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?; + Device::delete_all_by_user(&user.uuid, &conn)?; + user.reset_security_stamp(); + user.enabled = false; + + user.save(&conn) +} + +#[post("/users/<uuid>/enable")] +fn enable_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { + let mut user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?; + user.enabled = true; + + user.save(&conn) +} + #[post("/users/<uuid>/remove-2fa")] fn remove_2fa(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { let mut user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?; diff --git a/src/api/identity.rs b/src/api/identity.rs index 46a70405..dcfe607a 100644 --- a/src/api/identity.rs +++ b/src/api/identity.rs @@ -102,6 +102,14 @@ fn _password_login(data: ConnectData, conn: DbConn, ip: &ClientIp) -> JsonResult ) } + // Check if the user is disabled + if !user.enabled { + err!( + "This user has been disabled", + format!("IP: {}. Username: {}.", ip.ip, username) + ) + } + let now = Local::now(); if user.verified_at.is_none() && CONFIG.mail_enabled() && CONFIG.signups_verify() { diff --git a/src/db/models/user.rs b/src/db/models/user.rs index a9c6c3d2..a2473c03 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -11,6 +11,7 @@ db_object! { #[primary_key(uuid)] pub struct User { pub uuid: String, + pub enabled: bool, pub created_at: NaiveDateTime, pub updated_at: NaiveDateTime, pub verified_at: Option<NaiveDateTime>, @@ -70,6 +71,7 @@ impl User { Self { uuid: crate::util::get_uuid(), + enabled: true, created_at: now, updated_at: now, verified_at: None, diff --git a/src/db/schemas/mysql/schema.rs b/src/db/schemas/mysql/schema.rs index a353fa5b..cc91a730 100644 --- a/src/db/schemas/mysql/schema.rs +++ b/src/db/schemas/mysql/schema.rs @@ -116,6 +116,7 @@ table! { table! { users (uuid) { uuid -> Text, + enabled -> Bool, created_at -> Datetime, updated_at -> Datetime, verified_at -> Nullable<Datetime>, diff --git a/src/db/schemas/postgresql/schema.rs b/src/db/schemas/postgresql/schema.rs index fcacb3ec..69571e8e 100644 --- a/src/db/schemas/postgresql/schema.rs +++ b/src/db/schemas/postgresql/schema.rs @@ -116,6 +116,7 @@ table! { table! { users (uuid) { uuid -> Text, + enabled -> Bool, created_at -> Timestamp, updated_at -> Timestamp, verified_at -> Nullable<Timestamp>, diff --git a/src/db/schemas/sqlite/schema.rs b/src/db/schemas/sqlite/schema.rs index fcacb3ec..69571e8e 100644 --- a/src/db/schemas/sqlite/schema.rs +++ b/src/db/schemas/sqlite/schema.rs @@ -116,6 +116,7 @@ table! { table! { users (uuid) { uuid -> Text, + enabled -> Bool, created_at -> Timestamp, updated_at -> Timestamp, verified_at -> Nullable<Timestamp>, diff --git a/src/static/templates/admin/users.hbs b/src/static/templates/admin/users.hbs index 9f55b1e4..a910989d 100644 --- a/src/static/templates/admin/users.hbs +++ b/src/static/templates/admin/users.hbs @@ -24,6 +24,9 @@ <span class="d-block">Created at: {{created_at}}</span> <span class="d-block">Last active: {{last_active}}</span> <span class="d-block"> + {{#unless user_enabled}} + <span class="badge badge-danger mr-2" title="User is disabled">Disabled</span> + {{/unless}} {{#if TwoFactorEnabled}} <span class="badge badge-success mr-2" title="2FA is enabled">2FA</span> {{/if}} @@ -56,6 +59,11 @@ {{/if}} <a class="d-block" href="#" onclick='deauthUser({{jsesc Id}})'>Deauthorize sessions</a> <a class="d-block" href="#" onclick='deleteUser({{jsesc Id}}, {{jsesc Email}})'>Delete User</a> + {{#if user_enabled}} + <a class="d-block" href="#" onclick='disableUser({{jsesc Id}}, {{jsesc Email}})'>Disable User</a> + {{else}} + <a class="d-block" href="#" onclick='enableUser({{jsesc Id}}, {{jsesc Email}})'>Enable User</a> + {{/if}} </td> </tr> {{/each}} @@ -115,6 +123,24 @@ "Error deauthorizing sessions"); return false; } + function disableUser(id, mail) { + var confirmed = confirm("Are you sure you want to disable user '" + mail + "'? This will also deauthorize their sessions.") + if (confirmed) { + _post("{{urlpath}}/admin/users/" + id + "/disable", + "User disabled successfully", + "Error disabling user"); + } + return false; + } + function enableUser(id, mail) { + var confirmed = confirm("Are you sure you want to enable user '" + mail + "'?") + if (confirmed) { + _post("{{urlpath}}/admin/users/" + id + "/enable", + "User enabled successfully", + "Error enabling user"); + } + return false; + } function updateRevisions() { _post("{{urlpath}}/admin/users/update_revision", "Success, clients will sync next time they connect", |