admin/users: force delete totp secret, totp backup
This commit is contained in:
parent
2418c8e124
commit
bb2d8fed45
3 changed files with 172 additions and 0 deletions
|
|
@ -28,6 +28,8 @@ pub fn routes() -> Vec<Route> {
|
|||
admin_users_archive,
|
||||
admin_users_password_reset,
|
||||
admin_users_paper_key_reset,
|
||||
admin_users_totp_secret_disable,
|
||||
admin_users_totp_backup_delete,
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -351,6 +351,7 @@ pub async fn admin_users_paper_key_reset(
|
|||
.await?
|
||||
.ok_or_else(|| Error::not_found("Could not find user"))?;
|
||||
|
||||
// Delete paper key
|
||||
user.set_paper_key(&mut transaction, None).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
|
|
@ -366,3 +367,82 @@ pub async fn admin_users_paper_key_reset(
|
|||
flash_message,
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, FromForm)]
|
||||
pub struct TotpSecretDisableForm {
|
||||
pub disable: Option<bool>,
|
||||
}
|
||||
|
||||
#[post("/admin/users/<id>/totp_secret", data = "<form>")]
|
||||
pub async fn admin_users_totp_secret_disable(
|
||||
_admin_not_current: JwtAdminNotCurrent,
|
||||
mut db: Connection<Database>,
|
||||
id: RocketUserID,
|
||||
form: Form<TotpSecretDisableForm>,
|
||||
) -> Result<Flash<Redirect>> {
|
||||
let (flash_kind, flash_message) = match form.disable {
|
||||
Some(true) => {
|
||||
let mut transaction = db.begin().await?;
|
||||
|
||||
// Get user
|
||||
let user = User::get_by_id(&mut transaction, &id.0)
|
||||
.await?
|
||||
.ok_or_else(|| Error::not_found("Could not find user"))?;
|
||||
|
||||
// Delete totp secret
|
||||
user.set_totp_secret(&mut transaction, None).await?;
|
||||
|
||||
// Delete totp backup
|
||||
user.set_totp_backup(&mut transaction, None).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
(FlashKind::Success, "TOTP has been disabled.")
|
||||
}
|
||||
_ => (FlashKind::Warning, "Nothing to do."),
|
||||
};
|
||||
|
||||
Ok(Flash::new(
|
||||
Redirect::to(uri!(admin_users_view(id))),
|
||||
flash_kind,
|
||||
flash_message,
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, FromForm)]
|
||||
pub struct TotpBackupDeleteForm {
|
||||
pub delete: Option<bool>,
|
||||
}
|
||||
|
||||
#[post("/admin/users/<id>/totp_backup", data = "<form>")]
|
||||
pub async fn admin_users_totp_backup_delete(
|
||||
_admin_not_current: JwtAdminNotCurrent,
|
||||
mut db: Connection<Database>,
|
||||
id: RocketUserID,
|
||||
form: Form<TotpBackupDeleteForm>,
|
||||
) -> Result<Flash<Redirect>> {
|
||||
let (flash_kind, flash_message) = match form.delete {
|
||||
Some(true) => {
|
||||
let mut transaction = db.begin().await?;
|
||||
|
||||
// Get user
|
||||
let user = User::get_by_id(&mut transaction, &id.0)
|
||||
.await?
|
||||
.ok_or_else(|| Error::not_found("Could not find user"))?;
|
||||
|
||||
// Delete totp backup
|
||||
user.set_totp_backup(&mut transaction, None).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
(FlashKind::Success, "TOTP backup has been deleted.")
|
||||
}
|
||||
_ => (FlashKind::Warning, "Nothing to do."),
|
||||
};
|
||||
|
||||
Ok(Flash::new(
|
||||
Redirect::to(uri!(admin_users_view(id))),
|
||||
flash_kind,
|
||||
flash_message,
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -429,6 +429,96 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TOTP secret reset -->
|
||||
<div class="modal modal-blur" tabindex="-1" id="modal-totp-secret">
|
||||
<div class="modal-dialog modal-sm modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
|
||||
<div class="modal-status bg-danger"></div>
|
||||
|
||||
<form action="{{ local.id }}/totp_secret" method="post">
|
||||
|
||||
<div class="modal-body text-center py-4">
|
||||
|
||||
<div class="text-danger mb-2">
|
||||
{% include "icons/alert-triangle-large" %}
|
||||
</div>
|
||||
|
||||
<h3>Do you want to disable TOTP for this user?</h3>
|
||||
<div class="mt-2">This will also delete the TOTP backup.</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<div class="w-100">
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
<a href="#" class="btn w-100" data-bs-dismiss="modal">Cancel</a>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<button type="submit" name="disable" value="true"
|
||||
class="btn btn-danger w-100">
|
||||
Disable TOTP
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- TOTP backup delete -->
|
||||
<div class="modal modal-blur" tabindex="-1" id="modal-totp-backup">
|
||||
<div class="modal-dialog modal-sm modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
|
||||
<div class="modal-status bg-danger"></div>
|
||||
|
||||
<form action="{{ local.id }}/totp_backup" method="post">
|
||||
|
||||
<div class="modal-body text-center py-4">
|
||||
|
||||
<div class="text-danger mb-2">
|
||||
{% include "icons/alert-triangle-large" %}
|
||||
</div>
|
||||
|
||||
<h3>Do you want to delete the TOTP backup for this user?</h3>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<div class="w-100">
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
<a href="#" class="btn w-100" data-bs-dismiss="modal">Cancel</a>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<button type="submit" name="delete" value="true"
|
||||
class="btn btn-danger w-100">
|
||||
Delete backup
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
{% block libs_js %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue