user_manager.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. #include "user_manager.h"
  2. #include "jwt_auth.h"
  3. #include <nlohmann/json.hpp>
  4. #include <fstream>
  5. #include <filesystem>
  6. #include <sstream>
  7. #include <iomanip>
  8. #include <algorithm>
  9. #include <regex>
  10. #include <crypt.h>
  11. #include <unistd.h>
  12. #include <pwd.h>
  13. #include <shadow.h>
  14. #include <sys/types.h>
  15. #include <openssl/sha.h>
  16. // Define static permission constants
  17. const std::string UserManager::Permissions::READ = "read";
  18. const std::string UserManager::Permissions::GENERATE = "generate";
  19. const std::string UserManager::Permissions::QUEUE_MANAGE = "queue_manage";
  20. const std::string UserManager::Permissions::MODEL_MANAGE = "model_manage";
  21. const std::string UserManager::Permissions::USER_MANAGE = "user_manage";
  22. const std::string UserManager::Permissions::ADMIN = "admin";
  23. UserManager::UserManager(const std::string& dataDir,
  24. AuthMethod authMethod)
  25. : m_dataDir(dataDir)
  26. , m_authMethod(authMethod)
  27. , m_pamAuthEnabled(false)
  28. {
  29. #ifdef ENABLE_PAM_AUTH
  30. m_pamAuth = std::make_unique<PamAuth>();
  31. #endif
  32. }
  33. UserManager::~UserManager() {
  34. shutdown();
  35. }
  36. bool UserManager::initialize() {
  37. try {
  38. // Create data directory if it doesn't exist
  39. std::filesystem::create_directories(m_dataDir);
  40. // Load existing user data
  41. if (!loadUserData()) {
  42. // Create default admin user if no users exist
  43. if (m_users.empty()) {
  44. auto [success, adminId] = createUser("admin", "admin123", "admin@localhost", UserRole::ADMIN, "system");
  45. if (!success) {
  46. return false;
  47. }
  48. }
  49. }
  50. // Load existing API key data
  51. loadApiKeyData();
  52. return true;
  53. } catch (const std::exception& e) {
  54. return false;
  55. }
  56. }
  57. void UserManager::shutdown() {
  58. // Save data before shutdown
  59. saveUserData();
  60. saveApiKeyData();
  61. }
  62. AuthResult UserManager::authenticateUser(const std::string& username, const std::string& password) {
  63. AuthResult result;
  64. result.success = false;
  65. try {
  66. // Find user by username
  67. auto it = m_users.find(username);
  68. if (it == m_users.end()) {
  69. result.errorMessage = "User not found";
  70. result.errorCode = "USER_NOT_FOUND";
  71. return result;
  72. }
  73. const UserInfo& user = it->second;
  74. // Check if user is active
  75. if (!user.active) {
  76. result.errorMessage = "User account is disabled";
  77. result.errorCode = "ACCOUNT_DISABLED";
  78. return result;
  79. }
  80. // Verify password
  81. if (!verifyPassword(password, user.passwordHash)) {
  82. result.errorMessage = "Invalid password";
  83. result.errorCode = "INVALID_PASSWORD";
  84. return result;
  85. }
  86. // Authentication successful
  87. result.success = true;
  88. result.userId = user.id;
  89. result.username = user.username;
  90. result.role = user.role;
  91. result.permissions = user.permissions;
  92. // Update last login time
  93. m_users[username].lastLoginAt = getCurrentTimestamp();
  94. saveUserData();
  95. } catch (const std::exception& e) {
  96. result.errorMessage = "Authentication failed: " + std::string(e.what());
  97. result.errorCode = "AUTH_ERROR";
  98. }
  99. return result;
  100. }
  101. AuthResult UserManager::authenticateUnix(const std::string& username, const std::string& password) {
  102. AuthResult result;
  103. result.success = false;
  104. // Check if Unix authentication is the configured method
  105. if (m_authMethod != AuthMethod::UNIX) {
  106. result.errorMessage = "Unix authentication is not enabled";
  107. result.errorCode = "UNIX_AUTH_DISABLED";
  108. return result;
  109. }
  110. try {
  111. // If PAM is enabled, delegate to PAM authentication
  112. if (m_pamAuthEnabled) {
  113. return authenticatePam(username, password);
  114. }
  115. // Traditional Unix auth without PAM - just check if user exists
  116. // This is a fallback for when PAM is not available
  117. struct passwd* pw = getpwnam(username.c_str());
  118. if (!pw) {
  119. result.errorMessage = "Unix user not found";
  120. result.errorCode = "UNIX_USER_NOT_FOUND";
  121. return result;
  122. }
  123. // Check if user exists in our system or create guest user
  124. UserInfo user;
  125. auto it = m_users.find(username);
  126. if (it != m_users.end()) {
  127. user = it->second;
  128. } else {
  129. // Create guest user for Unix authentication
  130. user.id = generateUserId();
  131. user.username = username;
  132. user.email = username + "@localhost";
  133. user.role = roleToString(UserRole::USER);
  134. user.permissions = getDefaultPermissions(UserRole::USER);
  135. user.active = true;
  136. user.createdAt = getCurrentTimestamp();
  137. user.createdBy = "system";
  138. m_users[username] = user;
  139. saveUserData();
  140. }
  141. // Authentication successful
  142. result.success = true;
  143. result.userId = user.id;
  144. result.username = user.username;
  145. result.role = user.role;
  146. result.permissions = user.permissions;
  147. } catch (const std::exception& e) {
  148. result.errorMessage = "Unix authentication failed: " + std::string(e.what());
  149. result.errorCode = "UNIX_AUTH_ERROR";
  150. }
  151. return result;
  152. }
  153. AuthResult UserManager::authenticatePam(const std::string& username, const std::string& password) {
  154. AuthResult result;
  155. result.success = false;
  156. // Check if PAM authentication is the configured method
  157. if (m_authMethod != AuthMethod::PAM) {
  158. result.errorMessage = "PAM authentication is not enabled";
  159. result.errorCode = "PAM_AUTH_DISABLED";
  160. return result;
  161. }
  162. #ifdef ENABLE_PAM_AUTH
  163. if (!m_pamAuth || !m_pamAuth->isAvailable()) {
  164. result.errorMessage = "PAM authentication not available";
  165. result.errorCode = "PAM_AUTH_UNAVAILABLE";
  166. return result;
  167. }
  168. try {
  169. // Authenticate with PAM
  170. PamAuthResult pamResult = m_pamAuth->authenticate(username, password);
  171. if (!pamResult.success) {
  172. result.errorMessage = pamResult.errorMessage;
  173. result.errorCode = pamResult.errorCode;
  174. return result;
  175. }
  176. // Check if user exists in our system or create guest user
  177. UserInfo user;
  178. auto it = m_users.find(username);
  179. if (it != m_users.end()) {
  180. user = it->second;
  181. } else {
  182. // Create guest user for PAM authentication
  183. user.id = generateUserId();
  184. user.username = username;
  185. user.email = username + "@localhost";
  186. user.role = roleToString(UserRole::USER);
  187. user.permissions = getDefaultPermissions(UserRole::USER);
  188. user.active = true;
  189. user.createdAt = getCurrentTimestamp();
  190. user.createdBy = "system";
  191. m_users[username] = user;
  192. saveUserData();
  193. }
  194. // Authentication successful
  195. result.success = true;
  196. result.userId = user.id;
  197. result.username = user.username;
  198. result.role = user.role;
  199. result.permissions = user.permissions;
  200. } catch (const std::exception& e) {
  201. result.errorMessage = "PAM authentication failed: " + std::string(e.what());
  202. result.errorCode = "PAM_AUTH_ERROR";
  203. }
  204. #else
  205. result.errorMessage = "PAM authentication not available (compiled without PAM support)";
  206. result.errorCode = "PAM_NOT_AVAILABLE";
  207. #endif
  208. return result;
  209. }
  210. AuthResult UserManager::authenticateApiKey(const std::string& apiKey) {
  211. AuthResult result;
  212. result.success = false;
  213. try {
  214. // Hash the API key to compare with stored hashes
  215. std::string keyHash = hashApiKey(apiKey);
  216. auto it = m_apiKeyMap.find(keyHash);
  217. if (it == m_apiKeyMap.end()) {
  218. result.errorMessage = "Invalid API key";
  219. result.errorCode = "INVALID_API_KEY";
  220. return result;
  221. }
  222. const std::string& keyId = it->second;
  223. const ApiKeyInfo& keyInfo = m_apiKeys[keyId];
  224. // Check if key is active
  225. if (!keyInfo.active) {
  226. result.errorMessage = "API key is disabled";
  227. result.errorCode = "API_KEY_DISABLED";
  228. return result;
  229. }
  230. // Check expiration
  231. if (keyInfo.expiresAt > 0 && getCurrentTimestamp() >= keyInfo.expiresAt) {
  232. result.errorMessage = "API key has expired";
  233. result.errorCode = "API_KEY_EXPIRED";
  234. return result;
  235. }
  236. // Get user information
  237. auto userIt = m_users.find(keyInfo.userId);
  238. if (userIt == m_users.end()) {
  239. result.errorMessage = "API key owner not found";
  240. result.errorCode = "USER_NOT_FOUND";
  241. return result;
  242. }
  243. const UserInfo& user = userIt->second;
  244. if (!user.active) {
  245. result.errorMessage = "API key owner account is disabled";
  246. result.errorCode = "ACCOUNT_DISABLED";
  247. return result;
  248. }
  249. // Authentication successful
  250. result.success = true;
  251. result.userId = user.id;
  252. result.username = user.username;
  253. result.role = user.role;
  254. result.permissions = keyInfo.permissions.empty() ? user.permissions : keyInfo.permissions;
  255. // Update last used timestamp
  256. m_apiKeys[keyId].lastUsedAt = getCurrentTimestamp();
  257. saveApiKeyData();
  258. } catch (const std::exception& e) {
  259. result.errorMessage = "API key authentication failed: " + std::string(e.what());
  260. result.errorCode = "API_KEY_AUTH_ERROR";
  261. }
  262. return result;
  263. }
  264. std::pair<bool, std::string> UserManager::createUser(const std::string& username,
  265. const std::string& password,
  266. const std::string& email,
  267. UserRole role,
  268. const std::string& createdBy) {
  269. try {
  270. // Validate inputs
  271. if (!validateUsername(username)) {
  272. return {false, "Invalid username format"};
  273. }
  274. if (!validatePassword(password)) {
  275. return {false, "Password does not meet requirements"};
  276. }
  277. if (!validateEmail(email)) {
  278. return {false, "Invalid email format"};
  279. }
  280. // Check if user already exists
  281. if (m_users.find(username) != m_users.end()) {
  282. return {false, "User already exists"};
  283. }
  284. // Create user
  285. UserInfo user;
  286. user.id = generateUserId();
  287. user.username = username;
  288. user.email = email;
  289. user.passwordHash = hashPassword(password);
  290. user.role = roleToString(role);
  291. user.permissions = getDefaultPermissions(role);
  292. user.active = true;
  293. user.createdAt = getCurrentTimestamp();
  294. user.passwordChangedAt = getCurrentTimestamp();
  295. user.createdBy = createdBy;
  296. m_users[username] = user;
  297. saveUserData();
  298. return {true, user.id};
  299. } catch (const std::exception& e) {
  300. return {false, "Failed to create user: " + std::string(e.what())};
  301. }
  302. }
  303. std::pair<bool, std::string> UserManager::updateUser(const std::string& userId,
  304. const std::map<std::string, std::string>& updates) {
  305. try {
  306. // Find user by ID
  307. std::string username;
  308. for (const auto& pair : m_users) {
  309. if (pair.second.id == userId) {
  310. username = pair.first;
  311. break;
  312. }
  313. }
  314. if (username.empty()) {
  315. return {false, "User not found"};
  316. }
  317. UserInfo& user = m_users[username];
  318. // Update allowed fields
  319. for (const auto& update : updates) {
  320. const std::string& field = update.first;
  321. const std::string& value = update.second;
  322. if (field == "email") {
  323. if (!validateEmail(value)) {
  324. return {false, "Invalid email format"};
  325. }
  326. user.email = value;
  327. } else if (field == "role") {
  328. user.role = value;
  329. user.permissions = getDefaultPermissions(stringToRole(value));
  330. } else if (field == "active") {
  331. user.active = (value == "true" || value == "1");
  332. }
  333. }
  334. saveUserData();
  335. return {true, "User updated successfully"};
  336. } catch (const std::exception& e) {
  337. return {false, "Failed to update user: " + std::string(e.what())};
  338. }
  339. }
  340. std::pair<bool, std::string> UserManager::deleteUser(const std::string& userId,
  341. const std::string& requestingUserId) {
  342. try {
  343. // Find user by ID
  344. std::string username;
  345. for (const auto& pair : m_users) {
  346. if (pair.second.id == userId) {
  347. username = pair.first;
  348. break;
  349. }
  350. }
  351. if (username.empty()) {
  352. return {false, "User not found"};
  353. }
  354. // Check permissions
  355. if (!canManageUser(requestingUserId, userId)) {
  356. return {false, "Insufficient permissions to delete user"};
  357. }
  358. // Delete user's API keys
  359. auto it = m_apiKeys.begin();
  360. while (it != m_apiKeys.end()) {
  361. if (it->second.userId == userId) {
  362. m_apiKeyMap.erase(it->second.keyHash);
  363. it = m_apiKeys.erase(it);
  364. } else {
  365. ++it;
  366. }
  367. }
  368. // Delete user
  369. m_users.erase(username);
  370. saveUserData();
  371. saveApiKeyData();
  372. return {true, "User deleted successfully"};
  373. } catch (const std::exception& e) {
  374. return {false, "Failed to delete user: " + std::string(e.what())};
  375. }
  376. }
  377. std::pair<bool, std::string> UserManager::changePassword(const std::string& userId,
  378. const std::string& oldPassword,
  379. const std::string& newPassword,
  380. const std::string& requestingUserId) {
  381. try {
  382. // Find user by ID
  383. std::string username;
  384. for (const auto& pair : m_users) {
  385. if (pair.second.id == userId) {
  386. username = pair.first;
  387. break;
  388. }
  389. }
  390. if (username.empty()) {
  391. return {false, "User not found"};
  392. }
  393. UserInfo& user = m_users[username];
  394. // Check permissions (admin can change without old password)
  395. if (requestingUserId != userId) {
  396. if (!canManageUser(requestingUserId, userId)) {
  397. return {false, "Insufficient permissions to change password"};
  398. }
  399. } else {
  400. // User changing own password - verify old password
  401. if (!verifyPassword(oldPassword, user.passwordHash)) {
  402. return {false, "Current password is incorrect"};
  403. }
  404. }
  405. // Validate new password
  406. if (!validatePassword(newPassword)) {
  407. return {false, "New password does not meet requirements"};
  408. }
  409. // Update password
  410. user.passwordHash = hashPassword(newPassword);
  411. user.passwordChangedAt = getCurrentTimestamp();
  412. saveUserData();
  413. return {true, "Password changed successfully"};
  414. } catch (const std::exception& e) {
  415. return {false, "Failed to change password: " + std::string(e.what())};
  416. }
  417. }
  418. UserInfo UserManager::getUserInfo(const std::string& userId) {
  419. for (const auto& pair : m_users) {
  420. if (pair.second.id == userId) {
  421. return pair.second;
  422. }
  423. }
  424. return UserInfo{};
  425. }
  426. UserInfo UserManager::getUserInfoByUsername(const std::string& username) {
  427. auto it = m_users.find(username);
  428. if (it != m_users.end()) {
  429. return it->second;
  430. }
  431. return UserInfo{};
  432. }
  433. std::vector<UserInfo> UserManager::listUsers(const std::string& requestingUserId) {
  434. std::vector<UserInfo> users;
  435. // Check if requester is admin
  436. UserInfo requester = getUserInfo(requestingUserId);
  437. bool isAdmin = (requester.role == roleToString(UserRole::ADMIN));
  438. for (const auto& pair : m_users) {
  439. const UserInfo& user = pair.second;
  440. // Non-admins can only see themselves
  441. if (!isAdmin && user.id != requestingUserId) {
  442. continue;
  443. }
  444. // Don't include sensitive information for non-admins
  445. UserInfo userInfo = user;
  446. if (!isAdmin) {
  447. userInfo.passwordHash = "";
  448. userInfo.apiKeys.clear();
  449. }
  450. users.push_back(userInfo);
  451. }
  452. return users;
  453. }
  454. std::pair<bool, std::string> UserManager::createApiKey(const std::string& userId,
  455. const std::string& name,
  456. const std::vector<std::string>& permissions,
  457. int64_t expiresAt,
  458. const std::string& createdBy) {
  459. try {
  460. // Check if user exists
  461. bool userExists = false;
  462. for (const auto& pair : m_users) {
  463. if (pair.second.id == userId) {
  464. userExists = true;
  465. break;
  466. }
  467. }
  468. if (!userExists) {
  469. return {false, "User not found"};
  470. }
  471. // Generate API key
  472. std::string apiKey = JWTAuth::generateApiKey(32);
  473. std::string keyId = generateKeyId();
  474. std::string keyHash = hashApiKey(apiKey);
  475. // Create API key info
  476. ApiKeyInfo keyInfo;
  477. keyInfo.keyId = keyId;
  478. keyInfo.keyHash = keyHash;
  479. keyInfo.name = name;
  480. keyInfo.userId = userId;
  481. keyInfo.permissions = permissions;
  482. keyInfo.active = true;
  483. keyInfo.createdAt = getCurrentTimestamp();
  484. keyInfo.lastUsedAt = 0;
  485. keyInfo.expiresAt = expiresAt;
  486. keyInfo.createdBy = createdBy;
  487. m_apiKeys[keyId] = keyInfo;
  488. m_apiKeyMap[keyHash] = keyId;
  489. saveApiKeyData();
  490. return {true, apiKey};
  491. } catch (const std::exception& e) {
  492. return {false, "Failed to create API key: " + std::string(e.what())};
  493. }
  494. }
  495. std::pair<bool, std::string> UserManager::revokeApiKey(const std::string& keyId,
  496. const std::string& requestingUserId) {
  497. try {
  498. auto it = m_apiKeys.find(keyId);
  499. if (it == m_apiKeys.end()) {
  500. return {false, "API key not found"};
  501. }
  502. const ApiKeyInfo& keyInfo = it->second;
  503. // Check permissions
  504. if (keyInfo.userId != requestingUserId) {
  505. if (!canManageUser(requestingUserId, keyInfo.userId)) {
  506. return {false, "Insufficient permissions to revoke API key"};
  507. }
  508. }
  509. // Remove API key
  510. m_apiKeyMap.erase(keyInfo.keyHash);
  511. m_apiKeys.erase(it);
  512. saveApiKeyData();
  513. return {true, "API key revoked successfully"};
  514. } catch (const std::exception& e) {
  515. return {false, "Failed to revoke API key: " + std::string(e.what())};
  516. }
  517. }
  518. std::vector<ApiKeyInfo> UserManager::listApiKeys(const std::string& userId,
  519. const std::string& requestingUserId) {
  520. std::vector<ApiKeyInfo> apiKeys;
  521. // Check if requester is admin or owner
  522. UserInfo requester = getUserInfo(requestingUserId);
  523. bool isAdmin = (requester.role == roleToString(UserRole::ADMIN));
  524. bool isOwner = (requestingUserId == userId);
  525. for (const auto& pair : m_apiKeys) {
  526. const ApiKeyInfo& keyInfo = pair.second;
  527. // Filter by user ID if specified
  528. if (!userId.empty() && keyInfo.userId != userId) {
  529. continue;
  530. }
  531. // Check permissions
  532. if (!isAdmin && keyInfo.userId != requestingUserId) {
  533. continue;
  534. }
  535. // Don't include hash for non-owners
  536. ApiKeyInfo keyInfoCopy = keyInfo;
  537. if (!isOwner && !isAdmin) {
  538. keyInfoCopy.keyHash = "";
  539. }
  540. apiKeys.push_back(keyInfoCopy);
  541. }
  542. return apiKeys;
  543. }
  544. ApiKeyInfo UserManager::getApiKeyInfo(const std::string& keyId,
  545. const std::string& requestingUserId) {
  546. auto it = m_apiKeys.find(keyId);
  547. if (it == m_apiKeys.end()) {
  548. return ApiKeyInfo{};
  549. }
  550. const ApiKeyInfo& keyInfo = it->second;
  551. // Check permissions
  552. UserInfo requester = getUserInfo(requestingUserId);
  553. bool isAdmin = (requester.role == roleToString(UserRole::ADMIN));
  554. bool isOwner = (keyInfo.userId == requestingUserId);
  555. if (!isAdmin && !isOwner) {
  556. return ApiKeyInfo{};
  557. }
  558. // Don't include hash for non-owners
  559. ApiKeyInfo keyInfoCopy = keyInfo;
  560. if (!isOwner) {
  561. keyInfoCopy.keyHash = "";
  562. }
  563. return keyInfoCopy;
  564. }
  565. void UserManager::updateApiKeyLastUsed(const std::string& keyId) {
  566. auto it = m_apiKeys.find(keyId);
  567. if (it != m_apiKeys.end()) {
  568. it->second.lastUsedAt = getCurrentTimestamp();
  569. saveApiKeyData();
  570. }
  571. }
  572. bool UserManager::hasPermission(const std::string& userId, const std::string& permission) {
  573. UserInfo user = getUserInfo(userId);
  574. if (user.id.empty()) {
  575. return false;
  576. }
  577. return JWTAuth::hasPermission(user.permissions, permission);
  578. }
  579. bool UserManager::hasAnyPermission(const std::string& userId,
  580. const std::vector<std::string>& permissions) {
  581. UserInfo user = getUserInfo(userId);
  582. if (user.id.empty()) {
  583. return false;
  584. }
  585. return JWTAuth::hasAnyPermission(user.permissions, permissions);
  586. }
  587. std::string UserManager::roleToString(UserRole role) {
  588. switch (role) {
  589. case UserRole::GUEST: return "guest";
  590. case UserRole::USER: return "user";
  591. case UserRole::ADMIN: return "admin";
  592. case UserRole::SERVICE: return "service";
  593. default: return "unknown";
  594. }
  595. }
  596. UserManager::UserRole UserManager::stringToRole(const std::string& roleStr) {
  597. if (roleStr == "guest") return UserRole::GUEST;
  598. if (roleStr == "user") return UserRole::USER;
  599. if (roleStr == "admin") return UserRole::ADMIN;
  600. if (roleStr == "service") return UserRole::SERVICE;
  601. return UserRole::USER; // Default
  602. }
  603. std::vector<std::string> UserManager::getDefaultPermissions(UserRole role) {
  604. switch (role) {
  605. case UserRole::GUEST:
  606. return {Permissions::READ};
  607. case UserRole::USER:
  608. return {Permissions::READ, Permissions::GENERATE};
  609. case UserRole::ADMIN:
  610. return {Permissions::READ, Permissions::GENERATE, Permissions::QUEUE_MANAGE,
  611. Permissions::MODEL_MANAGE, Permissions::USER_MANAGE, Permissions::ADMIN};
  612. case UserRole::SERVICE:
  613. return {Permissions::READ, Permissions::GENERATE, Permissions::QUEUE_MANAGE};
  614. default:
  615. return {};
  616. }
  617. }
  618. void UserManager::setAuthMethod(AuthMethod method) {
  619. m_authMethod = method;
  620. }
  621. UserManager::AuthMethod UserManager::getAuthMethod() const {
  622. return m_authMethod;
  623. }
  624. void UserManager::setPamAuthEnabled(bool enable) {
  625. m_pamAuthEnabled = enable;
  626. #ifdef ENABLE_PAM_AUTH
  627. if (enable && m_pamAuth && !m_pamAuth->isAvailable()) {
  628. if (!m_pamAuth->initialize()) {
  629. m_pamAuthEnabled = false;
  630. }
  631. }
  632. #endif
  633. }
  634. bool UserManager::isPamAuthEnabled() const {
  635. return m_pamAuthEnabled;
  636. }
  637. std::map<std::string, int> UserManager::getStatistics() {
  638. std::map<std::string, int> stats;
  639. stats["total_users"] = m_users.size();
  640. stats["active_users"] = 0;
  641. stats["admin_users"] = 0;
  642. stats["total_api_keys"] = m_apiKeys.size();
  643. stats["active_api_keys"] = 0;
  644. stats["expired_api_keys"] = 0;
  645. int64_t currentTime = getCurrentTimestamp();
  646. for (const auto& pair : m_users) {
  647. const UserInfo& user = pair.second;
  648. if (user.active) {
  649. stats["active_users"]++;
  650. }
  651. if (user.role == roleToString(UserRole::ADMIN)) {
  652. stats["admin_users"]++;
  653. }
  654. }
  655. for (const auto& pair : m_apiKeys) {
  656. const ApiKeyInfo& keyInfo = pair.second;
  657. if (keyInfo.active) {
  658. stats["active_api_keys"]++;
  659. }
  660. if (keyInfo.expiresAt > 0 && currentTime >= keyInfo.expiresAt) {
  661. stats["expired_api_keys"]++;
  662. }
  663. }
  664. return stats;
  665. }
  666. std::string UserManager::hashPassword(const std::string& password) {
  667. // Simple SHA256 hash for now (in production, use proper password hashing like bcrypt/argon2)
  668. unsigned char hash[SHA256_DIGEST_LENGTH];
  669. SHA256((unsigned char*)password.c_str(), password.length(), hash);
  670. std::stringstream ss;
  671. for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
  672. ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
  673. }
  674. return "sha256:" + ss.str();
  675. }
  676. bool UserManager::verifyPassword(const std::string& password, const std::string& storedHash) {
  677. // Simple SHA256 verification (in production, use proper password hashing)
  678. if (storedHash.substr(0, 7) != "sha256:") {
  679. return false;
  680. }
  681. unsigned char hash[SHA256_DIGEST_LENGTH];
  682. SHA256((unsigned char*)password.c_str(), password.length(), hash);
  683. std::stringstream ss;
  684. for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
  685. ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
  686. }
  687. return "sha256:" + ss.str() == storedHash;
  688. }
  689. std::string UserManager::hashApiKey(const std::string& apiKey) {
  690. // Use SHA256 for API key hashing
  691. unsigned char hash[SHA256_DIGEST_LENGTH];
  692. SHA256((unsigned char*)apiKey.c_str(), apiKey.length(), hash);
  693. std::stringstream ss;
  694. for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
  695. ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
  696. }
  697. return ss.str();
  698. }
  699. std::string UserManager::generateUserId() {
  700. return "user_" + std::to_string(getCurrentTimestamp()) + "_" +
  701. std::to_string(rand() % 10000);
  702. }
  703. std::string UserManager::generateKeyId() {
  704. return "key_" + std::to_string(getCurrentTimestamp()) + "_" +
  705. std::to_string(rand() % 10000);
  706. }
  707. bool UserManager::saveUserData() {
  708. try {
  709. nlohmann::json usersData = nlohmann::json::object();
  710. for (const auto& pair : m_users) {
  711. const UserInfo& user = pair.second;
  712. nlohmann::json userData = {
  713. {"id", user.id},
  714. {"username", user.username},
  715. {"email", user.email},
  716. {"password_hash", user.passwordHash},
  717. {"role", user.role},
  718. {"permissions", user.permissions},
  719. {"api_keys", user.apiKeys},
  720. {"active", user.active},
  721. {"created_at", user.createdAt},
  722. {"last_login_at", user.lastLoginAt},
  723. {"password_changed_at", user.passwordChangedAt},
  724. {"created_by", user.createdBy}
  725. };
  726. usersData[user.username] = userData;
  727. }
  728. std::string filename = m_dataDir + "/users.json";
  729. std::ofstream file(filename);
  730. if (!file.is_open()) {
  731. return false;
  732. }
  733. file << usersData.dump(2);
  734. file.close();
  735. return true;
  736. } catch (const std::exception& e) {
  737. return false;
  738. }
  739. }
  740. bool UserManager::loadUserData() {
  741. try {
  742. std::string filename = m_dataDir + "/users.json";
  743. std::ifstream file(filename);
  744. if (!file.is_open()) {
  745. return false; // File doesn't exist is OK for first run
  746. }
  747. nlohmann::json usersJson;
  748. file >> usersJson;
  749. file.close();
  750. m_users.clear();
  751. for (auto& item : usersJson.items()) {
  752. const std::string& username = item.key();
  753. nlohmann::json& userJson = item.value();
  754. UserInfo user;
  755. user.id = userJson.value("id", "");
  756. user.username = userJson.value("username", username);
  757. user.email = userJson.value("email", "");
  758. user.passwordHash = userJson.value("password_hash", "");
  759. user.role = userJson.value("role", "user");
  760. user.permissions = userJson.value("permissions", std::vector<std::string>{});
  761. user.apiKeys = userJson.value("api_keys", std::vector<std::string>{});
  762. user.active = userJson.value("active", true);
  763. user.createdAt = userJson.value("created_at", 0);
  764. user.lastLoginAt = userJson.value("last_login_at", 0);
  765. user.passwordChangedAt = userJson.value("password_changed_at", 0);
  766. user.createdBy = userJson.value("created_by", "system");
  767. m_users[username] = user;
  768. }
  769. return true;
  770. } catch (const std::exception& e) {
  771. return false;
  772. }
  773. }
  774. bool UserManager::saveApiKeyData() {
  775. try {
  776. nlohmann::json apiKeysData = nlohmann::json::object();
  777. for (const auto& pair : m_apiKeys) {
  778. const ApiKeyInfo& keyInfo = pair.second;
  779. nlohmann::json keyData = {
  780. {"key_id", keyInfo.keyId},
  781. {"key_hash", keyInfo.keyHash},
  782. {"name", keyInfo.name},
  783. {"user_id", keyInfo.userId},
  784. {"permissions", keyInfo.permissions},
  785. {"active", keyInfo.active},
  786. {"created_at", keyInfo.createdAt},
  787. {"last_used_at", keyInfo.lastUsedAt},
  788. {"expires_at", keyInfo.expiresAt},
  789. {"created_by", keyInfo.createdBy}
  790. };
  791. apiKeysData[keyInfo.keyId] = keyData;
  792. }
  793. std::string filename = m_dataDir + "/api_keys.json";
  794. std::ofstream file(filename);
  795. if (!file.is_open()) {
  796. return false;
  797. }
  798. file << apiKeysData.dump(2);
  799. file.close();
  800. return true;
  801. } catch (const std::exception& e) {
  802. return false;
  803. }
  804. }
  805. bool UserManager::loadApiKeyData() {
  806. try {
  807. std::string filename = m_dataDir + "/api_keys.json";
  808. std::ifstream file(filename);
  809. if (!file.is_open()) {
  810. return false; // File doesn't exist is OK for first run
  811. }
  812. nlohmann::json apiKeysJson;
  813. file >> apiKeysJson;
  814. file.close();
  815. m_apiKeys.clear();
  816. m_apiKeyMap.clear();
  817. for (auto& item : apiKeysJson.items()) {
  818. const std::string& keyId = item.key();
  819. nlohmann::json& keyJson = item.value();
  820. ApiKeyInfo keyInfo;
  821. keyInfo.keyId = keyJson.value("key_id", keyId);
  822. keyInfo.keyHash = keyJson.value("key_hash", "");
  823. keyInfo.name = keyJson.value("name", "");
  824. keyInfo.userId = keyJson.value("user_id", "");
  825. keyInfo.permissions = keyJson.value("permissions", std::vector<std::string>{});
  826. keyInfo.active = keyJson.value("active", true);
  827. keyInfo.createdAt = keyJson.value("created_at", 0);
  828. keyInfo.lastUsedAt = keyJson.value("last_used_at", 0);
  829. keyInfo.expiresAt = keyJson.value("expires_at", 0);
  830. keyInfo.createdBy = keyJson.value("created_by", "system");
  831. m_apiKeys[keyId] = keyInfo;
  832. m_apiKeyMap[keyInfo.keyHash] = keyId;
  833. }
  834. return true;
  835. } catch (const std::exception& e) {
  836. return false;
  837. }
  838. }
  839. int64_t UserManager::getCurrentTimestamp() {
  840. return std::chrono::duration_cast<std::chrono::seconds>(
  841. std::chrono::system_clock::now().time_since_epoch()).count();
  842. }
  843. bool UserManager::validateUsername(const std::string& username) {
  844. if (username.length() < 3 || username.length() > 32) {
  845. return false;
  846. }
  847. // Username should contain only alphanumeric characters, underscores, and hyphens
  848. std::regex pattern("^[a-zA-Z0-9_-]+$");
  849. return std::regex_match(username, pattern);
  850. }
  851. bool UserManager::validatePassword(const std::string& password) {
  852. if (password.length() < 8 || password.length() > 128) {
  853. return false;
  854. }
  855. // Password should contain at least one letter and one digit
  856. bool hasLetter = false;
  857. bool hasDigit = false;
  858. for (char c : password) {
  859. if (std::isalpha(c)) hasLetter = true;
  860. if (std::isdigit(c)) hasDigit = true;
  861. }
  862. return hasLetter && hasDigit;
  863. }
  864. bool UserManager::validateEmail(const std::string& email) {
  865. if (email.length() < 5 || email.length() > 254) {
  866. return false;
  867. }
  868. // Basic email validation
  869. std::regex pattern("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
  870. return std::regex_match(email, pattern);
  871. }
  872. bool UserManager::canManageUser(const std::string& requestingUserId, const std::string& targetUserId) {
  873. // Users can always manage themselves
  874. if (requestingUserId == targetUserId) {
  875. return true;
  876. }
  877. // Check if requester is admin
  878. UserInfo requester = getUserInfo(requestingUserId);
  879. return requester.role == roleToString(UserRole::ADMIN);
  880. }