vw_small

Hardened fork of Vaultwarden (https://github.com/dani-garcia/vaultwarden) with fewer features.
git clone https://git.philomathiclife.com/repos/vw_small
Log | Files | Refs | README

commit 043aa27aa36f3918ad273eb67068cc0dc925dfb4
parent 9824d94a1cc039d1e0ac62301abf0b6fbb148709
Author: janost <janost@users.noreply.github.com>
Date:   Mon, 30 Nov 2020 23:12:56 +0100

Implement admin ability to enable/disable users

Diffstat:
Amigrations/mysql/2020-11-30-224000_add_user_enabled/down.sql | 0
Amigrations/mysql/2020-11-30-224000_add_user_enabled/up.sql | 1+
Amigrations/postgresql/2020-11-30-224000_add_user_enabled/down.sql | 0
Amigrations/postgresql/2020-11-30-224000_add_user_enabled/up.sql | 1+
Amigrations/sqlite/2020-11-30-224000_add_user_enabled/down.sql | 0
Amigrations/sqlite/2020-11-30-224000_add_user_enabled/up.sql | 1+
Msrc/api/admin.rs | 21+++++++++++++++++++++
Msrc/api/identity.rs | 8++++++++
Msrc/db/models/user.rs | 2++
Msrc/db/schemas/mysql/schema.rs | 1+
Msrc/db/schemas/postgresql/schema.rs | 1+
Msrc/db/schemas/sqlite/schema.rs | 1+
Msrc/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 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 @@ -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 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 @@ -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 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 @@ -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 @@ -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 }).collect(); @@ -319,6 +322,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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -22,6 +22,9 @@ <strong>{{Name}}</strong> <span class="d-block">{{Email}}</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}} @@ -54,6 +57,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}} @@ -113,6 +121,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",