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>
18 #include "otsdaq/NetworkUtilities/TransceiverSocket.h"
20 #define WEB_LOGIN_DB_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/LoginData/"
21 #define WEB_LOGIN_CERTDATA_PATH std::string(__ENV__("CERT_DATA_PATH"))
22 #define HASHES_DB_PATH "HashesData/"
23 #define USERS_DB_PATH "UsersData/"
24 #define USERS_LOGIN_HISTORY_PATH USERS_DB_PATH + "UserLoginHistoryData/"
25 #define USERS_PREFERENCES_PATH USERS_DB_PATH + "UserPreferencesData/"
26 #define TOOLTIP_DB_PATH USERS_DB_PATH + "/TooltipData/"
32 class HttpXmlDocument;
44 SESSION_ID_LENGTH = 512,
45 COOKIE_CODE_LENGTH = 512,
46 NOT_FOUND_IN_DATABASE = uint64_t(-1),
47 ACCOUNT_INACTIVE = uint64_t(-2),
48 ACCOUNT_BLACKLISTED = uint64_t(-3),
49 ACCOUNT_ERROR_THRESHOLD = uint64_t(-5),
51 DISPLAY_NAME_LENGTH = 4,
61 using permissionLevel_t = uint8_t;
65 PERMISSION_LEVEL_EXPERT = 100,
66 PERMISSION_LEVEL_USER = 10,
67 PERMISSION_LEVEL_NOVICE = 1,
68 PERMISSION_LEVEL_INACTIVE = 0,
73 static const std::string DEFAULT_ADMIN_USERNAME;
74 static const std::string DEFAULT_ADMIN_DISPLAY_NAME;
75 static const std::string DEFAULT_ADMIN_EMAIL;
76 static const std::string DEFAULT_ITERATOR_USERNAME;
77 static const std::string DEFAULT_STATECHANGER_USERNAME;
78 static const std::string DEFAULT_USER_GROUP;
80 static const std::string REQ_NO_LOGIN_RESPONSE;
81 static const std::string REQ_NO_PERMISSION_RESPONSE;
82 static const std::string REQ_USER_LOCKOUT_RESPONSE;
83 static const std::string REQ_LOCK_REQUIRED_RESPONSE;
84 static const std::string REQ_ALLOW_NO_USER;
86 static const std::string SECURITY_TYPE_NONE;
87 static const std::string SECURITY_TYPE_DIGEST_ACCESS;
88 static const std::string SECURITY_TYPE_DEFAULT;
110 User():lastLoginAttempt_(0),accountCreationTime_(0),loginFailureCount_(0),
111 lastModifierTime_(time(0)*100000 + (clock()%100000)) {}
115 lastModifierUsername_ = modifierUsername;
116 lastModifierTime_ = time(0)*100000 + (clock()%100000);
119 void loadModifierUsername(
const std::string& modifierUsername)
121 lastModifierUsername_ = modifierUsername;
124 time_t& accessModifierTime() {
return lastModifierTime_; }
126 time_t getModifierTime(
bool convertToRealTime =
false)
const {
return (convertToRealTime?lastModifierTime_/100000:lastModifierTime_); }
127 const std::string& getModifierUsername()
const {
return lastModifierUsername_; }
133 char charTimeStr[10];
134 sprintf(charTimeStr,
"%5.5d",
int(lastModifierTime_ & 0xffff));
138 std::string username_, email_, displayName_, salt_;
139 std::map<std::string , WebUsers::permissionLevel_t> permissions_;
141 time_t lastLoginAttempt_, accountCreationTime_;
142 uint8_t loginFailureCount_;
145 std::string lastModifierUsername_;
146 time_t lastModifierTime_;
159 std::string id_, uuid_, ip_;
161 uint8_t loginAttempts_;
176 std::string cookieCode_, ip_;
177 uint64_t userId_, sessionIndex_;
211 , creationTime_ (time(0))
216 std::string message_;
217 time_t creationTime_;
222 void addSystemMessage (
const std::string& targetUsersCSV,
const std::string& message);
223 void addSystemMessage (
const std::string& targetUsersCSV,
const std::string& subject,
const std::string& message,
bool doEmail);
224 void addSystemMessage (
const std::vector<std::string>& targetUsers,
const std::string& subject,
const std::string& message,
bool doEmail);
230 void addSystemMessageToMap (
const std::string& targetUser,
const std::string& fullMessage);
231 void systemMessageCleanup (
void);
232 std::mutex systemMessageLock_;
233 std::map<std::string ,std::vector<SystemMessage>> systemMessages_;
246 : requestType_(requestType)
247 , cookieCode_(cookieCode)
259 permissionLevel_ = 0;
262 groupPermissionLevelsString,
263 groupPermissionLevelMap_);
271 const std::map<std::string , WebUsers::permissionLevel_t>&
272 getGroupPermissionLevels()
const
274 return groupPermissionLevelMap_;
281 permissionLevel_ = 0;
286 bool matchedAcceptGroup =
false;
287 for(
const auto& userGroupPair : groupPermissionLevelMap_)
291 userGroupPair.second >
295 userGroupPair.second;
296 matchedAcceptGroup =
true;
300 if(!matchedAcceptGroup && groupsAllowed_.size())
304 <<
") has insufficient group permissions: user is in these groups... "
306 <<
" and the allowed groups are... "
308 return permissionLevel_;
312 if(!groupsAllowed_.size())
314 for(
const auto& userGroupPair : groupPermissionLevelMap_)
320 <<
") is in a disallowed group: user is in these groups... "
322 <<
" and the disallowed groups are... "
324 return permissionLevel_;
330 auto findIt = groupPermissionLevelMap_.find(WebUsers::DEFAULT_USER_GROUP);
331 if(findIt != groupPermissionLevelMap_.end())
334 permissionLevel_ = findIt->second;
337 return permissionLevel_;
340 inline bool isInactive()
const
342 return permissionLevel_ == WebUsers::PERMISSION_LEVEL_INACTIVE;
344 inline bool isAdmin()
const
350 const std::string& requestType_;
351 std::string cookieCode_;
353 bool automatedCommand_, NonXMLRequestType_, NoXmlWhiteSpace_;
354 bool checkLock_, requireLock_, allowNoUser_, requireSecurity_;
356 std::set<std::string> groupsAllowed_, groupsDisallowed_;
358 WebUsers::permissionLevel_t permissionLevel_, permissionsThreshold_;
361 std::string username_, displayName_, usernameWithLock_;
365 std::map<std::string , WebUsers::permissionLevel_t>
366 groupPermissionLevelMap_;
373 std::ostringstream* out,
383 std::ostringstream* out,
386 bool isWizardMode =
false,
387 const std::string& wizardModeSequence =
"");
390 const std::string& displayName,
391 const std::string& email);
397 std::string& jumbledUser,
398 const std::string& jumbledPw,
399 std::string& newAccountCode,
400 const std::string& ip);
402 std::string& jumbledEmail,
403 std::string& cookieCode,
404 std::string& username,
405 const std::string& ip);
407 std::string& cookieCode,
408 std::string& username);
410 std::string& cookieCode,
411 std::map<std::string /*groupName*/, WebUsers::permissionLevel_t>*
414 const std::string& ip =
"0",
416 bool doNotGoRemote =
false,
417 std::string* userWithLock = 0,
418 uint64_t* userSessionIndex = 0);
420 bool logoutOtherUserSessions,
422 const std::string& ip =
"0");
427 std::map<std::string , WebUsers::permissionLevel_t>
433 bool includeAccounts =
false);
435 const std::string& preferenceName,
439 const std::string& bgcolor,
440 const std::string& dbcolor,
441 const std::string& wincolor,
442 const std::string& layout,
443 const std::string& syslayout);
445 const std::string& preferenceName,
446 const std::string& preferenceValue);
449 const std::string& srcFile,
450 const std::string& srcFunc,
451 const std::string& srcId);
454 const std::string& srcFile,
455 const std::string& srcFunc,
456 const std::string& srcId,
458 bool temporarySilence);
462 const std::string& username,
463 const std::string& displayname,
464 const std::string& email,
465 const std::string& permissions);
466 bool setUserWithLock(uint64_t actingUid,
bool lock,
const std::string& username);
467 std::string getUserWithLock(
void) {
return usersUsernameWithLock_; }
477 static void deleteUserData(
void);
482 static void NACDisplayThread(
const std::string& nac,
const std::string& user);
488 inline WebUsers::permissionLevel_t getPermissionLevelForGroup(
489 const std::map<std::string /*groupName*/, WebUsers::permissionLevel_t>& permissionMap,
490 const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
491 inline bool isInactiveForGroup(
492 const std::map<std::string /*groupName*/, WebUsers::permissionLevel_t>& permissionMap,
493 const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
494 inline bool isAdminForGroup(
495 const std::map<std::string /*groupName*/, WebUsers::permissionLevel_t>& permissionMap,
496 const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
498 void loadSecuritySelection(
void);
499 void loadIPAddressSecurity(
void);
500 void loadUserWithLock(
void);
501 unsigned int hexByteStrToInt(
const char* h);
502 void intToHexStr(uint8_t i,
char* h);
503 std::string sha512(
const std::string& user,
504 const std::string& password,
506 std::string dejumble(
const std::string& jumbledUser,
const std::string& sessionId);
507 std::string createNewActiveSession(uint64_t uid,
508 const std::string& ip =
"0",
509 uint64_t asIndex = 0);
510 bool addToHashesDatabase(
const std::string& hash);
511 std::string genCookieCode(
void);
512 std::string refreshCookieCode(
unsigned int i,
bool enableRefresh =
true);
513 bool deleteAccount(
const std::string& username,
const std::string& displayName);
514 void incrementIpBlacklistCount(
const std::string& ip);
516 void saveToDatabase(FILE* fp,
517 const std::string& field,
518 const std::string& value,
519 uint8_t type = DB_SAVE_OPEN_AND_CLOSE,
520 bool addNewLine =
true);
521 bool saveDatabaseToFile(uint8_t db);
522 bool loadDatabases(
void);
524 uint64_t searchUsersDatabaseForUsername (
const std::string& username)
const;
525 uint64_t searchUsersDatabaseForDisplayName (
const std::string& displayName)
const;
526 uint64_t searchUsersDatabaseForUserEmail (
const std::string& useremail)
const;
527 uint64_t searchUsersDatabaseForUserId (uint64_t uid)
const;
528 uint64_t searchLoginSessionDatabaseForUUID (
const std::string& uuid)
const;
529 uint64_t searchHashesDatabaseForHash (
const std::string& hash);
530 uint64_t searchActiveSessionDatabaseForCookie (
const std::string& cookieCode)
const;
531 uint64_t searchRemoteSessionDatabaseForCookie (
const std::string& cookieCode)
const;
532 uint64_t checkRemoteLoginVerification (std::string& cookieCode,
bool refresh,
bool doNotGoRemote,
const std::string& ip);
534 static std::string getTooltipFilename(
const std::string& username,
535 const std::string& srcFile,
536 const std::string& srcFunc,
537 const std::string& srcId);
538 std::string getUserEmailFromFingerprint(
const std::string& fingerprint);
548 DB_SAVE_OPEN_AND_CLOSE,
553 std::unordered_map<std::string, std::string> certFingerprints_;
555 static const std::vector<std::string> UsersDatabaseEntryFields_, HashesDatabaseEntryFields_;
556 static volatile bool CareAboutCookieCodes_;
557 std::string securityType_;
558 std::set<std::string > ipAccessAccept_;
559 std::set<std::string > ipAccessReject_;
560 std::set<std::string > ipAccessBlacklist_;
563 std::vector<LoginSession> LoginSessions_;
572 LOGIN_SESSION_EXPIRATION_TIME = 5 * 60,
573 LOGIN_SESSION_ATTEMPTS_MAX = 5,
577 std::vector<ActiveSession> ActiveSessions_;
578 std::map<std::string , ActiveSession > RemoteSessions_;
590 ACTIVE_SESSION_EXPIRATION_TIME = 120 * 60,
593 ACTIVE_SESSION_COOKIE_OVERLAP_TIME =
595 ACTIVE_SESSION_STALE_COOKIE_LIMIT =
600 std::vector<User> Users_;
619 uint64_t usersNextUserId_;
622 USERS_LOGIN_HISTORY_SIZE = 20,
623 USERS_GLOBAL_HISTORY_SIZE = 1000,
624 USERS_MAX_LOGIN_FAILURES = 20,
626 std::string usersUsernameWithLock_;
628 std::vector<std::string> UsersLoggedOutUsernames_;
631 std::vector<Hash> Hashes_;
636 IP_BLACKLIST_COUNT_THRESHOLD = 200,
638 std::map<std::string , uint32_t > ipBlacklistCounts_;
640 std::mutex webUserMutex_;
642 std::unique_ptr<TransceiverSocket> remoteLoginVerificationSocket_;
643 std::unique_ptr<Socket> remoteLoginVerificationSocketTarget_;
645 time_t ipSecurityLastLoadTime_ = time(0);
648 std::atomic<time_t> remoteLoginVerificationEnabledBlackoutTime_ = 0;
void addSystemMessage(const std::string &targetUsersCSV, const std::string &message)
const std::string & getSecurity(void)
WebUsers::getSecurity.
std::string getGenericPreference(uint64_t uid, const std::string &preferenceName, HttpXmlDocument *xmldoc=0) const
bool setUserWithLock(uint64_t actingUid, bool lock, const std::string &username)
static bool checkRequestAccess(cgicc::Cgicc &cgi, std::ostringstream *out, HttpXmlDocument *xmldoc, WebUsers::RequestUserInfo &userInfo, bool isWizardMode=false, const std::string &wizardModeSequence="")
static void silenceAllUserTooltips(const std::string &username)
size_t getActiveUserCount(void)
std::map< std::string, WebUsers::permissionLevel_t > getPermissionsForUser(uint64_t uid)
from Gateway, use public version which considers remote users
uint64_t attemptActiveSession(const std::string &uuid, std::string &jumbledUser, const std::string &jumbledPw, std::string &newAccountCode, const std::string &ip)
void setGenericPreference(uint64_t uid, const std::string &preferenceName, const std::string &preferenceValue)
std::string getAllSystemMessages(void)
void cleanupExpiredEntries(std::vector< std::string > *loggedOutUsernames=0)
void changeSettingsForUser(uint64_t uid, const std::string &bgcolor, const std::string &dbcolor, const std::string &wincolor, const std::string &layout, const std::string &syslayout)
WebUsers::changeSettingsForUser.
uint64_t isCookieCodeActiveForLogin(const std::string &uuid, std::string &cookieCode, std::string &username)
std::string createNewLoginSession(const std::string &uuid, const std::string &ip)
std::string getActiveUsersString(void)
void createNewAccount(const std::string &username, const std::string &displayName, const std::string &email)
void modifyAccountSettings(uint64_t actingUid, uint8_t cmd_type, const std::string &username, const std::string &displayname, const std::string &email, const std::string &permissions)
WebUsers::modifyAccountSettings.
int remoteLoginVerificationPort_
Port of remote Gateway to be used for login verification.
bool isUsernameActive(const std::string &username) const
bool isUserIdActive(uint64_t uid) const
void saveActiveSessions(void)
static std::atomic< bool > remoteLoginVerificationEnabled_
true if this supervisor is under control of a remote supervisor
uint64_t getAdminUserID(void)
@ SYS_CLEANUP_WILDCARD_TIME
300 seconds
std::string getUsersUsername(uint64_t uid)
from Gateway, use public version which considers remote users
static void initializeRequestUserInfo(cgicc::Cgicc &cgi, WebUsers::RequestUserInfo &userInfo)
used by gateway and other supervisors to verify requests consistently
bool checkIpAccess(const std::string &ip)
bool xmlRequestOnGateway(cgicc::Cgicc &cgi, std::ostringstream *out, HttpXmlDocument *xmldoc, WebUsers::RequestUserInfo &userInfo)
uint64_t cookieCodeLogout(const std::string &cookieCode, bool logoutOtherUserSessions, uint64_t *uid=0, const std::string &ip="0")
std::string getSystemMessage(const std::string &targetUser)
uint64_t getActiveSessionCountForUser(uint64_t uid)
static void resetAllUserTooltips(const std::string &userNeedle="*")
WebUsers::resetAllUserTooltips.
static void tooltipSetNeverShowForUsername(const std::string &username, HttpXmlDocument *xmldoc, const std::string &srcFile, const std::string &srcFunc, const std::string &srcId, bool doNeverShow, bool temporarySilence)
void cleanupExpiredRemoteEntries(void)
std::string getUsersDisplayName(uint64_t uid)
from Gateway, use public version which considers remote users
void loadActiveSessions(void)
std::pair< std::string, time_t > getLastSystemMessage(void)
uint64_t attemptActiveSessionWithCert(const std::string &uuid, std::string &jumbledEmail, std::string &cookieCode, std::string &username, const std::string &ip)
static const std::string OTS_OWNER
defined by environment variable, e.g. experiment name
static void tooltipCheckForUsername(const std::string &username, HttpXmlDocument *xmldoc, const std::string &srcFile, const std::string &srcFunc, const std::string &srcId)
std::string remoteGatewaySelfName_
IP of remote Gateway to be used for login verification.
bool cookieCodeIsActiveForRequest(std::string &cookieCode, std::map< std::string, WebUsers::permissionLevel_t > *userPermissions=0, uint64_t *uid=0, const std::string &ip="0", bool refresh=true, bool doNotGoRemote=false, std::string *userWithLock=0, uint64_t *userSessionIndex=0)
void insertSettingsForUser(uint64_t uid, HttpXmlDocument *xmldoc, bool includeAccounts=false)
@ PERMISSION_LEVEL_ADMIN
max permission level!
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static bool inWildCardSet(const std::string &needle, const std::set< std::string > &haystack)
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
getMapFromString ~
time_t accessTime_
last login month resolution, blurred by 1/2 month
uint64_t userSessionIndex_
can use session index to track a user's session on multiple devices/browsers
const WebUsers::permissionLevel_t & getGroupPermissionLevel()
RequestUserInfo(const std::string &requestType, const std::string &cookieCode)
bool setGroupPermissionLevels(const std::string &groupPermissionLevelsString)
end setGroupPermissionLevels()
bool deliveredRemote_
flag
std::string getNewAccountCode() const
void setModifier(const std::string &modifierUsername)