server: Move the definition of UserId down to lldap_auth

This commit is contained in:
Valentin Tolmer 2024-01-15 23:37:42 +01:00 committed by nitnelave
parent 10609b25e9
commit 2ea17c04ba
18 changed files with 212 additions and 162 deletions

1
Cargo.lock generated
View file

@ -2572,6 +2572,7 @@ dependencies = [
"opaque-ke", "opaque-ke",
"rand 0.8.5", "rand 0.8.5",
"rust-argon2", "rust-argon2",
"sea-orm",
"serde", "serde",
"sha2 0.9.9", "sha2 0.9.9",
"thiserror", "thiserror",

View file

@ -97,7 +97,7 @@ impl CommonComponent<ChangePasswordForm> for ChangePasswordForm {
.context("Could not initialize login")?; .context("Could not initialize login")?;
self.opaque_data = OpaqueData::Login(login_start_request.state); self.opaque_data = OpaqueData::Login(login_start_request.state);
let req = login::ClientLoginStartRequest { let req = login::ClientLoginStartRequest {
username: ctx.props().username.clone(), username: ctx.props().username.clone().into(),
login_start_request: login_start_request.message, login_start_request: login_start_request.message,
}; };
self.common.call_backend( self.common.call_backend(
@ -134,7 +134,7 @@ impl CommonComponent<ChangePasswordForm> for ChangePasswordForm {
) )
.context("Could not initiate password change")?; .context("Could not initiate password change")?;
let req = registration::ClientRegistrationStartRequest { let req = registration::ClientRegistrationStartRequest {
username: ctx.props().username.clone(), username: ctx.props().username.clone().into(),
registration_start_request: registration_start_request.message, registration_start_request: registration_start_request.message,
}; };
self.opaque_data = OpaqueData::Registration(registration_start_request.state); self.opaque_data = OpaqueData::Registration(registration_start_request.state);

View file

@ -123,7 +123,7 @@ impl CommonComponent<CreateUserForm> for CreateUserForm {
&mut rng, &mut rng,
)?; )?;
let req = registration::ClientRegistrationStartRequest { let req = registration::ClientRegistrationStartRequest {
username: user_id, username: user_id.into(),
registration_start_request: message, registration_start_request: message,
}; };
self.common self.common

View file

@ -66,7 +66,7 @@ impl CommonComponent<LoginForm> for LoginForm {
opaque::client::login::start_login(&password, &mut rng) opaque::client::login::start_login(&password, &mut rng)
.context("Could not initialize login")?; .context("Could not initialize login")?;
let req = login::ClientLoginStartRequest { let req = login::ClientLoginStartRequest {
username, username: username.into(),
login_start_request: message, login_start_request: message,
}; };
self.common self.common

View file

@ -68,7 +68,7 @@ impl CommonComponent<ResetPasswordStep2Form> for ResetPasswordStep2Form {
opaque_registration::start_registration(new_password.as_bytes(), &mut rng) opaque_registration::start_registration(new_password.as_bytes(), &mut rng)
.context("Could not initiate password change")?; .context("Could not initiate password change")?;
let req = registration::ClientRegistrationStartRequest { let req = registration::ClientRegistrationStartRequest {
username: self.username.clone().unwrap(), username: self.username.as_ref().unwrap().into(),
registration_start_request: registration_start_request.message, registration_start_request: registration_start_request.message,
}; };
self.opaque_data = Some(registration_start_request.state); self.opaque_data = Some(registration_start_request.state);

View file

@ -13,6 +13,7 @@ default = ["opaque_server", "opaque_client"]
opaque_server = [] opaque_server = []
opaque_client = [] opaque_client = []
js = [] js = []
sea_orm = ["dep:sea-orm"]
[dependencies] [dependencies]
rust-argon2 = "0.8" rust-argon2 = "0.8"
@ -31,6 +32,12 @@ version = "0.6"
version = "*" version = "*"
features = [ "serde" ] features = [ "serde" ]
[dependencies.sea-orm]
version= "0.12"
default-features = false
features = ["macros"]
optional = true
# For WASM targets, use the JS getrandom. # For WASM targets, use the JS getrandom.
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.getrandom] [target.'cfg(not(target_arch = "wasm32"))'.dependencies.getrandom]
version = "0.2" version = "0.2"

View file

@ -9,17 +9,17 @@ pub mod opaque;
/// The messages for the 3-step OPAQUE and simple login process. /// The messages for the 3-step OPAQUE and simple login process.
pub mod login { pub mod login {
use super::*; use super::{types::UserId, *};
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct ServerData { pub struct ServerData {
pub username: String, pub username: UserId,
pub server_login: opaque::server::login::ServerLogin, pub server_login: opaque::server::login::ServerLogin,
} }
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct ClientLoginStartRequest { pub struct ClientLoginStartRequest {
pub username: String, pub username: UserId,
pub login_start_request: opaque::server::login::CredentialRequest, pub login_start_request: opaque::server::login::CredentialRequest,
} }
@ -39,14 +39,14 @@ pub mod login {
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct ClientSimpleLoginRequest { pub struct ClientSimpleLoginRequest {
pub username: String, pub username: UserId,
pub password: String, pub password: String,
} }
impl fmt::Debug for ClientSimpleLoginRequest { impl fmt::Debug for ClientSimpleLoginRequest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ClientSimpleLoginRequest") f.debug_struct("ClientSimpleLoginRequest")
.field("username", &self.username) .field("username", &self.username.as_str())
.field("password", &"***********") .field("password", &"***********")
.finish() .finish()
} }
@ -63,16 +63,16 @@ pub mod login {
/// The messages for the 3-step OPAQUE registration process. /// The messages for the 3-step OPAQUE registration process.
/// It is used to reset a user's password. /// It is used to reset a user's password.
pub mod registration { pub mod registration {
use super::*; use super::{types::UserId, *};
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct ServerData { pub struct ServerData {
pub username: String, pub username: UserId,
} }
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct ClientRegistrationStartRequest { pub struct ClientRegistrationStartRequest {
pub username: String, pub username: UserId,
pub registration_start_request: opaque::server::registration::RegistrationRequest, pub registration_start_request: opaque::server::registration::RegistrationRequest,
} }
@ -104,6 +104,100 @@ pub mod password_reset {
} }
} }
pub mod types {
use serde::{Deserialize, Serialize};
#[cfg(feature = "sea_orm")]
use sea_orm::{DbErr, DeriveValueType, QueryResult, TryFromU64, Value};
#[derive(
PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Default, Hash, Serialize, Deserialize,
)]
#[cfg_attr(feature = "sea_orm", derive(DeriveValueType))]
#[serde(from = "String")]
pub struct CaseInsensitiveString(String);
impl CaseInsensitiveString {
pub fn new(s: &str) -> Self {
Self(s.to_ascii_lowercase())
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn into_string(self) -> String {
self.0
}
}
impl From<String> for CaseInsensitiveString {
fn from(mut s: String) -> Self {
s.make_ascii_lowercase();
Self(s)
}
}
impl From<&String> for CaseInsensitiveString {
fn from(s: &String) -> Self {
Self::new(s.as_str())
}
}
impl From<&str> for CaseInsensitiveString {
fn from(s: &str) -> Self {
Self::new(s)
}
}
#[derive(
PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Default, Hash, Serialize, Deserialize,
)]
#[cfg_attr(feature = "sea_orm", derive(DeriveValueType))]
#[serde(from = "CaseInsensitiveString")]
pub struct UserId(CaseInsensitiveString);
impl UserId {
pub fn new(s: &str) -> Self {
s.into()
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn into_string(self) -> String {
self.0.into_string()
}
}
impl<T> From<T> for UserId
where
T: Into<CaseInsensitiveString>,
{
fn from(s: T) -> Self {
Self(s.into())
}
}
impl std::fmt::Display for UserId {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0.as_str())
}
}
#[cfg(feature = "sea_orm")]
impl From<&UserId> for Value {
fn from(user_id: &UserId) -> Self {
user_id.as_str().into()
}
}
#[cfg(feature = "sea_orm")]
impl TryFromU64 for UserId {
fn try_from_u64(_n: u64) -> Result<Self, DbErr> {
Err(DbErr::ConvertFromU64(
"UserId cannot be constructed from u64",
))
}
}
}
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct JWTClaims { pub struct JWTClaims {
pub exp: DateTime<Utc>, pub exp: DateTime<Utc>,

View file

@ -1,3 +1,4 @@
use crate::types::UserId;
use opaque_ke::ciphersuite::CipherSuite; use opaque_ke::ciphersuite::CipherSuite;
use rand::{CryptoRng, RngCore}; use rand::{CryptoRng, RngCore};
@ -145,12 +146,12 @@ pub mod server {
pub fn start_registration( pub fn start_registration(
server_setup: &ServerSetup, server_setup: &ServerSetup,
registration_request: RegistrationRequest, registration_request: RegistrationRequest,
username: &str, username: &UserId,
) -> AuthenticationResult<ServerRegistrationStartResult> { ) -> AuthenticationResult<ServerRegistrationStartResult> {
Ok(ServerRegistration::start( Ok(ServerRegistration::start(
server_setup, server_setup,
registration_request, registration_request,
username.as_bytes(), username.as_str().as_bytes(),
)?) )?)
} }
@ -178,14 +179,14 @@ pub mod server {
server_setup: &ServerSetup, server_setup: &ServerSetup,
password_file: Option<ServerRegistration>, password_file: Option<ServerRegistration>,
credential_request: CredentialRequest, credential_request: CredentialRequest,
username: &str, username: &UserId,
) -> AuthenticationResult<ServerLoginStartResult> { ) -> AuthenticationResult<ServerLoginStartResult> {
Ok(ServerLogin::start( Ok(ServerLogin::start(
rng, rng,
server_setup, server_setup,
password_file, password_file,
credential_request, credential_request,
username.as_bytes(), username.as_str().as_bytes(),
ServerLoginStartParameters::default(), ServerLoginStartParameters::default(),
)?) )?)
} }

View file

@ -136,7 +136,7 @@ fn try_login(
let ClientLoginStartResult { state, message } = let ClientLoginStartResult { state, message } =
start_login(password, &mut rng).context("Could not initialize login")?; start_login(password, &mut rng).context("Could not initialize login")?;
let req = ClientLoginStartRequest { let req = ClientLoginStartRequest {
username: username.to_owned(), username: username.into(),
login_start_request: message, login_start_request: message,
}; };
let response = client let response = client

View file

@ -79,6 +79,7 @@ version = "0.10.1"
[dependencies.lldap_auth] [dependencies.lldap_auth]
path = "../auth" path = "../auth"
features = ["opaque_server", "opaque_client", "sea_orm"]
[dependencies.opaque-ke] [dependencies.opaque-ke]
version = "0.6" version = "0.6"

View file

@ -63,7 +63,7 @@ pub mod tests {
opaque::client::registration::start_registration(pass.as_bytes(), &mut rng).unwrap(); opaque::client::registration::start_registration(pass.as_bytes(), &mut rng).unwrap();
let response = handler let response = handler
.registration_start(registration::ClientRegistrationStartRequest { .registration_start(registration::ClientRegistrationStartRequest {
username: name.to_string(), username: name.into(),
registration_start_request: client_registration_start.message, registration_start_request: client_registration_start.message,
}) })
.await .await

View file

@ -33,7 +33,7 @@ fn passwords_match(
server_setup, server_setup,
Some(password_file), Some(password_file),
client_login_start_result.message, client_login_start_result.message,
username.as_str(), username,
)?; )?;
client::login::finish_login( client::login::finish_login(
client_login_start_result.state, client_login_start_result.state,
@ -100,15 +100,13 @@ impl OpaqueHandler for SqlOpaqueHandler {
&self, &self,
request: login::ClientLoginStartRequest, request: login::ClientLoginStartRequest,
) -> Result<login::ServerLoginStartResponse> { ) -> Result<login::ServerLoginStartResponse> {
let user_id = request.username;
let maybe_password_file = self let maybe_password_file = self
.get_password_file_for_user(UserId::new(&request.username)) .get_password_file_for_user(user_id.clone())
.await? .await?
.map(|bytes| { .map(|bytes| {
opaque::server::ServerRegistration::deserialize(&bytes).map_err(|_| { opaque::server::ServerRegistration::deserialize(&bytes).map_err(|_| {
DomainError::InternalError(format!( DomainError::InternalError(format!("Corrupted password file for {}", &user_id))
"Corrupted password file for {}",
&request.username
))
}) })
}) })
.transpose()?; .transpose()?;
@ -120,11 +118,11 @@ impl OpaqueHandler for SqlOpaqueHandler {
self.config.get_server_setup(), self.config.get_server_setup(),
maybe_password_file, maybe_password_file,
request.login_start_request, request.login_start_request,
&request.username, &user_id,
)?; )?;
let secret_key = self.get_orion_secret_key()?; let secret_key = self.get_orion_secret_key()?;
let server_data = login::ServerData { let server_data = login::ServerData {
username: request.username, username: user_id,
server_login: start_response.state, server_login: start_response.state,
}; };
let encrypted_state = orion::aead::seal(&secret_key, &bincode::serialize(&server_data)?)?; let encrypted_state = orion::aead::seal(&secret_key, &bincode::serialize(&server_data)?)?;
@ -151,7 +149,7 @@ impl OpaqueHandler for SqlOpaqueHandler {
opaque::server::login::finish_login(server_login, request.credential_finalization)? opaque::server::login::finish_login(server_login, request.credential_finalization)?
.session_key; .session_key;
Ok(UserId::new(&username)) Ok(username)
} }
#[instrument(skip_all, level = "debug", err)] #[instrument(skip_all, level = "debug", err)]
@ -191,7 +189,7 @@ impl OpaqueHandler for SqlOpaqueHandler {
opaque::server::registration::get_password_file(request.registration_upload); opaque::server::registration::get_password_file(request.registration_upload);
// Set the user password to the new password. // Set the user password to the new password.
let user_update = model::users::ActiveModel { let user_update = model::users::ActiveModel {
user_id: ActiveValue::Set(UserId::new(&username)), user_id: ActiveValue::Set(username),
password_hash: ActiveValue::Set(Some(password_file.serialize())), password_hash: ActiveValue::Set(Some(password_file.serialize())),
..Default::default() ..Default::default()
}; };
@ -204,7 +202,7 @@ impl OpaqueHandler for SqlOpaqueHandler {
#[instrument(skip_all, level = "debug", err, fields(username = %username.as_str()))] #[instrument(skip_all, level = "debug", err, fields(username = %username.as_str()))]
pub(crate) async fn register_password( pub(crate) async fn register_password(
opaque_handler: &SqlOpaqueHandler, opaque_handler: &SqlOpaqueHandler,
username: &UserId, username: UserId,
password: &SecUtf8, password: &SecUtf8,
) -> Result<()> { ) -> Result<()> {
let mut rng = rand::rngs::OsRng; let mut rng = rand::rngs::OsRng;
@ -213,7 +211,7 @@ pub(crate) async fn register_password(
opaque::client::registration::start_registration(password.unsecure().as_bytes(), &mut rng)?; opaque::client::registration::start_registration(password.unsecure().as_bytes(), &mut rng)?;
let start_response = opaque_handler let start_response = opaque_handler
.registration_start(ClientRegistrationStartRequest { .registration_start(ClientRegistrationStartRequest {
username: username.to_string(), username,
registration_start_request: registration_start.message, registration_start_request: registration_start.message,
}) })
.await?; .await?;
@ -245,7 +243,7 @@ mod tests {
let login_start = opaque::client::login::start_login(password, &mut rng)?; let login_start = opaque::client::login::start_login(password, &mut rng)?;
let start_response = opaque_handler let start_response = opaque_handler
.login_start(ClientLoginStartRequest { .login_start(ClientLoginStartRequest {
username: username.to_string(), username: UserId::new(username),
login_start_request: login_start.message, login_start_request: login_start.message,
}) })
.await?; .await?;
@ -276,7 +274,7 @@ mod tests {
.unwrap_err(); .unwrap_err();
register_password( register_password(
&opaque_handler, &opaque_handler,
&UserId::new("bob"), UserId::new("bob"),
&secstr::SecUtf8::from("bob00"), &secstr::SecUtf8::from("bob00"),
) )
.await?; .await?;

View file

@ -2,6 +2,7 @@ use std::cmp::Ordering;
use base64::Engine; use base64::Engine;
use chrono::{NaiveDateTime, TimeZone}; use chrono::{NaiveDateTime, TimeZone};
use lldap_auth::types::CaseInsensitiveString;
use sea_orm::{ use sea_orm::{
entity::IntoActiveValue, entity::IntoActiveValue,
sea_query::{value::ValueType, ArrayType, BlobSize, ColumnType, Nullable, ValueTypeErr}, sea_query::{value::ValueType, ArrayType, BlobSize, ColumnType, Nullable, ValueTypeErr},
@ -11,6 +12,7 @@ use serde::{Deserialize, Serialize};
use strum::{EnumString, IntoStaticStr}; use strum::{EnumString, IntoStaticStr};
pub use super::model::UserColumn; pub use super::model::UserColumn;
pub use lldap_auth::types::UserId;
#[derive(PartialEq, Hash, Eq, Clone, Debug, Default, Serialize, Deserialize, DeriveValueType)] #[derive(PartialEq, Hash, Eq, Clone, Debug, Default, Serialize, Deserialize, DeriveValueType)]
#[serde(try_from = "&str")] #[serde(try_from = "&str")]
@ -122,112 +124,6 @@ impl Serialized {
} }
} }
#[derive(
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Debug,
Default,
Hash,
Serialize,
Deserialize,
DeriveValueType,
)]
#[serde(from = "String")]
pub struct CaseInsensitiveString(String);
impl CaseInsensitiveString {
pub fn new(user_id: &str) -> Self {
Self(user_id.to_lowercase())
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn into_string(self) -> String {
self.0
}
}
impl From<String> for CaseInsensitiveString {
fn from(s: String) -> Self {
Self::new(&s)
}
}
macro_rules! make_case_insensitive_string {
($c:ident) => {
#[derive(
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Debug,
Default,
Hash,
Serialize,
Deserialize,
DeriveValueType,
)]
#[serde(from = "CaseInsensitiveString")]
pub struct $c(CaseInsensitiveString);
impl $c {
pub fn new(raw: &str) -> Self {
Self(CaseInsensitiveString::new(raw))
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn into_string(self) -> String {
self.0.into_string()
}
}
impl From<CaseInsensitiveString> for $c {
fn from(s: CaseInsensitiveString) -> Self {
Self(s)
}
}
impl From<String> for $c {
fn from(s: String) -> Self {
Self(CaseInsensitiveString::from(s))
}
}
impl From<&str> for $c {
fn from(s: &str) -> Self {
Self::new(s)
}
}
impl std::fmt::Display for $c {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0.as_str())
}
}
impl From<&$c> for Value {
fn from(user_id: &$c) -> Self {
user_id.as_str().into()
}
}
impl TryFromU64 for $c {
fn try_from_u64(_n: u64) -> Result<Self, DbErr> {
Err(DbErr::ConvertFromU64("$c cannot be constructed from u64"))
}
}
};
}
fn compare_str_case_insensitive(s1: &str, s2: &str) -> Ordering { fn compare_str_case_insensitive(s1: &str, s2: &str) -> Ordering {
let mut it_1 = s1.chars().flat_map(|c| c.to_lowercase()); let mut it_1 = s1.chars().flat_map(|c| c.to_lowercase());
let mut it_2 = s2.chars().flat_map(|c| c.to_lowercase()); let mut it_2 = s2.chars().flat_map(|c| c.to_lowercase());
@ -323,8 +219,58 @@ macro_rules! make_case_insensitive_comparable_string {
}; };
} }
make_case_insensitive_string!(UserId); #[derive(
make_case_insensitive_string!(AttributeName); PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Debug,
Default,
Hash,
Serialize,
Deserialize,
DeriveValueType,
)]
#[serde(from = "CaseInsensitiveString")]
pub struct AttributeName(CaseInsensitiveString);
impl AttributeName {
pub fn new(s: &str) -> Self {
s.into()
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn into_string(self) -> String {
self.0.into_string()
}
}
impl<T> From<T> for AttributeName
where
T: Into<CaseInsensitiveString>,
{
fn from(s: T) -> Self {
Self(s.into())
}
}
impl std::fmt::Display for AttributeName {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0.as_str())
}
}
impl From<&AttributeName> for Value {
fn from(attribute_name: &AttributeName) -> Self {
attribute_name.as_str().into()
}
}
impl TryFromU64 for AttributeName {
fn try_from_u64(_n: u64) -> Result<Self, DbErr> {
Err(DbErr::ConvertFromU64(
"AttributeName cannot be constructed from u64",
))
}
}
make_case_insensitive_comparable_string!(Email); make_case_insensitive_comparable_string!(Email);
make_case_insensitive_comparable_string!(GroupName); make_case_insensitive_comparable_string!(GroupName);

View file

@ -428,13 +428,13 @@ async fn simple_login<Backend>(
where where
Backend: TcpBackendHandler + BackendHandler + OpaqueHandler + LoginHandler + 'static, Backend: TcpBackendHandler + BackendHandler + OpaqueHandler + LoginHandler + 'static,
{ {
let user_id = UserId::new(&request.username); let login::ClientSimpleLoginRequest { username, password } = request.into_inner();
let bind_request = BindRequest { let bind_request = BindRequest {
name: user_id.clone(), name: username.clone(),
password: request.password.clone(), password,
}; };
data.get_login_handler().bind(bind_request).await?; data.get_login_handler().bind(bind_request).await?;
get_login_successful_response(&data, &user_id).await get_login_successful_response(&data, &username).await
} }
async fn simple_login_handler<Backend>( async fn simple_login_handler<Backend>(
@ -500,14 +500,14 @@ where
.await .await
.map_err(|e| TcpError::BadRequest(format!("{:#?}", e)))? .map_err(|e| TcpError::BadRequest(format!("{:#?}", e)))?
.into_inner(); .into_inner();
let user_id = UserId::new(&registration_start_request.username); let user_id = &registration_start_request.username;
let user_is_admin = data let user_is_admin = data
.get_readonly_handler() .get_readonly_handler()
.get_user_groups(&user_id) .get_user_groups(user_id)
.await? .await?
.iter() .iter()
.any(|g| g.display_name == "lldap_admin".into()); .any(|g| g.display_name == "lldap_admin".into());
if !validation_result.can_change_password(&user_id, user_is_admin) { if !validation_result.can_change_password(user_id, user_is_admin) {
return Err(TcpError::UnauthorizedError( return Err(TcpError::UnauthorizedError(
"Not authorized to change the user's password".to_string(), "Not authorized to change the user's password".to_string(),
)); ));

View file

@ -306,7 +306,7 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
async fn change_password<B: OpaqueHandler>( async fn change_password<B: OpaqueHandler>(
&self, &self,
backend_handler: &B, backend_handler: &B,
user: &UserId, user: UserId,
password: &[u8], password: &[u8],
) -> Result<()> { ) -> Result<()> {
use lldap_auth::*; use lldap_auth::*;
@ -314,7 +314,7 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
let registration_start_request = let registration_start_request =
opaque::client::registration::start_registration(password, &mut rng)?; opaque::client::registration::start_registration(password, &mut rng)?;
let req = registration::ClientRegistrationStartRequest { let req = registration::ClientRegistrationStartRequest {
username: user.to_string(), username: user.clone(),
registration_start_request: registration_start_request.message, registration_start_request: registration_start_request.message,
}; };
let registration_start_response = backend_handler.registration_start(req).await?; let registration_start_response = backend_handler.registration_start(req).await?;
@ -371,7 +371,7 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
), ),
}) })
} else if let Err(e) = self } else if let Err(e) = self
.change_password(self.get_opaque_handler(), &uid, password.as_bytes()) .change_password(self.get_opaque_handler(), uid, password.as_bytes())
.await .await
{ {
Err(LdapError { Err(LdapError {
@ -413,7 +413,7 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
async fn handle_modify_change( async fn handle_modify_change(
&mut self, &mut self,
user_id: &UserId, user_id: UserId,
credentials: &ValidationResults, credentials: &ValidationResults,
user_is_admin: bool, user_is_admin: bool,
change: &LdapModify, change: &LdapModify,
@ -429,7 +429,7 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
), ),
}); });
} }
if !credentials.can_change_password(user_id, user_is_admin) { if !credentials.can_change_password(&user_id, user_is_admin) {
return Err(LdapError { return Err(LdapError {
code: LdapResultCode::InsufficentAccessRights, code: LdapResultCode::InsufficentAccessRights,
message: format!( message: format!(
@ -488,7 +488,7 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
.iter() .iter()
.any(|g| g.display_name == "lldap_admin".into()); .any(|g| g.display_name == "lldap_admin".into());
for change in &request.changes { for change in &request.changes {
self.handle_modify_change(&uid, &credentials, user_is_admin, change) self.handle_modify_change(uid.clone(), &credentials, user_is_admin, change)
.await? .await?
} }
Ok(vec![make_modify_response( Ok(vec![make_modify_response(
@ -2199,7 +2199,7 @@ mod tests {
opaque::client::registration::start_registration("password".as_bytes(), &mut rng) opaque::client::registration::start_registration("password".as_bytes(), &mut rng)
.unwrap(); .unwrap();
let request = registration::ClientRegistrationStartRequest { let request = registration::ClientRegistrationStartRequest {
username: "bob".to_string(), username: "bob".into(),
registration_start_request: registration_start_request.message, registration_start_request: registration_start_request.message,
}; };
let start_response = opaque::server::registration::start_registration( let start_response = opaque::server::registration::start_registration(
@ -2247,7 +2247,7 @@ mod tests {
opaque::client::registration::start_registration("password".as_bytes(), &mut rng) opaque::client::registration::start_registration("password".as_bytes(), &mut rng)
.unwrap(); .unwrap();
let request = registration::ClientRegistrationStartRequest { let request = registration::ClientRegistrationStartRequest {
username: "bob".to_string(), username: "bob".into(),
registration_start_request: registration_start_request.message, registration_start_request: registration_start_request.message,
}; };
let start_response = opaque::server::registration::start_registration( let start_response = opaque::server::registration::start_registration(
@ -2297,7 +2297,7 @@ mod tests {
opaque::client::registration::start_registration("password".as_bytes(), &mut rng) opaque::client::registration::start_registration("password".as_bytes(), &mut rng)
.unwrap(); .unwrap();
let request = registration::ClientRegistrationStartRequest { let request = registration::ClientRegistrationStartRequest {
username: "bob".to_string(), username: "bob".into(),
registration_start_request: registration_start_request.message, registration_start_request: registration_start_request.message,
}; };
let start_response = opaque::server::registration::start_registration( let start_response = opaque::server::registration::start_registration(

View file

@ -46,7 +46,9 @@ async fn create_admin_user(handler: &SqlBackendHandler, config: &Configuration)
display_name: Some("Administrator".to_string()), display_name: Some("Administrator".to_string()),
..Default::default() ..Default::default()
}) })
.and_then(|_| register_password(handler, &config.ldap_user_dn, &config.ldap_user_pass)) .and_then(|_| {
register_password(handler, config.ldap_user_dn.clone(), &config.ldap_user_pass)
})
.await .await
.context("Error creating admin user")?; .context("Error creating admin user")?;
let groups = handler let groups = handler
@ -137,7 +139,7 @@ async fn set_up_server(config: Configuration) -> Result<ServerBuilder> {
warn!("Forcing admin password reset to the config-provided password"); warn!("Forcing admin password reset to the config-provided password");
register_password( register_password(
&backend_handler, &backend_handler,
&config.ldap_user_dn, config.ldap_user_dn.clone(),
&config.ldap_user_pass, &config.ldap_user_pass,
) )
.await .await

View file

@ -10,7 +10,7 @@ pub fn get_token(client: &Client) -> String {
.header(reqwest::header::CONTENT_TYPE, "application/json") .header(reqwest::header::CONTENT_TYPE, "application/json")
.body( .body(
serde_json::to_string(&lldap_auth::login::ClientSimpleLoginRequest { serde_json::to_string(&lldap_auth::login::ClientSimpleLoginRequest {
username, username: username.into(),
password, password,
}) })
.expect("Failed to encode the username/password as json to log in"), .expect("Failed to encode the username/password as json to log in"),

View file

@ -49,7 +49,7 @@ fn get_token(base_url: &Url, username: &str, password: &str) -> Result<String> {
.header(reqwest::header::CONTENT_TYPE, "application/json") .header(reqwest::header::CONTENT_TYPE, "application/json")
.body( .body(
serde_json::to_string(&lldap_auth::login::ClientSimpleLoginRequest { serde_json::to_string(&lldap_auth::login::ClientSimpleLoginRequest {
username: username.to_string(), username: username.into(),
password: password.to_string(), password: password.to_string(),
}) })
.expect("Failed to encode the username/password as json to log in"), .expect("Failed to encode the username/password as json to log in"),
@ -121,7 +121,7 @@ fn main() -> Result<()> {
opaque::client::registration::start_registration(opts.password.as_bytes(), &mut rng) opaque::client::registration::start_registration(opts.password.as_bytes(), &mut rng)
.context("Could not initiate password change")?; .context("Could not initiate password change")?;
let start_request = registration::ClientRegistrationStartRequest { let start_request = registration::ClientRegistrationStartRequest {
username: opts.username.to_string(), username: opts.username.clone().into(),
registration_start_request: registration_start_request.message, registration_start_request: registration_start_request.message,
}; };
let res = register_start(&opts.base_url, &token, start_request)?; let res = register_start(&opts.base_url, &token, start_request)?;