diff --git a/src/api/admin.rs b/src/api/admin.rs index 63629bf32050f66639c41e0b2ab2aac811c57908..b49d3ca0291f8383dd8d921b4191eae8a5272b81 100644 --- a/src/api/admin.rs +++ b/src/api/admin.rs @@ -17,7 +17,14 @@ pub fn routes() -> Vec<Route> { return Vec::new(); } - routes![admin_login, post_admin_login, admin_page, invite_user, delete_user] + routes![ + admin_login, + post_admin_login, + admin_page, + invite_user, + delete_user, + deauth_user, + ] } const COOKIE_NAME: &'static str = "BWRS_ADMIN"; @@ -150,6 +157,18 @@ fn delete_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { user.delete(&conn) } +#[post("/users/<uuid>/deauth")] +fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { + let mut user = match User::find_by_uuid(&uuid, &conn) { + Some(user) => user, + None => err!("User doesn't exist"), + }; + + user.reset_security_stamp(); + + user.save(&conn) +} + pub struct AdminToken {} impl<'a, 'r> FromRequest<'a, 'r> for AdminToken { diff --git a/src/db/models/user.rs b/src/db/models/user.rs index 608f87b5392bf8245bd30d7fc89ee2ec71a2335d..429fc4ea65dd25dfacf2ae5dc7a19046b02975ad 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -120,6 +120,7 @@ impl User { let twofactor_enabled = !TwoFactor::find_by_user(&self.uuid, conn).is_empty(); json!({ + "_Enabled": !self.password_hash.is_empty(), "Id": self.uuid, "Name": self.name, "Email": self.email, diff --git a/src/static/templates/admin/page.hbs b/src/static/templates/admin/page.hbs index 5d1d9c71ebf4500f732934417f0dc7c3419963eb..7caa8b167c34d495c0011708cff397389efd79a5 100644 --- a/src/static/templates/admin/page.hbs +++ b/src/static/templates/admin/page.hbs @@ -13,6 +13,9 @@ {{#if TwoFactorEnabled}} <span class="badge badge-success ml-2">2FA</span> {{/if}} + {{#unless _Enabled}} + <span class="badge badge-warning ml-2">Disabled</span> + {{/unless}} <span class="d-block">{{Email}}</span> </div> <div class="col"> @@ -23,7 +26,8 @@ {{/each}} </span> </div> - <div style="flex: 0 0 100px;"> + <div style="flex: 0 0 240px;"> + <a class="mr-3" href="#" onclick='deauthUser("{{Id}}")'>Deauthorize sessions</a> <a class="mr-3" href="#" onclick='deleteUser("{{Id}}", "{{Email}}")'>Delete User</a> </div> </div> @@ -79,6 +83,12 @@ } return false; } + function deauthUser(id) { + _post("/admin/users/" + id + "/deauth", + "Sessions deauthorized correctly", + "Error deauthorizing sessions"); + return false; + } function inviteUser() { inv = $("#email-invite"); data = JSON.stringify({ "Email": inv.val() }); @@ -87,14 +97,12 @@ "Error inviting user", data); return false; } - let OrgTypes = { "0": { "name": "Owner", "color": "orange" }, "1": { "name": "Admin", "color": "blueviolet" }, "2": { "name": "User", "color": "blue" }, "3": { "name": "Manager", "color": "green" }, }; - $(window).on('load', function () { $("#invite-form").submit(inviteUser); $("img.identicon").each(function (i, e) {