mirror of
https://github.com/dani-garcia/vaultwarden
synced 2024-11-25 05:10:20 +00:00
Implement admin ability to enable/disable users
This commit is contained in:
parent
9824d94a1c
commit
043aa27aa3
13 changed files with 63 additions and 0 deletions
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE users ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT 1;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE users ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT true;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE users ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT 1;
|
|
@ -36,6 +36,8 @@ pub fn routes() -> Vec<Route> {
|
||||||
logout,
|
logout,
|
||||||
delete_user,
|
delete_user,
|
||||||
deauth_user,
|
deauth_user,
|
||||||
|
disable_user,
|
||||||
|
enable_user,
|
||||||
remove_2fa,
|
remove_2fa,
|
||||||
update_revision_users,
|
update_revision_users,
|
||||||
post_config,
|
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["cipher_count"] = json!(Cipher::count_owned_by_user(&u.uuid, &conn));
|
||||||
usr["attachment_count"] = json!(Attachment::count_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["attachment_size"] = json!(get_display_size(Attachment::size_by_user(&u.uuid, &conn) as i32));
|
||||||
|
usr["user_enabled"] = json!(u.enabled);
|
||||||
usr
|
usr
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
@ -319,6 +322,24 @@ fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult {
|
||||||
user.save(&conn)
|
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")]
|
#[post("/users/<uuid>/remove-2fa")]
|
||||||
fn remove_2fa(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult {
|
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")?;
|
let mut user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?;
|
||||||
|
|
|
@ -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();
|
let now = Local::now();
|
||||||
|
|
||||||
if user.verified_at.is_none() && CONFIG.mail_enabled() && CONFIG.signups_verify() {
|
if user.verified_at.is_none() && CONFIG.mail_enabled() && CONFIG.signups_verify() {
|
||||||
|
|
|
@ -11,6 +11,7 @@ db_object! {
|
||||||
#[primary_key(uuid)]
|
#[primary_key(uuid)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub uuid: String,
|
pub uuid: String,
|
||||||
|
pub enabled: bool,
|
||||||
pub created_at: NaiveDateTime,
|
pub created_at: NaiveDateTime,
|
||||||
pub updated_at: NaiveDateTime,
|
pub updated_at: NaiveDateTime,
|
||||||
pub verified_at: Option<NaiveDateTime>,
|
pub verified_at: Option<NaiveDateTime>,
|
||||||
|
@ -70,6 +71,7 @@ impl User {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
uuid: crate::util::get_uuid(),
|
uuid: crate::util::get_uuid(),
|
||||||
|
enabled: true,
|
||||||
created_at: now,
|
created_at: now,
|
||||||
updated_at: now,
|
updated_at: now,
|
||||||
verified_at: None,
|
verified_at: None,
|
||||||
|
|
|
@ -116,6 +116,7 @@ table! {
|
||||||
table! {
|
table! {
|
||||||
users (uuid) {
|
users (uuid) {
|
||||||
uuid -> Text,
|
uuid -> Text,
|
||||||
|
enabled -> Bool,
|
||||||
created_at -> Datetime,
|
created_at -> Datetime,
|
||||||
updated_at -> Datetime,
|
updated_at -> Datetime,
|
||||||
verified_at -> Nullable<Datetime>,
|
verified_at -> Nullable<Datetime>,
|
||||||
|
|
|
@ -116,6 +116,7 @@ table! {
|
||||||
table! {
|
table! {
|
||||||
users (uuid) {
|
users (uuid) {
|
||||||
uuid -> Text,
|
uuid -> Text,
|
||||||
|
enabled -> Bool,
|
||||||
created_at -> Timestamp,
|
created_at -> Timestamp,
|
||||||
updated_at -> Timestamp,
|
updated_at -> Timestamp,
|
||||||
verified_at -> Nullable<Timestamp>,
|
verified_at -> Nullable<Timestamp>,
|
||||||
|
|
|
@ -116,6 +116,7 @@ table! {
|
||||||
table! {
|
table! {
|
||||||
users (uuid) {
|
users (uuid) {
|
||||||
uuid -> Text,
|
uuid -> Text,
|
||||||
|
enabled -> Bool,
|
||||||
created_at -> Timestamp,
|
created_at -> Timestamp,
|
||||||
updated_at -> Timestamp,
|
updated_at -> Timestamp,
|
||||||
verified_at -> Nullable<Timestamp>,
|
verified_at -> Nullable<Timestamp>,
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<strong>{{Name}}</strong>
|
<strong>{{Name}}</strong>
|
||||||
<span class="d-block">{{Email}}</span>
|
<span class="d-block">{{Email}}</span>
|
||||||
<span class="d-block">
|
<span class="d-block">
|
||||||
|
{{#unless user_enabled}}
|
||||||
|
<span class="badge badge-danger mr-2" title="User is disabled">Disabled</span>
|
||||||
|
{{/unless}}
|
||||||
{{#if TwoFactorEnabled}}
|
{{#if TwoFactorEnabled}}
|
||||||
<span class="badge badge-success mr-2" title="2FA is enabled">2FA</span>
|
<span class="badge badge-success mr-2" title="2FA is enabled">2FA</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -54,6 +57,11 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<a class="d-block" href="#" onclick='deauthUser({{jsesc Id}})'>Deauthorize sessions</a>
|
<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>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -113,6 +121,24 @@
|
||||||
"Error deauthorizing sessions");
|
"Error deauthorizing sessions");
|
||||||
return false;
|
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() {
|
function updateRevisions() {
|
||||||
_post("{{urlpath}}/admin/users/update_revision",
|
_post("{{urlpath}}/admin/users/update_revision",
|
||||||
"Success, clients will sync next time they connect",
|
"Success, clients will sync next time they connect",
|
||||||
|
|
Loading…
Reference in a new issue