| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- #ifndef USER_MANAGER_H
- #define USER_MANAGER_H
- #include <string>
- #include <vector>
- #include <map>
- #include <memory>
- #include <mutex>
- #include <functional>
- #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<std::string> permissions; ///< User permissions
- std::vector<std::string> 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<std::string> 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<std::string> 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 {
- NONE, ///< No authentication required
- JWT, ///< JWT token authentication
- API_KEY, ///< API key authentication
- UNIX, ///< Unix system authentication
- PAM, ///< PAM authentication
- OPTIONAL ///< Authentication optional (guest access allowed)
- };
- /**
- * @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 enableUnixAuth Enable Unix authentication
- */
- explicit UserManager(const std::string& dataDir,
- AuthMethod authMethod = AuthMethod::JWT);
- /**
- * @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 API key
- *
- * @param apiKey API key string
- * @return AuthResult Authentication result
- */
- AuthResult authenticateApiKey(const std::string& apiKey);
- /**
- * @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<bool, std::string> Success flag and user ID or error message
- */
- std::pair<bool, std::string> 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<bool, std::string> Success flag and message
- */
- std::pair<bool, std::string> updateUser(const std::string& userId,
- const std::map<std::string, std::string>& updates);
- /**
- * @brief Delete a user
- *
- * @param userId User ID to delete
- * @param requestingUserId User ID making the request
- * @return std::pair<bool, std::string> Success flag and message
- */
- std::pair<bool, std::string> 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<bool, std::string> Success flag and message
- */
- std::pair<bool, std::string> 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<UserInfo> List of users (limited for non-admins)
- */
- std::vector<UserInfo> 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<bool, std::string> Success flag and API key or error message
- */
- std::pair<bool, std::string> createApiKey(const std::string& userId,
- const std::string& name,
- const std::vector<std::string>& 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<bool, std::string> Success flag and message
- */
- std::pair<bool, std::string> 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<ApiKeyInfo> List of API keys
- */
- std::vector<ApiKeyInfo> 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<std::string>& 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<std::string> List of permissions
- */
- static std::vector<std::string> 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<std::string, int> Statistics map
- */
- std::map<std::string, int> getStatistics();
- private:
- std::string m_dataDir; ///< Data directory
- AuthMethod m_authMethod; ///< Current auth method
- bool m_pamAuthEnabled; ///< PAM auth enabled flag
- std::map<std::string, UserInfo> m_users; ///< User storage (username -> UserInfo)
- std::map<std::string, ApiKeyInfo> m_apiKeys; ///< API key storage (keyId -> ApiKeyInfo)
- std::map<std::string, std::string> m_apiKeyMap; ///< API key hash -> keyId mapping
- mutable std::mutex m_mutex; ///< Thread safety mutex
- #ifdef ENABLE_PAM_AUTH
- std::unique_ptr<PamAuth> 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
|