1 #ifndef _ots_Utilities_WebUsers_h_
2 #define _ots_Utilities_WebUsers_h_
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/Macros/StringMacros.h"
6 #include "otsdaq/MessageFacility/MessageFacility.h"
7 #include "otsdaq/SOAPUtilities/SOAPMessenger.h"
8 #pragma GCC diagnostic push
9 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
10 #include <xgi/Method.h>
11 #pragma GCC diagnostic pop
16 #include <unordered_map>
19 #define WEB_LOGIN_DB_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/LoginData/"
20 #define WEB_LOGIN_CERTDATA_PATH std::string(__ENV__("CERT_DATA_PATH"))
21 #define HASHES_DB_PATH "HashesData/"
22 #define USERS_DB_PATH "UsersData/"
23 #define USERS_LOGIN_HISTORY_PATH USERS_DB_PATH + "UserLoginHistoryData/"
24 #define USERS_PREFERENCES_PATH USERS_DB_PATH + "UserPreferencesData/"
25 #define TOOLTIP_DB_PATH USERS_DB_PATH + "/TooltipData/"
29 class HttpXmlDocument;
42 SESSION_ID_LENGTH = 512,
43 COOKIE_CODE_LENGTH = 512,
44 NOT_FOUND_IN_DATABASE = uint64_t(-1),
45 ACCOUNT_INACTIVE = uint64_t(-2),
46 ACCOUNT_BLACKLISTED = uint64_t(-3),
47 ACCOUNT_ERROR_THRESHOLD = uint64_t(-5),
49 DISPLAY_NAME_LENGTH = 4,
59 using permissionLevel_t = uint8_t;
62 PERMISSION_LEVEL_ADMIN = WebUsers::permissionLevel_t(-1),
63 PERMISSION_LEVEL_EXPERT = 100,
64 PERMISSION_LEVEL_USER = 10,
65 PERMISSION_LEVEL_NOVICE = 1,
66 PERMISSION_LEVEL_INACTIVE = 0,
69 static const std::string OTS_OWNER;
71 static const std::string DEFAULT_ADMIN_USERNAME;
72 static const std::string DEFAULT_ADMIN_DISPLAY_NAME;
73 static const std::string DEFAULT_ADMIN_EMAIL;
74 static const std::string DEFAULT_ITERATOR_USERNAME;
75 static const std::string DEFAULT_STATECHANGER_USERNAME;
76 static const std::string DEFAULT_USER_GROUP;
78 static const std::string REQ_NO_LOGIN_RESPONSE;
79 static const std::string REQ_NO_PERMISSION_RESPONSE;
80 static const std::string REQ_USER_LOCKOUT_RESPONSE;
81 static const std::string REQ_LOCK_REQUIRED_RESPONSE;
82 static const std::string REQ_ALLOW_NO_USER;
84 static const std::string SECURITY_TYPE_NONE;
85 static const std::string SECURITY_TYPE_DIGEST_ACCESS;
86 static const std::string SECURITY_TYPE_DEFAULT;
108 User():lastLoginAttempt_(0),accountCreationTime_(0),loginFailureCount_(0),
109 lastModifierTime_(time(0)*100000 + (clock()%100000)) {}
111 void setModifier(
const std::string& modifierUsername)
113 lastModifierUsername_ = modifierUsername;
114 lastModifierTime_ = time(0)*100000 + (clock()%100000);
117 void loadModifierUsername(
const std::string& modifierUsername)
119 lastModifierUsername_ = modifierUsername;
122 time_t& accessModifierTime() {
return lastModifierTime_; }
124 time_t getModifierTime(
bool convertToRealTime =
false)
const {
return (convertToRealTime?lastModifierTime_/100000:lastModifierTime_); }
125 const std::string& getModifierUsername()
const {
return lastModifierUsername_; }
126 std::string getNewAccountCode()
const {
131 char charTimeStr[10];
132 sprintf(charTimeStr,
"%5.5d",
int(lastModifierTime_ & 0xffff));
136 std::string username_, email_, displayName_, salt_;
137 std::map<std::string , WebUsers::permissionLevel_t> permissions_;
139 time_t lastLoginAttempt_, accountCreationTime_;
140 uint8_t loginFailureCount_;
143 std::string lastModifierUsername_;
144 time_t lastModifierTime_;
157 std::string id_, uuid_, ip_;
159 uint8_t loginAttempts_;
174 std::string cookieCode_, ip_;
175 uint64_t userId_, sessionIndex_;
190 SYS_CLEANUP_WILDCARD_TIME = 30,
209 , creationTime_ (time(0))
213 std::string message_;
214 time_t creationTime_;
218 void addSystemMessage (
const std::string& targetUsersCSV,
const std::string& message);
219 void addSystemMessage (
const std::string& targetUsersCSV,
const std::string& subject,
const std::string& message,
bool doEmail);
220 void addSystemMessage (
const std::vector<std::string>& targetUsers,
const std::string& subject,
const std::string& message,
bool doEmail);
221 std::string getSystemMessage (
const std::string& targetUser);
224 void addSystemMessageToMap (
const std::string& targetUser,
const std::string& fullMessage);
225 void systemMessageCleanup (
void);
226 std::mutex systemMessageLock_;
227 std::map<std::string ,std::vector<SystemMessage>> systemMessages_;
239 RequestUserInfo(
const std::string& requestType,
const std::string& cookieCode)
240 : requestType_(requestType)
241 , cookieCode_(cookieCode)
250 bool setGroupPermissionLevels(
const std::string& groupPermissionLevelsString)
253 permissionLevel_ = 0;
255 StringMacros::getMapFromString(
256 groupPermissionLevelsString,
257 groupPermissionLevelMap_);
258 getGroupPermissionLevel();
265 const std::map<std::string , WebUsers::permissionLevel_t>&
266 getGroupPermissionLevels()
const
268 return groupPermissionLevelMap_;
273 const WebUsers::permissionLevel_t& getGroupPermissionLevel()
275 permissionLevel_ = 0;
280 bool matchedAcceptGroup =
false;
281 for(
const auto& userGroupPair : groupPermissionLevelMap_)
282 if(StringMacros::inWildCardSet(
285 userGroupPair.second >
289 userGroupPair.second;
290 matchedAcceptGroup =
true;
294 if(!matchedAcceptGroup && groupsAllowed_.size())
298 <<
") has insufficient group permissions: user is in these groups... "
299 << StringMacros::mapToString(groupPermissionLevelMap_)
300 <<
" and the allowed groups are... "
301 << StringMacros::setToString(groupsAllowed_) << std::endl;
302 return permissionLevel_;
306 if(!groupsAllowed_.size())
308 for(
const auto& userGroupPair : groupPermissionLevelMap_)
309 if(StringMacros::inWildCardSet(userGroupPair.first,
314 <<
") is in a disallowed group: user is in these groups... "
315 << StringMacros::mapToString(groupPermissionLevelMap_)
316 <<
" and the disallowed groups are... "
317 << StringMacros::setToString(groupsDisallowed_) << std::endl;
318 return permissionLevel_;
324 auto findIt = groupPermissionLevelMap_.find(WebUsers::DEFAULT_USER_GROUP);
325 if(findIt != groupPermissionLevelMap_.end())
328 permissionLevel_ = findIt->second;
331 return permissionLevel_;
334 inline bool isInactive()
const
336 return permissionLevel_ == WebUsers::PERMISSION_LEVEL_INACTIVE;
338 inline bool isAdmin()
const
340 return permissionLevel_ == WebUsers::PERMISSION_LEVEL_ADMIN;
344 const std::string& requestType_;
345 std::string cookieCode_;
347 bool automatedCommand_, NonXMLRequestType_, NoXmlWhiteSpace_;
348 bool checkLock_, requireLock_, allowNoUser_, requireSecurity_;
350 std::set<std::string> groupsAllowed_, groupsDisallowed_;
352 WebUsers::permissionLevel_t permissionLevel_, permissionsThreshold_;
355 std::string username_, displayName_, usernameWithLock_;
356 uint64_t activeUserSessionIndex_;
359 std::map<std::string , WebUsers::permissionLevel_t>
360 groupPermissionLevelMap_;
366 bool xmlRequestOnGateway(cgicc::Cgicc& cgi,
367 std::ostringstream* out,
374 static void initializeRequestUserInfo(cgicc::Cgicc& cgi,
376 static bool checkRequestAccess(cgicc::Cgicc& cgi,
377 std::ostringstream* out,
380 bool isWizardMode =
false,
381 const std::string& wizardModeSequence =
"");
383 void createNewAccount(
const std::string& username,
384 const std::string& displayName,
385 const std::string& email);
386 void cleanupExpiredEntries(std::vector<std::string>* loggedOutUsernames = 0);
387 std::string createNewLoginSession(
const std::string& uuid,
const std::string& ip);
389 uint64_t attemptActiveSession(
const std::string& uuid,
390 std::string& jumbledUser,
391 const std::string& jumbledPw,
392 std::string& newAccountCode,
393 const std::string& ip);
394 uint64_t attemptActiveSessionWithCert(
const std::string& uuid,
395 std::string& jumbledEmail,
396 std::string& cookieCode,
397 std::string& username,
398 const std::string& ip);
399 uint64_t isCookieCodeActiveForLogin(
const std::string& uuid,
400 std::string& cookieCode,
401 std::string& username);
402 bool cookieCodeIsActiveForRequest(
403 std::string& cookieCode,
404 std::map<std::string /*groupName*/, WebUsers::permissionLevel_t>*
407 const std::string& ip =
"0",
409 std::string* userWithLock = 0,
410 uint64_t* activeUserSessionIndex = 0);
411 uint64_t cookieCodeLogout(
const std::string& cookieCode,
412 bool logoutOtherUserSessions,
414 const std::string& ip =
"0");
415 bool checkIpAccess(
const std::string& ip);
417 std::string getUsersDisplayName(uint64_t uid);
418 std::string getUsersUsername(uint64_t uid);
419 uint64_t getActiveSessionCountForUser(uint64_t uid);
420 std::map<std::string , WebUsers::permissionLevel_t>
421 getPermissionsForUser(uint64_t uid);
422 void insertSettingsForUser(uint64_t uid,
424 bool includeAccounts =
false);
425 std::string getGenericPreference(uint64_t uid,
426 const std::string& preferenceName,
429 void changeSettingsForUser(uint64_t uid,
430 const std::string& bgcolor,
431 const std::string& dbcolor,
432 const std::string& wincolor,
433 const std::string& layout,
434 const std::string& syslayout);
435 void setGenericPreference(uint64_t uid,
436 const std::string& preferenceName,
437 const std::string& preferenceValue);
438 static void tooltipCheckForUsername(
const std::string& username,
440 const std::string& srcFile,
441 const std::string& srcFunc,
442 const std::string& srcId);
443 static void tooltipSetNeverShowForUsername(
const std::string& username,
445 const std::string& srcFile,
446 const std::string& srcFunc,
447 const std::string& srcId,
449 bool temporarySilence);
451 void modifyAccountSettings(uint64_t actingUid,
453 const std::string& username,
454 const std::string& displayname,
455 const std::string& email,
456 const std::string& permissions);
457 bool setUserWithLock(uint64_t actingUid,
bool lock,
const std::string& username);
458 std::string getUserWithLock(
void) {
return usersUsernameWithLock_; }
460 std::string getActiveUsersString(
void);
462 bool getUserInfoForCookie(std::string& cookieCode,
463 std::string* userName,
464 std::string* displayName = 0,
465 uint64_t* activeSessionIndex = 0);
467 bool isUsernameActive(
const std::string& username)
const;
468 bool isUserIdActive(uint64_t uid)
const;
469 uint64_t getAdminUserID(
void);
470 std::string getSecurity(
void);
472 static void deleteUserData(
void);
474 static void resetAllUserTooltips(
const std::string& userNeedle =
"*");
475 static void silenceAllUserTooltips(
const std::string& username);
477 static void NACDisplayThread(
const std::string& nac,
const std::string& user);
479 void saveActiveSessions(
void);
480 void loadActiveSessions(
void);
483 inline WebUsers::permissionLevel_t getPermissionLevelForGroup(
484 const std::map<std::string /*groupName*/, WebUsers::permissionLevel_t>& permissionMap,
485 const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
486 inline bool isInactiveForGroup(
487 const std::map<std::string /*groupName*/, WebUsers::permissionLevel_t>& permissionMap,
488 const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
489 inline bool isAdminForGroup(
490 const std::map<std::string /*groupName*/, WebUsers::permissionLevel_t>& permissionMap,
491 const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
493 void loadSecuritySelection(
void);
494 void loadUserWithLock(
void);
495 unsigned int hexByteStrToInt(
const char* h);
496 void intToHexStr(uint8_t i,
char* h);
497 std::string sha512(
const std::string& user,
498 const std::string& password,
500 std::string dejumble(
const std::string& jumbledUser,
const std::string& sessionId);
501 std::string createNewActiveSession(uint64_t uid,
502 const std::string& ip =
"0",
503 uint64_t asIndex = 0);
504 bool addToHashesDatabase(
const std::string& hash);
505 std::string genCookieCode(
void);
506 std::string refreshCookieCode(
unsigned int i,
bool enableRefresh =
true);
507 bool deleteAccount(
const std::string& username,
const std::string& displayName);
508 void incrementIpBlacklistCount(
const std::string& ip);
510 void saveToDatabase(FILE* fp,
511 const std::string& field,
512 const std::string& value,
513 uint8_t type = DB_SAVE_OPEN_AND_CLOSE,
514 bool addNewLine =
true);
515 bool saveDatabaseToFile(uint8_t db);
516 bool loadDatabases(
void);
518 uint64_t searchUsersDatabaseForUsername (
const std::string& username)
const;
519 uint64_t searchUsersDatabaseForDisplayName (
const std::string& displayName)
const;
520 uint64_t searchUsersDatabaseForUserEmail (
const std::string& useremail)
const;
521 uint64_t searchUsersDatabaseForUserId (uint64_t uid)
const;
522 uint64_t searchLoginSessionDatabaseForUUID (
const std::string& uuid)
const;
523 uint64_t searchHashesDatabaseForHash (
const std::string& hash);
524 uint64_t searchActiveSessionDatabaseForCookie (
const std::string& cookieCode)
const;
526 static std::string getTooltipFilename(
const std::string& username,
527 const std::string& srcFile,
528 const std::string& srcFunc,
529 const std::string& srcId);
530 std::string getUserEmailFromFingerprint(
const std::string& fingerprint);
540 DB_SAVE_OPEN_AND_CLOSE,
545 std::unordered_map<std::string, std::string> certFingerprints_;
547 static const std::vector<std::string> UsersDatabaseEntryFields_, HashesDatabaseEntryFields_;
548 bool CareAboutCookieCodes_;
549 std::string securityType_;
552 std::vector<LoginSession> LoginSessions_;
566 LOGIN_SESSION_EXPIRATION_TIME = 5 * 60,
567 LOGIN_SESSION_ATTEMPTS_MAX = 5,
571 std::vector<ActiveSession> ActiveSessions_;
587 ACTIVE_SESSION_EXPIRATION_TIME = 120 * 60,
590 ACTIVE_SESSION_COOKIE_OVERLAP_TIME =
592 ACTIVE_SESSION_STALE_COOKIE_LIMIT =
597 std::vector<User> Users_;
624 uint64_t usersNextUserId_;
627 USERS_LOGIN_HISTORY_SIZE = 20,
628 USERS_GLOBAL_HISTORY_SIZE = 1000,
629 USERS_MAX_LOGIN_FAILURES = 20,
631 std::string usersUsernameWithLock_;
633 std::vector<std::string> UsersLoggedOutUsernames_;
636 std::vector<Hash> Hashes_;
644 IP_BLACKLIST_COUNT_THRESHOLD = 200,
646 std::map<std::string , uint32_t > ipBlacklistCounts_;
648 std::mutex webUserMutex_;