mirror of
https://github.com/dani-garcia/vaultwarden
synced 2024-11-24 21:03:05 +00:00
Add password_hints_allowed
config option
Disabling password hints is mainly useful for admins who are concerned that their users might provide password hints that are too revealing.
This commit is contained in:
parent
60b339f450
commit
5e13b1a7cb
3 changed files with 32 additions and 9 deletions
|
@ -270,6 +270,9 @@
|
||||||
## The change only applies when the password is changed
|
## The change only applies when the password is changed
|
||||||
# PASSWORD_ITERATIONS=100000
|
# PASSWORD_ITERATIONS=100000
|
||||||
|
|
||||||
|
## Controls whether users can set password hints. This setting applies globally to all users.
|
||||||
|
# PASSWORD_HINTS_ALLOWED=true
|
||||||
|
|
||||||
## Controls whether a password hint should be shown directly in the web page if
|
## Controls whether a password hint should be shown directly in the web page if
|
||||||
## SMTP service is not configured. Not recommended for publicly-accessible instances
|
## SMTP service is not configured. Not recommended for publicly-accessible instances
|
||||||
## as this provides unauthenticated access to potentially sensitive data.
|
## as this provides unauthenticated access to potentially sensitive data.
|
||||||
|
|
|
@ -62,6 +62,24 @@ struct KeysData {
|
||||||
PublicKey: String,
|
PublicKey: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trims whitespace from password hints, and converts blank password hints to `None`.
|
||||||
|
fn clean_password_hint(password_hint: &Option<String>) -> Option<String> {
|
||||||
|
match password_hint {
|
||||||
|
None => None,
|
||||||
|
Some(h) => match h.trim() {
|
||||||
|
"" => None,
|
||||||
|
ht => Some(ht.to_string()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enforce_password_hint_setting(password_hint: &Option<String>) -> EmptyResult {
|
||||||
|
if password_hint.is_some() && !CONFIG.password_hints_allowed() {
|
||||||
|
err!("Password hints have been disabled by the administrator. Remove the hint and try again.");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/accounts/register", data = "<data>")]
|
#[post("/accounts/register", data = "<data>")]
|
||||||
async fn register(data: JsonUpcase<RegisterData>, conn: DbConn) -> EmptyResult {
|
async fn register(data: JsonUpcase<RegisterData>, conn: DbConn) -> EmptyResult {
|
||||||
let data: RegisterData = data.into_inner().data;
|
let data: RegisterData = data.into_inner().data;
|
||||||
|
@ -75,6 +93,11 @@ async fn register(data: JsonUpcase<RegisterData>, conn: DbConn) -> EmptyResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check against the password hint setting here so if it fails, the user
|
||||||
|
// can retry without losing their invitation below.
|
||||||
|
let password_hint = clean_password_hint(&data.MasterPasswordHint);
|
||||||
|
enforce_password_hint_setting(&password_hint)?;
|
||||||
|
|
||||||
let mut user = match User::find_by_mail(&email, &conn).await {
|
let mut user = match User::find_by_mail(&email, &conn).await {
|
||||||
Some(user) => {
|
Some(user) => {
|
||||||
if !user.password_hash.is_empty() {
|
if !user.password_hash.is_empty() {
|
||||||
|
@ -131,16 +154,13 @@ async fn register(data: JsonUpcase<RegisterData>, conn: DbConn) -> EmptyResult {
|
||||||
|
|
||||||
user.set_password(&data.MasterPasswordHash, None);
|
user.set_password(&data.MasterPasswordHash, None);
|
||||||
user.akey = data.Key;
|
user.akey = data.Key;
|
||||||
|
user.password_hint = password_hint;
|
||||||
|
|
||||||
// Add extra fields if present
|
// Add extra fields if present
|
||||||
if let Some(name) = data.Name {
|
if let Some(name) = data.Name {
|
||||||
user.name = name;
|
user.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(hint) = data.MasterPasswordHint {
|
|
||||||
user.password_hint = Some(hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(keys) = data.Keys {
|
if let Some(keys) = data.Keys {
|
||||||
user.private_key = Some(keys.EncryptedPrivateKey);
|
user.private_key = Some(keys.EncryptedPrivateKey);
|
||||||
user.public_key = Some(keys.PublicKey);
|
user.public_key = Some(keys.PublicKey);
|
||||||
|
@ -191,12 +211,10 @@ async fn post_profile(data: JsonUpcase<ProfileData>, headers: Headers, conn: DbC
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut user = headers.user;
|
let mut user = headers.user;
|
||||||
|
|
||||||
user.name = data.Name;
|
user.name = data.Name;
|
||||||
user.password_hint = match data.MasterPasswordHint {
|
user.password_hint = clean_password_hint(&data.MasterPasswordHint);
|
||||||
Some(ref h) if h.is_empty() => None,
|
enforce_password_hint_setting(&user.password_hint)?;
|
||||||
_ => data.MasterPasswordHint,
|
|
||||||
};
|
|
||||||
user.save(&conn).await?;
|
user.save(&conn).await?;
|
||||||
Ok(Json(user.to_json(&conn).await))
|
Ok(Json(user.to_json(&conn).await))
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,6 +436,8 @@ make_config! {
|
||||||
/// Password iterations |> Number of server-side passwords hashing iterations.
|
/// Password iterations |> Number of server-side passwords hashing iterations.
|
||||||
/// The changes only apply when a user changes their password. Not recommended to lower the value
|
/// The changes only apply when a user changes their password. Not recommended to lower the value
|
||||||
password_iterations: i32, true, def, 100_000;
|
password_iterations: i32, true, def, 100_000;
|
||||||
|
/// Allow password hints |> Controls whether users can set password hints. This setting applies globally to all users.
|
||||||
|
password_hints_allowed: bool, true, def, true;
|
||||||
/// Show password hint |> Controls whether a password hint should be shown directly in the web page
|
/// Show password hint |> Controls whether a password hint should be shown directly in the web page
|
||||||
/// if SMTP service is not configured. Not recommended for publicly-accessible instances as this
|
/// if SMTP service is not configured. Not recommended for publicly-accessible instances as this
|
||||||
/// provides unauthenticated access to potentially sensitive data.
|
/// provides unauthenticated access to potentially sensitive data.
|
||||||
|
|
Loading…
Reference in a new issue