feat(user): add given_name/family_name auth.users
reflect OIDC schema migration, User entity additions, and three defense-in-depth gaps closed, with all 280 unit tests and 13 Hurl files green infrastructure (lettre + EmailSender port). - Migration migrations/20260612000003_users_username_email_login.sql — adds nullable given_name/family_name columns to auth.users. - User entity (src/domain/entities/user.rs) — has_login_credential() placeholder-check encapsulation, set_username revalidating setter, given/family-name fields + getters/setters, validate_username widened 32→254 and now accepts email shape. from_data_full extended with two new params; all 7 callsites in user_pg_repository.rs updated. - Schema-side legacy guards (src/application/services/auth_application_service.rs) — bumped the duplicated 32-char check in setup_create_admin and admin_create_user to 254 to match. - Gap #1 (subject_group_service.rs) — add_member now rejects external candidates with an audit-logged AccessDenied. Service gained an Arc<UserPgRepository> field, wired through DI. New integration test test_external_user_cannot_be_added_as_member. - Gap #2 (user_repository.rs + auth_ports.rs + user_pg_repository.rs) — list_users/search_users gained an include_external: bool param defaulting effectively to false everywhere internal-user-facing. auth_application_service exposes a new list_users_including_external for the admin surface. - Gap #3 (pg_acl_engine.rs) — expand_user now SELECTs is_external and skips INTERNAL_GROUP_ID for externals; defaults to is_external=true on missing user to fail closed.
This commit is contained in:
@@ -67,11 +67,28 @@ pub trait UserRepository: Send + Sync + 'static {
|
||||
/// Updates the last login date
|
||||
async fn update_last_login(&self, user_id: Uuid) -> UserRepositoryResult<()>;
|
||||
|
||||
/// Lists users with pagination
|
||||
async fn list_users(&self, limit: i64, offset: i64) -> UserRepositoryResult<Vec<User>>;
|
||||
/// Lists users with pagination.
|
||||
///
|
||||
/// `include_external` controls whether external (grant-only) users
|
||||
/// appear in the result. Default callers should pass `false` so
|
||||
/// external users stay invisible to internal-user surfaces (system
|
||||
/// address book autocomplete, sharee search, etc.). Only the admin
|
||||
/// management UI should request `true`.
|
||||
async fn list_users(
|
||||
&self,
|
||||
limit: i64,
|
||||
offset: i64,
|
||||
include_external: bool,
|
||||
) -> UserRepositoryResult<Vec<User>>;
|
||||
|
||||
/// Searches users by username or email (SQL ILIKE) with a limit.
|
||||
async fn search_users(&self, query: &str, limit: i64) -> UserRepositoryResult<Vec<User>>;
|
||||
/// See [`list_users`] for the meaning of `include_external`.
|
||||
async fn search_users(
|
||||
&self,
|
||||
query: &str,
|
||||
limit: i64,
|
||||
include_external: bool,
|
||||
) -> UserRepositoryResult<Vec<User>>;
|
||||
|
||||
/// Activates or deactivates a user
|
||||
async fn set_user_active_status(&self, user_id: Uuid, active: bool)
|
||||
|
||||
Reference in New Issue
Block a user