mirror of
https://github.com/lldap/lldap.git
synced 2026-07-25 17:58:44 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2d9d47623 | |||
| edf22afda0 | |||
| 7e64e061d3 | |||
| 233262efa6 | |||
| b8b48ebe24 | |||
| 8a8eb4157c | |||
| 1c92ae60d3 | |||
| f7ab6ded36 | |||
| a90695a6ce | |||
| df49d827d0 |
Generated
+1
@@ -2729,6 +2729,7 @@ dependencies = [
|
|||||||
"lldap_domain_handlers",
|
"lldap_domain_handlers",
|
||||||
"lldap_domain_model",
|
"lldap_domain_model",
|
||||||
"lldap_ldap",
|
"lldap_ldap",
|
||||||
|
"lldap_opaque_handler",
|
||||||
"lldap_sql_backend_handler",
|
"lldap_sql_backend_handler",
|
||||||
"lldap_test_utils",
|
"lldap_test_utils",
|
||||||
"lldap_validation",
|
"lldap_validation",
|
||||||
|
|||||||
@@ -55,20 +55,24 @@ version = "1"
|
|||||||
mockall = "0.11.4"
|
mockall = "0.11.4"
|
||||||
pretty_assertions = "1"
|
pretty_assertions = "1"
|
||||||
|
|
||||||
#[dev-dependencies.lldap_auth]
|
[dev-dependencies.lldap_auth]
|
||||||
#path = "../auth"
|
path = "../auth"
|
||||||
#features = ["test"]
|
features = ["test"]
|
||||||
#
|
|
||||||
#[dev-dependencies.lldap_opaque_handler]
|
[dev-dependencies.lldap_domain]
|
||||||
#path = "../opaque-handler"
|
path = "../domain"
|
||||||
#features = ["test"]
|
features = ["test"]
|
||||||
|
|
||||||
|
[dev-dependencies.lldap_opaque_handler]
|
||||||
|
path = "../opaque-handler"
|
||||||
|
features = ["test"]
|
||||||
|
|
||||||
[dev-dependencies.lldap_test_utils]
|
[dev-dependencies.lldap_test_utils]
|
||||||
path = "../test-utils"
|
path = "../test-utils"
|
||||||
#
|
|
||||||
#[dev-dependencies.lldap_sql_backend_handler]
|
[dev-dependencies.lldap_sql_backend_handler]
|
||||||
#path = "../sql-backend-handler"
|
path = "../sql-backend-handler"
|
||||||
#features = ["test"]
|
features = ["test"]
|
||||||
|
|
||||||
[dev-dependencies.tokio]
|
[dev-dependencies.tokio]
|
||||||
features = ["full"]
|
features = ["full"]
|
||||||
|
|||||||
@@ -291,12 +291,12 @@ pub fn make_ldap_subschema_entry(schema: PublicSchema) -> LdapOp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_root_dse_request(request: &LdapSearchRequest) -> bool {
|
pub(crate) fn is_root_dse_request(request: &LdapSearchRequest) -> bool {
|
||||||
if request.base.is_empty() && request.scope == LdapSearchScope::Base {
|
if request.base.is_empty()
|
||||||
if let LdapFilter::Present(attribute) = &request.filter {
|
&& request.scope == LdapSearchScope::Base
|
||||||
if attribute.eq_ignore_ascii_case("objectclass") {
|
&& let LdapFilter::Present(attribute) = &request.filter
|
||||||
return true;
|
&& attribute.eq_ignore_ascii_case("objectclass")
|
||||||
}
|
{
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1159,6 +1159,30 @@ async fn migrate_to_v11(transaction: DatabaseTransaction) -> Result<DatabaseTran
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// Initialize existing users with modified_date and password_modified_date = now
|
||||||
|
let now = chrono::Utc::now().naive_utc();
|
||||||
|
transaction
|
||||||
|
.execute(
|
||||||
|
builder.build(
|
||||||
|
Query::update()
|
||||||
|
.table(Users::Table)
|
||||||
|
.value(Users::ModifiedDate, now)
|
||||||
|
.value(Users::PasswordModifiedDate, now),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Initialize existing groups with modified_date = now
|
||||||
|
transaction
|
||||||
|
.execute(
|
||||||
|
builder.build(
|
||||||
|
Query::update()
|
||||||
|
.table(Groups::Table)
|
||||||
|
.value(Groups::ModifiedDate, now),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(transaction)
|
Ok(transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -395,12 +395,12 @@ impl UserBackendHandler for SqlBackendHandler {
|
|||||||
|
|
||||||
#[instrument(skip_all, level = "debug", err, fields(user_id = ?user_id.as_str(), group_id))]
|
#[instrument(skip_all, level = "debug", err, fields(user_id = ?user_id.as_str(), group_id))]
|
||||||
async fn add_user_to_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()> {
|
async fn add_user_to_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()> {
|
||||||
let user_id = user_id.clone();
|
let user_id_owned = user_id.clone();
|
||||||
self.sql_pool
|
self.sql_pool
|
||||||
.transaction::<_, _, sea_orm::DbErr>(|transaction| {
|
.transaction::<_, _, sea_orm::DbErr>(|transaction| {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let new_membership = model::memberships::ActiveModel {
|
let new_membership = model::memberships::ActiveModel {
|
||||||
user_id: ActiveValue::Set(user_id),
|
user_id: ActiveValue::Set(user_id_owned),
|
||||||
group_id: ActiveValue::Set(group_id),
|
group_id: ActiveValue::Set(group_id),
|
||||||
};
|
};
|
||||||
new_membership.insert(transaction).await?;
|
new_membership.insert(transaction).await?;
|
||||||
@@ -423,16 +423,16 @@ impl UserBackendHandler for SqlBackendHandler {
|
|||||||
|
|
||||||
#[instrument(skip_all, level = "debug", err, fields(user_id = ?user_id.as_str(), group_id))]
|
#[instrument(skip_all, level = "debug", err, fields(user_id = ?user_id.as_str(), group_id))]
|
||||||
async fn remove_user_from_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()> {
|
async fn remove_user_from_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()> {
|
||||||
let user_id = user_id.clone();
|
let user_id_owned = user_id.clone();
|
||||||
self.sql_pool
|
self.sql_pool
|
||||||
.transaction::<_, _, sea_orm::DbErr>(|transaction| {
|
.transaction::<_, _, sea_orm::DbErr>(|transaction| {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let res = model::Membership::delete_by_id((user_id.clone(), group_id))
|
let res = model::Membership::delete_by_id((user_id_owned.clone(), group_id))
|
||||||
.exec(transaction)
|
.exec(transaction)
|
||||||
.await?;
|
.await?;
|
||||||
if res.rows_affected == 0 {
|
if res.rows_affected == 0 {
|
||||||
return Err(sea_orm::DbErr::Custom(format!(
|
return Err(sea_orm::DbErr::Custom(format!(
|
||||||
"No such membership: '{user_id}' -> {group_id:?}"
|
"No such membership: '{user_id_owned}' -> {group_id:?}"
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,8 +186,9 @@ where
|
|||||||
Some(token) => token,
|
Some(token) => token,
|
||||||
};
|
};
|
||||||
if let Err(e) = super::mail::send_password_reset_email(
|
if let Err(e) = super::mail::send_password_reset_email(
|
||||||
user.display_name.as_deref(),
|
user.display_name
|
||||||
user.user_id.as_str(),
|
.as_deref()
|
||||||
|
.unwrap_or_else(|| user.user_id.as_str()),
|
||||||
user.email.as_str(),
|
user.email.as_str(),
|
||||||
&token,
|
&token,
|
||||||
&data.server_url,
|
&data.server_url,
|
||||||
|
|||||||
+1
-6
@@ -80,7 +80,6 @@ async fn send_email(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_password_reset_email(
|
pub async fn send_password_reset_email(
|
||||||
display_name: Option<&str>,
|
|
||||||
username: &str,
|
username: &str,
|
||||||
to: &str,
|
to: &str,
|
||||||
token: &str,
|
token: &str,
|
||||||
@@ -93,16 +92,12 @@ pub async fn send_password_reset_email(
|
|||||||
.path_segments_mut()
|
.path_segments_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.extend(["reset-password", "step2", token]);
|
.extend(["reset-password", "step2", token]);
|
||||||
let greeting = format!("Hello {},", display_name.unwrap_or(username));
|
|
||||||
|
|
||||||
let body = format!(
|
let body = format!(
|
||||||
"{greeting}
|
"Hello {username},
|
||||||
This email has been sent to you in order to validate your identity.
|
This email has been sent to you in order to validate your identity.
|
||||||
If you did not initiate the process your credentials might have been
|
If you did not initiate the process your credentials might have been
|
||||||
compromised. You should reset your password and contact an administrator.
|
compromised. You should reset your password and contact an administrator.
|
||||||
|
|
||||||
Your username is: {username}
|
|
||||||
|
|
||||||
To reset your password please visit the following URL: {reset_url}
|
To reset your password please visit the following URL: {reset_url}
|
||||||
|
|
||||||
Please contact an administrator if you did not initiate the process."
|
Please contact an administrator if you did not initiate the process."
|
||||||
|
|||||||
+6
-14
@@ -125,7 +125,7 @@ async fn setup_sql_tables(database_url: &DatabaseUrl) -> Result<DatabaseConnecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
async fn set_up_server(config: Configuration) -> Result<(ServerBuilder, DatabaseConnection)> {
|
async fn set_up_server(config: Configuration) -> Result<ServerBuilder> {
|
||||||
info!("Starting LLDAP version {}", env!("CARGO_PKG_VERSION"));
|
info!("Starting LLDAP version {}", env!("CARGO_PKG_VERSION"));
|
||||||
|
|
||||||
let sql_pool = setup_sql_tables(&config.database_url).await?;
|
let sql_pool = setup_sql_tables(&config.database_url).await?;
|
||||||
@@ -214,9 +214,9 @@ async fn set_up_server(config: Configuration) -> Result<(ServerBuilder, Database
|
|||||||
.await
|
.await
|
||||||
.context("while binding the TCP server")?;
|
.context("while binding the TCP server")?;
|
||||||
// Run every hour.
|
// Run every hour.
|
||||||
let scheduler = Scheduler::new("0 0 * * * * *", sql_pool.clone());
|
let scheduler = Scheduler::new("0 0 * * * * *", sql_pool);
|
||||||
scheduler.start();
|
scheduler.start();
|
||||||
Ok((server_builder, sql_pool))
|
Ok(server_builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_server_command(opts: RunOpts) -> Result<()> {
|
async fn run_server_command(opts: RunOpts) -> Result<()> {
|
||||||
@@ -225,14 +225,9 @@ async fn run_server_command(opts: RunOpts) -> Result<()> {
|
|||||||
let config = configuration::init(opts)?;
|
let config = configuration::init(opts)?;
|
||||||
logging::init(&config)?;
|
logging::init(&config)?;
|
||||||
|
|
||||||
let (server, sql_pool) = set_up_server(config).await?;
|
let server = set_up_server(config).await?.workers(1);
|
||||||
let server = server.workers(1);
|
|
||||||
|
|
||||||
let result = server.run().await.context("while starting the server");
|
server.run().await.context("while starting the server")
|
||||||
if let Err(e) = sql_pool.close().await {
|
|
||||||
error!("Error closing database connection pool: {}", e);
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_test_email_command(opts: TestEmailOpts) -> Result<()> {
|
async fn send_test_email_command(opts: TestEmailOpts) -> Result<()> {
|
||||||
@@ -280,11 +275,8 @@ async fn create_schema_command(opts: RunOpts) -> Result<()> {
|
|||||||
debug!("CLI: {:#?}", &opts);
|
debug!("CLI: {:#?}", &opts);
|
||||||
let config = configuration::init(opts)?;
|
let config = configuration::init(opts)?;
|
||||||
logging::init(&config)?;
|
logging::init(&config)?;
|
||||||
let sql_pool = setup_sql_tables(&config.database_url).await?;
|
setup_sql_tables(&config.database_url).await?;
|
||||||
info!("Schema created successfully.");
|
info!("Schema created successfully.");
|
||||||
if let Err(e) = sql_pool.close().await {
|
|
||||||
error!("Error closing database connection pool: {}", e);
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user