Skip to content

Commit

Permalink
Create user with preferred_username
Browse files Browse the repository at this point in the history
  • Loading branch information
Timshel committed Nov 15, 2023
1 parent 1a133da commit c0cb3b4
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/api/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ async fn invite_user(data: Json<InviteData>, _token: AdminToken, mut conn: DbCon
err_code!("User already exists", Status::Conflict.code)
}

let mut user = User::new(data.email);
let mut user = User::new(data.email, None);

async fn _generate_invite(user: &User, conn: &mut DbConn) -> EmptyResult {
if CONFIG.mail_enabled() {
Expand Down
2 changes: 1 addition & 1 deletion src/api/core/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ pub async fn _register(data: JsonUpcase<RegisterData>, mut conn: DbConn) -> Json
// because the vaultwarden admin can invite anyone, regardless
// of other signup restrictions.
if Invitation::take(&email, &mut conn).await || CONFIG.is_signup_allowed(&email) {
User::new(email.clone())
User::new(email.clone(), None)
} else {
err!("Registration not allowed or user already exists")
}
Expand Down
2 changes: 1 addition & 1 deletion src/api/core/emergency_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ async fn send_invite(data: JsonUpcase<EmergencyAccessInviteData>, headers: Heade
invitation.save(&mut conn).await?;
}

let mut user = User::new(email.clone());
let mut user = User::new(email.clone(), None);
user.save(&mut conn).await?;
user
}
Expand Down
2 changes: 1 addition & 1 deletion src/api/core/organizations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,7 @@ async fn send_invite(
invitation.save(&mut conn).await?;
}

let mut user = User::new(email.clone());
let mut user = User::new(email.clone(), None);
user.save(&mut conn).await?;
user
}
Expand Down
2 changes: 1 addition & 1 deletion src/api/core/public.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ async fn ldap_import(data: JsonUpcase<OrgImportData>, token: PublicToken, mut co
Some(user) => user, // exists in vaultwarden
None => {
// User does not exist yet
let mut new_user = User::new(user_data.Email.clone());
let mut new_user = User::new(user_data.Email.clone(), None);
new_user.save(&mut conn).await?;

if !CONFIG.mail_enabled() {
Expand Down
6 changes: 3 additions & 3 deletions src/api/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ async fn _authorization_login(
Some(code) => code,
};

let email = sso::exchange_code(code).await?;
let user_infos = sso::exchange_code(code).await?;

let user_data = match User::find_by_mail(email.as_str(), conn).await {
let user_data = match User::find_by_mail(user_infos.email.as_str(), conn).await {
None => None,
Some(user) => {
let (mut device, new_device) = get_device(&data, conn, &user).await;
Expand All @@ -186,7 +186,7 @@ async fn _authorization_login(
let (user, mut device, new_device, twofactor_token) = match user_data {
Some(data) => data,
None => {
let mut user = User::new(email.clone());
let mut user = User::new(user_infos.email, user_infos.user_name);
user.verified_at = Some(now);
user.save(conn).await?;

Expand Down
4 changes: 2 additions & 2 deletions src/db/models/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl User {
pub const CLIENT_KDF_TYPE_DEFAULT: i32 = UserKdfType::Pbkdf2 as i32;
pub const CLIENT_KDF_ITER_DEFAULT: i32 = 600_000;

pub fn new(email: String) -> Self {
pub fn new(email: String, name: Option<String>) -> Self {
let now = Utc::now().naive_utc();
let email = email.to_lowercase();

Expand All @@ -97,7 +97,7 @@ impl User {
verified_at: None,
last_verifying_at: None,
login_verify_count: 0,
name: email.clone(),
name: name.unwrap_or(email.clone()),
email,
akey: String::new(),
email_new: None,
Expand Down
24 changes: 20 additions & 4 deletions src/sso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ struct AuthenticatedUser {
pub nonce: String,
pub refresh_token: String,
pub email: String,
pub user_name: Option<String>,
}

// DecodingKey and Validation used to read the SSO JWT token response
Expand Down Expand Up @@ -131,14 +132,23 @@ fn prepare_decoding() -> (DecodingKey, Validation) {
}
}

#[derive(Clone, Debug)]
pub struct UserInformation {
pub email: String,
pub user_name: Option<String>,
}

// During the 2FA flow we will
// - retrieve the user information and then only discover he needs 2FA.
// - second time we will rely on the `AC_CACHE` since the `code` has already been exchanged.
// The `nonce` will ensure that the user is authorized only once.
// We return only the `email` to force calling `redeem` to obtain the `refresh_token`.
pub async fn exchange_code(code: &String) -> ApiResult<String> {
// We return only the `UserInformation` to force calling `redeem` to obtain the `refresh_token`.
pub async fn exchange_code(code: &String) -> ApiResult<UserInformation> {
if let Some(authenticated_user) = AC_CACHE.get(code) {
return Ok(authenticated_user.email);
return Ok(UserInformation {
email: authenticated_user.email,
user_name: authenticated_user.user_name,
});
}

let oidc_code = AuthorizationCode::new(code.clone());
Expand Down Expand Up @@ -178,15 +188,21 @@ pub async fn exchange_code(code: &String) -> ApiResult<String> {
},
};

let user_name = user_info.preferred_username().map(|un| un.to_string());

let authenticated_user = AuthenticatedUser {
nonce: token.nonce,
refresh_token,
email: email.clone(),
user_name: user_name.clone(),
};

AC_CACHE.insert(code.clone(), authenticated_user.clone());

Ok(email)
Ok(UserInformation {
email,
user_name,
})
}
Err(err) => err!(format!("Failed to contact token endpoint: {err}")),
}
Expand Down

0 comments on commit c0cb3b4

Please sign in to comment.