Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/identity/backends/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,3 @@ pub fn db_err(e: sea_orm::DbErr, context: &str) -> IdentityDatabaseError {
},
)
}

impl From<sea_orm::DbErr> for IdentityDatabaseError {
fn from(err: sea_orm::DbErr) -> Self {
db_err(err, "unknown")
}
}
63 changes: 46 additions & 17 deletions src/identity/backends/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,10 @@ async fn list_users(
federated_user_select.filter(db_federated_user::Column::DisplayName.eq(name));
}

let db_users: Vec<db_user::Model> = user_select.all(db).await?;
let db_users: Vec<db_user::Model> = user_select
.all(db)
.await
.map_err(|err| db_err(err, "fetching users data"))?;

let (user_opts, local_users, nonlocal_users, federated_users) = tokio::join!(
db_users.load_many(UserOption, db),
Expand All @@ -373,23 +376,31 @@ async fn list_users(
db_users.load_many(federated_user_select, db)
);

let locals = local_users?;
let locals = local_users.map_err(|err| db_err(err, "fetching local users data"))?;

let local_users_passwords: Vec<Option<Vec<db_password::Model>>> =
local_user::load_local_users_passwords(db, locals.iter().cloned().map(|u| u.map(|x| x.id)))
.await?;

let mut results: Vec<UserResponse> = Vec::new();
for (u, (o, (l, (p, (n, f))))) in db_users.into_iter().zip(
user_opts?.into_iter().zip(
locals.into_iter().zip(
local_users_passwords.into_iter().zip(
nonlocal_users?
.into_iter()
.zip(federated_users?.into_iter()),
user_opts
.map_err(|err| db_err(err, "fetching user options"))?
.into_iter()
.zip(
locals.into_iter().zip(
local_users_passwords.into_iter().zip(
nonlocal_users
.map_err(|err| db_err(err, "fetching nonlocal users data"))?
.into_iter()
.zip(
federated_users
.map_err(|err| db_err(err, "fetching federated users data"))?
.into_iter(),
),
),
),
),
),
) {
if l.is_none() && n.is_none() && f.is_empty() {
continue;
Expand Down Expand Up @@ -430,7 +441,10 @@ pub async fn get_user(
) -> Result<Option<UserResponse>, IdentityDatabaseError> {
let user_select = DbUser::find_by_id(user_id);

let user_entry: Option<db_user::Model> = user_select.one(db).await?;
let user_entry: Option<db_user::Model> = user_select
.one(db)
.await
.map_err(|err| db_err(err, "fetching the user data"))?;

if let Some(user) = user_entry {
let (user_opts, local_user_with_passwords) = tokio::join!(
Expand All @@ -449,16 +463,31 @@ pub async fn get_user(
&user,
local_user_with_passwords.0,
Some(local_user_with_passwords.1),
user_opts?,
user_opts.map_err(|err| db_err(err, "fetching user options"))?,
),
_ => match user.find_related(NonlocalUser).one(db).await? {
Some(nonlocal_user) => {
common::get_nonlocal_user_builder(&user, nonlocal_user, user_opts?)
}
_ => match user
.find_related(NonlocalUser)
.one(db)
.await
.map_err(|err| db_err(err, "fetching nonlocal user data"))?
{
Some(nonlocal_user) => common::get_nonlocal_user_builder(
&user,
nonlocal_user,
user_opts.map_err(|err| db_err(err, "fetching user options"))?,
),
_ => {
let federated_user = user.find_related(FederatedUser).all(db).await?;
let federated_user = user
.find_related(FederatedUser)
.all(db)
.await
.map_err(|err| db_err(err, "fetching federated user data"))?;
if !federated_user.is_empty() {
common::get_federated_user_builder(&user, federated_user, user_opts?)
common::get_federated_user_builder(
&user,
federated_user,
user_opts.map_err(|err| db_err(err, "fetching user options"))?,
)
} else {
return Err(IdentityDatabaseError::MalformedUser(user_id.to_string()))?;
}
Expand Down
11 changes: 8 additions & 3 deletions src/identity/backends/sql/federated_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use sea_orm::query::*;

use crate::config::Config;
use crate::db::entity::{federated_user, prelude::FederatedUser};
use crate::identity::backends::error::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};

pub async fn create<A>(
_conf: &Config,
Expand All @@ -28,7 +28,11 @@ pub async fn create<A>(
where
A: Into<federated_user::ActiveModel>,
{
let db_user: federated_user::Model = federation.into().insert(db).await?;
let db_user: federated_user::Model = federation
.into()
.insert(db)
.await
.map_err(|err| db_err(err, "persisting federated user data"))?;

Ok(db_user)
}
Expand All @@ -44,7 +48,8 @@ pub async fn find_by_idp_and_unique_id<I: AsRef<str>, U: AsRef<str>>(
.filter(federated_user::Column::IdpId.eq(idp_id.as_ref()))
.filter(federated_user::Column::UniqueId.eq(unique_id.as_ref()))
.all(db)
.await?
.await
.map_err(|err| db_err(err, "searching federated user by the idp and unique id"))?
.first()
.cloned())
}
Expand Down
7 changes: 5 additions & 2 deletions src/identity/backends/sql/group/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use serde_json::json;

use crate::db::entity::group;
use crate::identity::Config;
use crate::identity::backends::sql::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};
use crate::identity::types::{Group, GroupCreate};

pub async fn create(
Expand All @@ -36,7 +36,10 @@ pub async fn create(
)?)),
};

let db_entry: group::Model = entry.insert(db).await?;
let db_entry: group::Model = entry
.insert(db)
.await
.map_err(|err| db_err(err, "persisting new group record"))?;

Ok(db_entry.into())
}
Expand Down
7 changes: 5 additions & 2 deletions src/identity/backends/sql/group/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ use sea_orm::entity::*;

use crate::db::entity::prelude::Group as DbGroup;
use crate::identity::Config;
use crate::identity::backends::sql::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};

pub async fn delete<S: AsRef<str>>(
_conf: &Config,
db: &DatabaseConnection,
group_id: S,
) -> Result<(), IdentityDatabaseError> {
let res = DbGroup::delete_by_id(group_id.as_ref()).exec(db).await?;
let res = DbGroup::delete_by_id(group_id.as_ref())
.exec(db)
.await
.map_err(|err| db_err(err, "removing group record"))?;
if res.rows_affected == 1 {
Ok(())
} else {
Expand Down
5 changes: 3 additions & 2 deletions src/identity/backends/sql/group/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use sea_orm::entity::*;

use crate::db::entity::prelude::Group as DbGroup;
use crate::identity::Config;
use crate::identity::backends::sql::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};
use crate::identity::types::Group;

pub async fn get<S: AsRef<str>>(
Expand All @@ -27,7 +27,8 @@ pub async fn get<S: AsRef<str>>(
) -> Result<Option<Group>, IdentityDatabaseError> {
Ok(DbGroup::find_by_id(group_id.as_ref())
.one(db)
.await?
.await
.map_err(|err| db_err(err, "fetching group data"))?
.map(Into::into))
}

Expand Down
7 changes: 5 additions & 2 deletions src/identity/backends/sql/group/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use sea_orm::query::*;

use crate::db::entity::{group, prelude::Group as DbGroup};
use crate::identity::Config;
use crate::identity::backends::sql::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};
use crate::identity::types::{Group, GroupListParameters};

pub async fn list(
Expand All @@ -36,7 +36,10 @@ pub async fn list(
group_select = group_select.filter(group::Column::Name.eq(name));
}

let db_groups: Vec<group::Model> = group_select.all(db).await?;
let db_groups: Vec<group::Model> = group_select
.all(db)
.await
.map_err(|err| db_err(err, "listing groups"))?;
let results: Vec<Group> = db_groups.into_iter().map(Into::into).collect();

Ok(results)
Expand Down
23 changes: 15 additions & 8 deletions src/identity/backends/sql/local_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::db::entity::{
local_user, password,
prelude::{LocalUser, Password},
};
use crate::identity::backends::error::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};
use crate::identity::types::UserCreate;

/// Load local user record with passwords from database
Expand Down Expand Up @@ -55,7 +55,8 @@ pub async fn load_local_user_with_passwords<S1: AsRef<str>, S2: AsRef<str>, S3:
.find_with_related(Password)
.order_by(password::Column::CreatedAtInt, Order::Desc)
.all(db)
.await?;
.await
.map_err(|err| db_err(err, "fetching user with passwords"))?;
Ok(results.first().cloned())
}

Expand All @@ -76,7 +77,8 @@ pub async fn load_local_users_passwords<L: IntoIterator<Item = Option<i32>>>(
.filter(password::Column::LocalUserId.is_in(keys.clone()))
.order_by(password::Column::CreatedAtInt, Order::Desc)
.all(db)
.await?;
.await
.map_err(|err| db_err(err, "fetching user passwords"))?;

// Prepare hashmap of passwords per local_user_id from requested users
let mut hashmap: HashMap<i32, Vec<password::Model>> =
Expand Down Expand Up @@ -126,7 +128,10 @@ pub async fn create(
entry.failed_auth_count = Set(Some(0));
}

let db_user: local_user::Model = entry.insert(db).await?;
let db_user: local_user::Model = entry
.insert(db)
.await
.map_err(|err| db_err(err, "inserting new user record"))?;

Ok(db_user)
}
Expand All @@ -137,20 +142,22 @@ pub async fn get_by_name_and_domain<N: AsRef<str>, D: AsRef<str>>(
name: N,
domain_id: D,
) -> Result<Option<local_user::Model>, IdentityDatabaseError> {
Ok(LocalUser::find()
LocalUser::find()
.filter(local_user::Column::Name.eq(name.as_ref()))
.filter(local_user::Column::DomainId.eq(domain_id.as_ref()))
.one(db)
.await?)
.await
.map_err(|err| db_err(err, "searching user by name and domain"))
}

pub async fn get_by_user_id<U: AsRef<str>>(
_conf: &Config,
db: &DatabaseConnection,
user_id: U,
) -> Result<Option<local_user::Model>, IdentityDatabaseError> {
Ok(LocalUser::find()
LocalUser::find()
.filter(local_user::Column::UserId.eq(user_id.as_ref()))
.one(db)
.await?)
.await
.map_err(|err| db_err(err, "fetching the user by ID"))
}
7 changes: 5 additions & 2 deletions src/identity/backends/sql/password.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use sea_orm::DatabaseConnection;
use sea_orm::entity::*;

use crate::db::entity::password;
use crate::identity::backends::error::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};

pub async fn create<S: AsRef<str>>(
db: &DatabaseConnection,
Expand All @@ -40,6 +40,9 @@ pub async fn create<S: AsRef<str>>(
entry.expires_at = Set(Some(expire.naive_utc()));
entry.expires_at_int = Set(Some(expire.timestamp_micros()));
}
let db_entry: password::Model = entry.insert(db).await?;
let db_entry: password::Model = entry
.insert(db)
.await
.map_err(|err| db_err(err, "inserting new password record"))?;
Ok(db_entry)
}
17 changes: 13 additions & 4 deletions src/identity/backends/sql/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ use serde_json::json;

use crate::config::Config;
use crate::db::entity::{prelude::User as DbUser, user};
use crate::identity::backends::error::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};
use crate::identity::types::UserCreate;

pub async fn get<U: AsRef<str>>(
db: &DatabaseConnection,
user_id: U,
) -> Result<Option<user::Model>, IdentityDatabaseError> {
Ok(DbUser::find_by_id(user_id.as_ref()).one(db).await?)
DbUser::find_by_id(user_id.as_ref())
.one(db)
.await
.map_err(|err| db_err(err, "fetching user by ID"))
}

pub(super) async fn create(
Expand Down Expand Up @@ -62,7 +65,10 @@ pub(super) async fn create(
created_at: Set(Some(now)),
domain_id: Set(user.domain_id.clone()),
};
let db_user: user::Model = entry.insert(db).await?;
let db_user: user::Model = entry
.insert(db)
.await
.map_err(|err| db_err(err, "inserting user entry"))?;
Ok(db_user)
}

Expand All @@ -71,7 +77,10 @@ pub async fn delete<U: AsRef<str>>(
db: &DatabaseConnection,
user_id: U,
) -> Result<(), IdentityDatabaseError> {
let res = DbUser::delete_by_id(user_id.as_ref()).exec(db).await?;
let res = DbUser::delete_by_id(user_id.as_ref())
.exec(db)
.await
.map_err(|err| db_err(err, "deleting the user record"))?;
if res.rows_affected == 1 {
Ok(())
} else {
Expand Down
7 changes: 4 additions & 3 deletions src/identity/backends/sql/user_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ use sea_orm::entity::*;
use sea_orm::query::*;

use crate::db::entity::{prelude::UserOption as DbUserOptions, user_option};
use crate::identity::backends::sql::IdentityDatabaseError;
use crate::identity::backends::sql::{IdentityDatabaseError, db_err};
use crate::identity::types::*;

pub async fn get<S: AsRef<str>>(
db: &DatabaseConnection,
user_id: S,
) -> Result<impl IntoIterator<Item = user_option::Model>, IdentityDatabaseError> {
Ok(DbUserOptions::find()
DbUserOptions::find()
.filter(user_option::Column::UserId.eq(user_id.as_ref()))
.all(db)
.await?)
.await
.map_err(|err| db_err(err, "fetching options of the user"))
}

impl FromIterator<user_option::Model> for UserOptions {
Expand Down
Loading