mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-09-10 18:55:57 +03:00
Config can now be serialized / deserialized
This commit is contained in:
@@ -24,6 +24,8 @@ pub fn routes() -> Vec<Route> {
|
||||
invite_user,
|
||||
delete_user,
|
||||
deauth_user,
|
||||
get_config,
|
||||
post_config,
|
||||
]
|
||||
}
|
||||
|
||||
@@ -136,11 +138,11 @@ fn invite_user(data: JsonUpcase<InviteData>, _token: AdminToken, conn: DbConn) -
|
||||
err!("Invitations are not allowed")
|
||||
}
|
||||
|
||||
if let Some(ref mail_config) = CONFIG.mail() {
|
||||
if CONFIG.mail_enabled() {
|
||||
let mut user = User::new(email);
|
||||
user.save(&conn)?;
|
||||
let org_name = "bitwarden_rs";
|
||||
mail::send_invite(&user.email, &user.uuid, None, None, &org_name, None, mail_config)
|
||||
mail::send_invite(&user.email, &user.uuid, None, None, &org_name, None)
|
||||
} else {
|
||||
let mut invitation = Invitation::new(data.Email);
|
||||
invitation.save(&conn)
|
||||
@@ -169,6 +171,20 @@ fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult {
|
||||
user.save(&conn)
|
||||
}
|
||||
|
||||
#[get("/config")]
|
||||
fn get_config(_token: AdminToken) -> EmptyResult {
|
||||
unimplemented!("Get config")
|
||||
}
|
||||
|
||||
#[post("/config", data = "<data>")]
|
||||
fn post_config(data: JsonUpcase<Value>, _token: AdminToken) -> EmptyResult {
|
||||
let data: Value = data.into_inner().data;
|
||||
|
||||
info!("CONFIG: {:#?}", data);
|
||||
|
||||
unimplemented!("Update config")
|
||||
}
|
||||
|
||||
pub struct AdminToken {}
|
||||
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for AdminToken {
|
||||
|
@@ -419,8 +419,8 @@ fn password_hint(data: JsonUpcase<PasswordHintData>, conn: DbConn) -> EmptyResul
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
if let Some(ref mail_config) = CONFIG.mail() {
|
||||
mail::send_password_hint(&data.Email, hint, mail_config)?;
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_password_hint(&data.Email, hint)?;
|
||||
} else if CONFIG.show_password_hint() {
|
||||
if let Some(hint) = hint {
|
||||
err!(format!("Your password hint is: {}", &hint));
|
||||
|
@@ -486,9 +486,9 @@ fn send_invite(org_id: String, data: JsonUpcase<InviteData>, headers: AdminHeade
|
||||
}
|
||||
|
||||
for email in data.Emails.iter() {
|
||||
let mut user_org_status = match CONFIG.mail() {
|
||||
Some(_) => UserOrgStatus::Invited as i32,
|
||||
None => UserOrgStatus::Accepted as i32, // Automatically mark user as accepted if no email invites
|
||||
let mut user_org_status = match CONFIG.mail_enabled() {
|
||||
true => UserOrgStatus::Invited as i32,
|
||||
false => UserOrgStatus::Accepted as i32, // Automatically mark user as accepted if no email invites
|
||||
};
|
||||
let user = match User::find_by_mail(&email, &conn) {
|
||||
None => {
|
||||
@@ -496,7 +496,7 @@ fn send_invite(org_id: String, data: JsonUpcase<InviteData>, headers: AdminHeade
|
||||
err!(format!("User email does not exist: {}", email))
|
||||
}
|
||||
|
||||
if CONFIG.mail().is_none() {
|
||||
if !CONFIG.mail_enabled() {
|
||||
let mut invitation = Invitation::new(email.clone());
|
||||
invitation.save(&conn)?;
|
||||
}
|
||||
@@ -535,7 +535,7 @@ fn send_invite(org_id: String, data: JsonUpcase<InviteData>, headers: AdminHeade
|
||||
|
||||
new_user.save(&conn)?;
|
||||
|
||||
if let Some(ref mail_config) = CONFIG.mail() {
|
||||
if CONFIG.mail_enabled() {
|
||||
let org_name = match Organization::find_by_uuid(&org_id, &conn) {
|
||||
Some(org) => org.name,
|
||||
None => err!("Error looking up organization"),
|
||||
@@ -548,7 +548,6 @@ fn send_invite(org_id: String, data: JsonUpcase<InviteData>, headers: AdminHeade
|
||||
Some(new_user.uuid),
|
||||
&org_name,
|
||||
Some(headers.user.email.clone()),
|
||||
mail_config,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
@@ -562,7 +561,7 @@ fn reinvite_user(org_id: String, user_org: String, headers: AdminHeaders, conn:
|
||||
err!("Invitations are not allowed.")
|
||||
}
|
||||
|
||||
if CONFIG.mail().is_none() {
|
||||
if !CONFIG.mail_enabled() {
|
||||
err!("SMTP is not configured.")
|
||||
}
|
||||
|
||||
@@ -585,7 +584,7 @@ fn reinvite_user(org_id: String, user_org: String, headers: AdminHeaders, conn:
|
||||
None => err!("Error looking up organization."),
|
||||
};
|
||||
|
||||
if let Some(ref mail_config) = CONFIG.mail() {
|
||||
if CONFIG.mail_enabled() {
|
||||
mail::send_invite(
|
||||
&user.email,
|
||||
&user.uuid,
|
||||
@@ -593,7 +592,6 @@ fn reinvite_user(org_id: String, user_org: String, headers: AdminHeaders, conn:
|
||||
Some(user_org.uuid),
|
||||
&org_name,
|
||||
Some(headers.user.email),
|
||||
mail_config,
|
||||
)?;
|
||||
} else {
|
||||
let mut invitation = Invitation::new(user.email.clone());
|
||||
@@ -637,7 +635,7 @@ fn accept_invite(_org_id: String, _org_user_id: String, data: JsonUpcase<AcceptD
|
||||
None => err!("Invited user not found"),
|
||||
}
|
||||
|
||||
if let Some(ref mail_config) = CONFIG.mail() {
|
||||
if CONFIG.mail_enabled() {
|
||||
let mut org_name = String::from("bitwarden_rs");
|
||||
if let Some(org_id) = &claims.org_id {
|
||||
org_name = match Organization::find_by_uuid(&org_id, &conn) {
|
||||
@@ -647,10 +645,10 @@ fn accept_invite(_org_id: String, _org_user_id: String, data: JsonUpcase<AcceptD
|
||||
};
|
||||
if let Some(invited_by_email) = &claims.invited_by_email {
|
||||
// User was invited to an organization, so they must be confirmed manually after acceptance
|
||||
mail::send_invite_accepted(&claims.email, invited_by_email, &org_name, mail_config)?;
|
||||
mail::send_invite_accepted(&claims.email, invited_by_email, &org_name)?;
|
||||
} else {
|
||||
// User was invited from /admin, so they are automatically confirmed
|
||||
mail::send_invite_confirmed(&claims.email, &org_name, mail_config)?;
|
||||
mail::send_invite_confirmed(&claims.email, &org_name)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,7 +684,7 @@ fn confirm_invite(
|
||||
None => err!("Invalid key provided"),
|
||||
};
|
||||
|
||||
if let Some(ref mail_config) = CONFIG.mail() {
|
||||
if CONFIG.mail_enabled() {
|
||||
let org_name = match Organization::find_by_uuid(&org_id, &conn) {
|
||||
Some(org) => org.name,
|
||||
None => err!("Error looking up organization."),
|
||||
@@ -695,7 +693,7 @@ fn confirm_invite(
|
||||
Some(user) => user.email,
|
||||
None => err!("Error looking up user."),
|
||||
};
|
||||
mail::send_invite_confirmed(&address, &org_name, mail_config)?;
|
||||
mail::send_invite_confirmed(&address, &org_name)?;
|
||||
}
|
||||
|
||||
user_to_confirm.save(&conn)
|
||||
|
@@ -3,15 +3,14 @@ use rocket_contrib::json::Json;
|
||||
use serde_json;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::api::{ApiResult, EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData};
|
||||
use crate::auth::Headers;
|
||||
use crate::crypto;
|
||||
use crate::db::{
|
||||
models::{TwoFactor, TwoFactorType, User},
|
||||
DbConn,
|
||||
};
|
||||
|
||||
use crate::crypto;
|
||||
|
||||
use crate::api::{ApiResult, EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData};
|
||||
use crate::auth::Headers;
|
||||
use crate::error::{Error, MapResult};
|
||||
|
||||
use rocket::Route;
|
||||
|
||||
@@ -508,32 +507,31 @@ fn jsonify_yubikeys(yubikeys: Vec<String>) -> serde_json::Value {
|
||||
result
|
||||
}
|
||||
|
||||
fn verify_yubikey_otp(otp: String) -> JsonResult {
|
||||
if !CONFIG.yubico_cred_set() {
|
||||
err!("`YUBICO_CLIENT_ID` or `YUBICO_SECRET_KEY` environment variable is not set. Yubikey OTP Disabled")
|
||||
fn get_yubico_credentials() -> Result<(String, String), Error> {
|
||||
match (CONFIG.yubico_client_id(), CONFIG.yubico_secret_key()) {
|
||||
(Some(id), Some(secret)) => Ok((id, secret)),
|
||||
_ => err!("`YUBICO_CLIENT_ID` or `YUBICO_SECRET_KEY` environment variable is not set. Yubikey OTP Disabled"),
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_yubikey_otp(otp: String) -> EmptyResult {
|
||||
let (yubico_id, yubico_secret) = get_yubico_credentials()?;
|
||||
|
||||
let yubico = Yubico::new();
|
||||
let config = Config::default()
|
||||
.set_client_id(CONFIG.yubico_client_id())
|
||||
.set_key(CONFIG.yubico_secret_key());
|
||||
let config = Config::default().set_client_id(yubico_id).set_key(yubico_secret);
|
||||
|
||||
let result = match CONFIG.yubico_server() {
|
||||
match CONFIG.yubico_server() {
|
||||
Some(server) => yubico.verify(otp, config.set_api_hosts(vec![server])),
|
||||
None => yubico.verify(otp, config),
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(_answer) => Ok(Json(json!({}))),
|
||||
Err(_e) => err!("Failed to verify OTP"),
|
||||
}
|
||||
.map_res("Failed to verify OTP")
|
||||
.and(Ok(()))
|
||||
}
|
||||
|
||||
#[post("/two-factor/get-yubikey", data = "<data>")]
|
||||
fn generate_yubikey(data: JsonUpcase<PasswordData>, headers: Headers, conn: DbConn) -> JsonResult {
|
||||
if !CONFIG.yubico_cred_set() {
|
||||
err!("`YUBICO_CLIENT_ID` or `YUBICO_SECRET_KEY` environment variable is not set. Yubikey OTP Disabled")
|
||||
}
|
||||
// Make sure the credentials are set
|
||||
get_yubico_credentials()?;
|
||||
|
||||
let data: PasswordData = data.into_inner().data;
|
||||
let user = headers.user;
|
||||
@@ -597,11 +595,7 @@ fn activate_yubikey(data: JsonUpcase<EnableYubikeyData>, headers: Headers, conn:
|
||||
continue;
|
||||
}
|
||||
|
||||
let result = verify_yubikey_otp(yubikey.to_owned());
|
||||
|
||||
if let Err(_e) = result {
|
||||
err!("Invalid Yubikey OTP provided");
|
||||
}
|
||||
verify_yubikey_otp(yubikey.to_owned()).map_res("Invalid Yubikey OTP provided")?;
|
||||
}
|
||||
|
||||
let yubikey_ids: Vec<String> = yubikeys.into_iter().map(|x| (&x[..12]).to_owned()).collect();
|
||||
|
@@ -355,7 +355,7 @@ pub fn start_notification_server() -> WebSocketUsers {
|
||||
thread::spawn(move || {
|
||||
WebSocket::new(factory)
|
||||
.unwrap()
|
||||
.listen(&CONFIG.websocket_url())
|
||||
.listen((CONFIG.websocket_address().as_str(), CONFIG.websocket_port()))
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user