#ifndef USER_MANAGER_H #define USER_MANAGER_H #include #include #include #include #include #include #ifdef ENABLE_PAM_AUTH #include "pam_auth.h" #endif /** * @brief User information structure */ struct UserInfo { std::string id; ///< Unique user ID std::string username; ///< Username (unique) std::string email; ///< Email address std::string passwordHash; ///< Hashed password std::string role; ///< User role (admin, user, etc.) std::vector permissions; ///< User permissions std::vector apiKeys; ///< User's API keys bool active; ///< Account active status int64_t createdAt; ///< Account creation timestamp int64_t lastLoginAt; ///< Last login timestamp int64_t passwordChangedAt; ///< Password change timestamp std::string createdBy; ///< Who created this user }; /** * @brief API key information structure */ struct ApiKeyInfo { std::string keyId; ///< Unique key ID std::string keyHash; ///< Hashed API key std::string name; ///< Key name/description std::string userId; ///< Owner user ID std::vector permissions; ///< Key permissions bool active; ///< Key active status int64_t createdAt; ///< Key creation timestamp int64_t lastUsedAt; ///< Last used timestamp int64_t expiresAt; ///< Key expiration timestamp (0 = no expiration) std::string createdBy; ///< Who created this key }; /** * @brief Authentication result structure */ struct AuthResult { bool success; ///< Authentication success std::string userId; ///< User ID if successful std::string username; ///< Username if successful std::string role; ///< User role if successful std::vector permissions; ///< User permissions if successful std::string errorMessage; ///< Error message if failed std::string errorCode; ///< Error code for API responses }; /** * @brief User management system * * This class provides user authentication, authorization, and management * functionality for the stable-diffusion.cpp-rest server. It supports * local user storage, API key management, and role-based access control. */ class UserManager { public: /** * @brief Authentication methods enumeration */ enum class AuthMethod { PAM, ///< PAM authentication SHARED_KEY ///< Shared key authentication }; /** * @brief User roles enumeration */ enum class UserRole { GUEST, ///< Guest user (no authentication) USER, ///< Regular user ADMIN, ///< Administrator SERVICE ///< Service account }; /** * @brief Standard permissions */ struct Permissions { static const std::string READ; ///< Read access to models and status static const std::string GENERATE; ///< Generate images static const std::string QUEUE_MANAGE; ///< Manage generation queue static const std::string MODEL_MANAGE; ///< Load/unload models static const std::string USER_MANAGE; ///< Manage other users static const std::string ADMIN; ///< Full administrative access }; /** * @brief Construct a new User Manager object * * @param dataDir Directory for storing user data * @param authMethod Primary authentication method * @param defaultAdminUsername Default admin username * @param defaultAdminPassword Default admin password * @param defaultAdminEmail Default admin email */ explicit UserManager(const std::string& dataDir, AuthMethod authMethod = AuthMethod::PAM, const std::string& defaultAdminUsername = "admin", const std::string& defaultAdminPassword = "admin123", const std::string& defaultAdminEmail = "admin@localhost"); /** * @brief Destroy the User Manager object */ ~UserManager(); /** * @brief Initialize the user manager * * @return true if initialization successful, false otherwise */ bool initialize(); /** * @brief Shutdown the user manager */ void shutdown(); /** * @brief Authenticate user with username and password * * @param username Username * @param password Plain text password * @return AuthResult Authentication result */ AuthResult authenticateUser(const std::string& username, const std::string& password); /** * @brief authenticate user with Unix system * * @param username Unix username * @param password Unix password (used when PAM is enabled) * @return AuthResult Authentication result */ AuthResult authenticateUnix(const std::string& username, const std::string& password = ""); /** * @brief authenticate user with PAM * * @param username Username * @param password Plain text password * @return AuthResult Authentication result */ AuthResult authenticatePam(const std::string& username, const std::string& password); /** * @brief Authenticate with shared key * * @param sharedKey Shared key string * @return AuthResult Authentication result */ AuthResult authenticateSharedKey(const std::string& sharedKey); /** * @brief Create a new user * * @param username Username * @param password Plain text password * @param email Email address * @param role User role * @param createdBy User ID of creator * @return std::pair Success flag and user ID or error message */ std::pair createUser(const std::string& username, const std::string& password, const std::string& email, UserRole role = UserRole::USER, const std::string& createdBy = "system"); /** * @brief Update user information * * @param userId User ID * @param updates Map of fields to update * @return std::pair Success flag and message */ std::pair updateUser(const std::string& userId, const std::map& updates); /** * @brief Delete a user * * @param userId User ID to delete * @param requestingUserId User ID making the request * @return std::pair Success flag and message */ std::pair deleteUser(const std::string& userId, const std::string& requestingUserId); /** * @brief Change user password * * @param userId User ID * @param oldPassword Current password (can be empty for admin) * @param newPassword New password * @param requestingUserId User ID making the request * @return std::pair Success flag and message */ std::pair changePassword(const std::string& userId, const std::string& oldPassword, const std::string& newPassword, const std::string& requestingUserId); /** * @brief Get user information * * @param userId User ID * @return UserInfo User information, empty if not found */ UserInfo getUserInfo(const std::string& userId); /** * @brief Get user information by username * * @param username Username * @return UserInfo User information, empty if not found */ UserInfo getUserInfoByUsername(const std::string& username); /** * @brief List all users * * @param requestingUserId User ID making the request * @return std::vector List of users (limited for non-admins) */ std::vector listUsers(const std::string& requestingUserId); /** * @brief Create API key for user * * @param userId User ID * @param name Key name/description * @param permissions Key permissions * @param expiresAt Expiration timestamp (0 = no expiration) * @param createdBy User ID creating the key * @return std::pair Success flag and API key or error message */ std::pair createApiKey(const std::string& userId, const std::string& name, const std::vector& permissions, int64_t expiresAt = 0, const std::string& createdBy = "system"); /** * @brief Revoke API key * * @param keyId API key ID * @param requestingUserId User ID making the request * @return std::pair Success flag and message */ std::pair revokeApiKey(const std::string& keyId, const std::string& requestingUserId); /** * @brief List API keys for user * * @param userId User ID * @param requestingUserId User ID making the request * @return std::vector List of API keys */ std::vector listApiKeys(const std::string& userId, const std::string& requestingUserId); /** * @brief Get API key information * * @param keyId API key ID * @param requestingUserId User ID making the request * @return ApiKeyInfo API key information, empty if not found */ ApiKeyInfo getApiKeyInfo(const std::string& keyId, const std::string& requestingUserId); /** * @brief Update API key last used timestamp * * @param keyId API key ID */ void updateApiKeyLastUsed(const std::string& keyId); /** * @brief Check if user has permission * * @param userId User ID * @param permission Permission to check * @return true if user has permission, false otherwise */ bool hasPermission(const std::string& userId, const std::string& permission); /** * @brief Check if user has any of the specified permissions * * @param userId User ID * @param permissions List of permissions to check * @return true if user has any permission, false otherwise */ bool hasAnyPermission(const std::string& userId, const std::vector& permissions); /** * @brief Get user role as string * * @param role User role enum * @return std::string Role string */ static std::string roleToString(UserRole role); /** * @brief Parse role from string * * @param roleStr Role string * @return UserRole Role enum */ static UserRole stringToRole(const std::string& roleStr); /** * @brief Get default permissions for role * * @param role User role * @return std::vector List of permissions */ static std::vector getDefaultPermissions(UserRole role); /** * @brief Set authentication method * * @param method Authentication method */ void setAuthMethod(AuthMethod method); /** * @brief Get current authentication method * * @return AuthMethod Current authentication method */ AuthMethod getAuthMethod() const; /** * @brief Enable or disable PAM authentication * * @param enable Enable PAM authentication */ void setPamAuthEnabled(bool enable); /** * @brief Check if PAM authentication is enabled * * @return true if PAM authentication is enabled, false otherwise */ bool isPamAuthEnabled() const; /** * @brief Get user statistics * * @return std::map Statistics map */ std::map getStatistics(); private: std::string m_dataDir; ///< Data directory AuthMethod m_authMethod; ///< Current auth method bool m_pamAuthEnabled; ///< PAM auth enabled flag std::string m_defaultAdminUsername; ///< Default admin username std::string m_defaultAdminPassword; ///< Default admin password std::string m_defaultAdminEmail; ///< Default admin email std::map m_users; ///< User storage (username -> UserInfo) std::map m_apiKeys; ///< API key storage (keyId -> ApiKeyInfo) std::map m_apiKeyMap; ///< API key hash -> keyId mapping mutable std::mutex m_mutex; ///< Thread safety mutex #ifdef ENABLE_PAM_AUTH std::unique_ptr m_pamAuth; ///< PAM authentication instance #endif /** * @brief Hash password using bcrypt * * @param password Plain text password * @return std::string Hashed password */ std::string hashPassword(const std::string& password); /** * @brief Verify password against hash * * @param password Plain text password * @param hash Password hash * @return true if password matches, false otherwise */ bool verifyPassword(const std::string& password, const std::string& hash); /** * @brief Hash API key * * @param apiKey Plain text API key * @return std::string Hashed API key */ std::string hashApiKey(const std::string& apiKey); /** * @brief Generate unique user ID * * @return std::string Unique user ID */ std::string generateUserId(); /** * @brief Generate unique API key ID * * @return std::string Unique API key ID */ std::string generateKeyId(); /** * @brief Save user data to file * * @return true if successful, false otherwise */ bool saveUserData(); /** * @brief Load user data from file * * @return true if successful, false otherwise */ bool loadUserData(); /** * @brief Save API key data to file * * @return true if successful, false otherwise */ bool saveApiKeyData(); /** * @brief Load API key data from file * * @return true if successful, false otherwise */ bool loadApiKeyData(); /** * @brief Get current timestamp * * @return int64_t Current timestamp */ static int64_t getCurrentTimestamp(); /** * @brief Validate username format * * @param username Username to validate * @return true if valid, false otherwise */ static bool validateUsername(const std::string& username); /** * @brief Validate password strength * * @param password Password to validate * @return true if valid, false otherwise */ static bool validatePassword(const std::string& password); /** * @brief Validate email format * * @param email Email to validate * @return true if valid, false otherwise */ static bool validateEmail(const std::string& email); /** * @brief Check if user can manage target user * * @param requestingUserId User making request * @param targetUserId Target user * @return true if allowed, false otherwise */ bool canManageUser(const std::string& requestingUserId, const std::string& targetUserId); }; #endif // USER_MANAGER_H