feat(v1.1.8): UsersService trait + impl — CRUD + login/verify/logout

UsersService trait in shared::users + Postgres-backed impl in
manager-core::users_service. Wired into the Services bundle (new
`users` field) and the picloud binary's startup.

Commit 4 ships:

  * CRUD: create / get / find_by_email / update / delete / list
    (cursor-paged on created_at). create validates email shape,
    8-char password minimum, optional display_name; throws
    DuplicateEmail on (app_id, lower(email)) collision.
  * Auth: login (timing-flat — runs verify_password against the
    shared dummy Argon2id PHC even on email miss, so the
    bad-email and good-email branches share wall-clock cost);
    verify (sliding TTL bump capped at absolute_expires_at);
    logout (revoke by token).
  * verify_session_for_realtime — non-SDK method taking app_id
    explicitly; used by the F3 realtime auth_mode='session' path
    in a later commit.
  * Cross-app isolation everywhere: cx.app_id (or explicit app_id)
    is the only source of truth; a logout for a foreign-app token
    is a silent no-op rather than a probe of session existence.

Email-tied flows (verification, password reset, invitations), roles,
and admin-mediated helpers are stubbed UsersError::Backend and ship
in later commits in this series.

Config (UsersServiceConfig) sources from env with documented
defaults:
  PICLOUD_APP_USER_SESSION_TTL_HOURS         (24)
  PICLOUD_APP_USER_SESSION_ABSOLUTE_HOURS    (720 = 30d)
  PICLOUD_APP_USER_VERIFICATION_TTL_HOURS    (48)
  PICLOUD_APP_USER_PASSWORD_RESET_TTL_HOURS  (1)
  PICLOUD_APP_USER_INVITATION_TTL_DAYS       (7)

Reserved a TIMING_FLAT_DUMMY_HASH constant on manager-core::auth so
the dummy PHC is one shared definition.

Added AppUserId + InvitationId id types in picloud-shared.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-06 11:57:06 +02:00
parent 7a44cbf5a4
commit c6bf8d3de5
6 changed files with 1198 additions and 10 deletions

View File

@@ -19,6 +19,7 @@ pub mod app_repo;
pub mod app_secrets_repo;
pub mod app_user_repo;
pub mod app_user_session_repo;
pub mod users_service;
pub mod apps_api;
pub mod auth;
pub mod auth_api;
@@ -86,6 +87,7 @@ pub use app_user_session_repo::{
AppUserSessionLookup, AppUserSessionRepository, AppUserSessionRepositoryError,
PostgresAppUserSessionRepository,
};
pub use users_service::{UsersServiceConfig, UsersServiceImpl};
pub use admin_users_api::{admins_router, AdminsState};
pub use api::{admin_router, AdminState};
pub use api_key_repo::{