00001 #ifndef _ots_Utilities_WebUsers_h_
00002 #define _ots_Utilities_WebUsers_h_
00003
00004 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00005 #include "otsdaq-core/Macros/CoutMacros.h"
00006 #include "otsdaq-core/Macros/StringMacros.h"
00007 #include "otsdaq-core/SOAPUtilities/SOAPMessenger.h"
00008 #include "xgi/Method.h"
00009
00010 #include <string>
00011 #include <vector>
00012 #include <iostream>
00013 #include <unordered_map>
00014
00015 #define WEB_LOGIN_DB_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/LoginData/"
00016 #define WEB_LOGIN_CERTDATA_PATH std::string(getenv("CERT_DATA_PATH"))
00017 #define HASHES_DB_PATH "HashesData/"
00018 #define USERS_DB_PATH "UsersData/"
00019 #define USERS_LOGIN_HISTORY_PATH USERS_DB_PATH + "UserLoginHistoryData/"
00020 #define USERS_PREFERENCES_PATH USERS_DB_PATH + "UserPreferencesData/"
00021 #define TOOLTIP_DB_PATH USERS_DB_PATH + "/TooltipData/"
00022
00023
00024 namespace ots
00025 {
00026
00027 class HttpXmlDocument;
00028
00029
00030
00031
00032 class WebUsers
00033 {
00034 public:
00035 WebUsers();
00036
00037 enum {
00038 SESSION_ID_LENGTH = 512,
00039 COOKIE_CODE_LENGTH = 512,
00040 NOT_FOUND_IN_DATABASE = uint64_t(-1),
00041 USERNAME_LENGTH = 4,
00042 DISPLAY_NAME_LENGTH = 4,
00043 };
00044
00045
00046 using permissionLevel_t = uint8_t;
00047 enum {
00048 PERMISSION_LEVEL_ADMIN = WebUsers::permissionLevel_t(-1),
00049 PERMISSION_LEVEL_EXPERT = 100,
00050 PERMISSION_LEVEL_USER = 10,
00051 PERMISSION_LEVEL_NOVICE = 1,
00052 PERMISSION_LEVEL_INACTIVE = 0,
00053 };
00054
00055 static const std::string DEFAULT_ADMIN_USERNAME;
00056 static const std::string DEFAULT_ADMIN_DISPLAY_NAME;
00057 static const std::string DEFAULT_ADMIN_EMAIL;
00058 static const std::string DEFAULT_ITERATOR_USERNAME;
00059 static const std::string DEFAULT_STATECHANGER_USERNAME;
00060 static const std::string DEFAULT_USER_GROUP;
00061
00062 static const std::string REQ_NO_LOGIN_RESPONSE;
00063 static const std::string REQ_NO_PERMISSION_RESPONSE;
00064 static const std::string REQ_USER_LOCKOUT_RESPONSE;
00065 static const std::string REQ_LOCK_REQUIRED_RESPONSE;
00066 static const std::string REQ_ALLOW_NO_USER;
00067
00068 static const std::string SECURITY_TYPE_NONE;
00069 static const std::string SECURITY_TYPE_DIGEST_ACCESS;
00070
00071
00072 struct RequestUserInfo
00073 {
00074
00075 friend class WebUsers;
00076
00077 RequestUserInfo(const std::string& requestType,
00078 const std::string& cookieCode)
00079 : requestType_ (requestType)
00080 , cookieCode_ (cookieCode)
00081 , uid_ (-1)
00082 {}
00083
00084
00085
00086
00087 bool setGroupPermissionLevels(const std::string& groupPermissionLevelsString)
00088 {
00089 permissionLevel_ = 0;
00090 if(allowNoUser_) return false;
00091
00092 StringMacros::getMapFromString(
00093 groupPermissionLevelsString,
00094 groupPermissionLevelMap_);
00095 getGroupPermissionLevel();
00096 return true;
00097 }
00098
00099
00100
00101
00102 const std::map<std::string ,
00103 WebUsers::permissionLevel_t>& getGroupPermissionLevels() const { return groupPermissionLevelMap_; }
00104
00105
00106
00107 const WebUsers::permissionLevel_t& getGroupPermissionLevel()
00108 {
00109 permissionLevel_ = 0;
00110
00111
00112
00113
00114 bool matchedAcceptGroup = false;
00115 for(const auto& userGroupPair:groupPermissionLevelMap_)
00116 if(StringMacros::inWildCardSet(
00117 userGroupPair.first,
00118 groupsAllowed_) &&
00119 userGroupPair.second > permissionLevel_)
00120 {
00121 permissionLevel_ = userGroupPair.second;
00122 matchedAcceptGroup = true;
00123 }
00124
00125
00126 if(!matchedAcceptGroup && groupsAllowed_.size())
00127 {
00128
00129
00130 __COUT_INFO__ << "User (@" << ip_ << ") has insufficient group permissions: user is in these groups... " <<
00131 StringMacros::mapToString(groupPermissionLevelMap_) << " and the allowed groups are... " <<
00132 StringMacros::setToString(groupsAllowed_) << std::endl;
00133 return permissionLevel_;
00134 }
00135
00136
00137 if(!groupsAllowed_.size())
00138 {
00139 for(const auto& userGroupPair:groupPermissionLevelMap_)
00140 if(StringMacros::inWildCardSet(
00141 userGroupPair.first,
00142 groupsDisallowed_))
00143 {
00144
00145
00146 __COUT_INFO__ << "User (@" << ip_ << ") is in a disallowed group: user is in these groups... " <<
00147 StringMacros::mapToString(groupPermissionLevelMap_) << " and the disallowed groups are... " <<
00148 StringMacros::setToString(groupsDisallowed_) << std::endl;
00149 return permissionLevel_;
00150 }
00151 }
00152
00153
00154
00155 auto findIt = groupPermissionLevelMap_.find(WebUsers::DEFAULT_USER_GROUP);
00156 if(findIt != groupPermissionLevelMap_.end())
00157 {
00158
00159 permissionLevel_ = findIt->second;
00160 }
00161
00162 return permissionLevel_;
00163 }
00164
00165
00166 inline bool isInactive() { return permissionLevel_ == WebUsers::PERMISSION_LEVEL_INACTIVE; }
00167 inline bool isAdmin() { return permissionLevel_ == WebUsers::PERMISSION_LEVEL_ADMIN; }
00168
00169
00170 const std::string& requestType_;
00171 std::string cookieCode_;
00172
00173 bool automatedCommand_, NonXMLRequestType_, NoXmlWhiteSpace_;
00174 bool checkLock_, requireLock_, allowNoUser_;
00175
00176 std::set<std::string> groupsAllowed_, groupsDisallowed_;
00177
00178 WebUsers::permissionLevel_t permissionLevel_, permissionsThreshold_;
00179 std::string ip_;
00180 uint64_t uid_ ;
00181 std::string username_, displayName_, usernameWithLock_;
00182 uint64_t activeUserSessionIndex_;
00183 private:
00184 std::map<std::string ,WebUsers::permissionLevel_t> groupPermissionLevelMap_;
00185 };
00186
00187
00188
00189 bool xmlRequestOnGateway(
00190 cgicc::Cgicc& cgi,
00191 std::ostringstream* out,
00192 HttpXmlDocument* xmldoc,
00193 WebUsers::RequestUserInfo& userInfo);
00194
00195 public:
00196
00197
00198 static void initializeRequestUserInfo(
00199 cgicc::Cgicc& cgi,
00200 WebUsers::RequestUserInfo& userInfo);
00201 static bool checkRequestAccess(
00202 cgicc::Cgicc& cgi,
00203 std::ostringstream* out,
00204 HttpXmlDocument* xmldoc,
00205 WebUsers::RequestUserInfo& userInfo,
00206 bool isWizardMode = false);
00207
00208 bool createNewAccount (const std::string& username, const std::string& displayName, const std::string& email);
00209 void cleanupExpiredEntries (std::vector<std::string>* loggedOutUsernames = 0);
00210 std::string createNewLoginSession (const std::string& uuid, const std::string& ip);
00211
00212 uint64_t attemptActiveSession (const std::string& uuid, std::string& jumbledUser, const std::string& jumbledPw, std::string& newAccountCode, const std::string& ip);
00213 uint64_t attemptActiveSessionWithCert (const std::string& uuid, std::string& jumbledEmail, std::string& cookieCode, std::string& username, const std::string& ip);
00214 uint64_t isCookieCodeActiveForLogin (const std::string& uuid, std::string& cookieCode,std::string& username);
00215 bool cookieCodeIsActiveForRequest (std::string& cookieCode, std::map<std::string /*groupName*/,WebUsers::permissionLevel_t>* userPermissions = 0, uint64_t* uid = 0, const std::string& ip = "0", bool refresh = true, std::string* userWithLock = 0, uint64_t* activeUserSessionIndex = 0);
00216 uint64_t cookieCodeLogout (const std::string& cookieCode, bool logoutOtherUserSessions, uint64_t* uid = 0, const std::string& ip = "0");
00217 bool checkIpAccess (const std::string& ip);
00218
00219 std::string getUsersDisplayName (uint64_t uid);
00220 std::string getUsersUsername (uint64_t uid);
00221 uint64_t getActiveSessionCountForUser (uint64_t uid);
00222 std::map<std::string ,WebUsers::permissionLevel_t> getPermissionsForUser (uint64_t uid);
00223 void insertSettingsForUser (uint64_t uid, HttpXmlDocument* xmldoc,bool includeAccounts=false);
00224 std::string getGenericPreference (uint64_t uid, const std::string& preferenceName, HttpXmlDocument* xmldoc = 0) const;
00225
00226 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);
00227 void setGenericPreference (uint64_t uid, const std::string& preferenceName, const std::string& preferenceValue);
00228 static void tooltipCheckForUsername (const std::string& username, HttpXmlDocument* xmldoc, const std::string& srcFile, const std::string& srcFunc, const std::string& srcId);
00229 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);
00230
00231 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);
00232 bool setUserWithLock (uint64_t actingUid, bool lock, const std::string& username);
00233 std::string getUserWithLock (void) { return usersUsernameWithLock_; }
00234
00235 std::string getActiveUsersString (void);
00236
00237 bool getUserInfoForCookie (std::string& cookieCode, std::string* userName, std::string* displayName = 0, uint64_t* activeSessionIndex = 0);
00238
00239 bool isUsernameActive (const std::string& username) const;
00240 bool isUserIdActive (uint64_t uid) const;
00241 uint64_t getAdminUserID (void);
00242 std::string getSecurity (void);
00243
00244 static void deleteUserData (void);
00245 static void resetAllUserTooltips (const std::string& userNeedle = "*");
00246
00247 static void NACDisplayThread (const std::string& nac, const std::string& user);
00248
00249 void saveActiveSessions (void);
00250 void loadActiveSessions (void);
00251
00252 private:
00253
00254 inline WebUsers::permissionLevel_t getPermissionLevelForGroup (std::map<std::string /*groupName*/,WebUsers::permissionLevel_t>& permissionMap, const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
00255 inline bool isInactiveForGroup (std::map<std::string /*groupName*/,WebUsers::permissionLevel_t>& permissionMap, const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
00256 inline bool isAdminForGroup (std::map<std::string /*groupName*/,WebUsers::permissionLevel_t>& permissionMap, const std::string& groupName = WebUsers::DEFAULT_USER_GROUP);
00257
00258 void loadSecuritySelection (void);
00259 void loadUserWithLock (void);
00260 unsigned int hexByteStrToInt (const char* h);
00261 void intToHexStr (uint8_t i, char* h);
00262 std::string sha512 (const std::string& user, const std::string& password, std::string& salt);
00263 std::string dejumble (const std::string& jumbledUser, const std::string& sessionId);
00264 std::string createNewActiveSession (uint64_t uid, const std::string& ip = "0", uint64_t asIndex = 0);
00265 bool addToHashesDatabase (const std::string& hash);
00266 std::string genCookieCode (void);
00267 std::string refreshCookieCode (unsigned int i, bool enableRefresh = true);
00268 void removeActiveSessionEntry (unsigned int i);
00269 void removeLoginSessionEntry (unsigned int i);
00270 bool deleteAccount (const std::string& username, const std::string& displayName);
00271 void incrementIpBlacklistCount (const std::string& ip);
00272
00273 void saveToDatabase (FILE* fp, const std::string& field, const std::string& value, uint8_t type = DB_SAVE_OPEN_AND_CLOSE, bool addNewLine = true);
00274 bool saveDatabaseToFile (uint8_t db);
00275 bool loadDatabases (void);
00276
00277 uint64_t searchUsersDatabaseForUsername (const std::string& username) const;
00278 uint64_t searchUsersDatabaseForUserEmail (const std::string& useremail) const;
00279 uint64_t searchUsersDatabaseForUserId (uint64_t uid) const;
00280 uint64_t searchLoginSessionDatabaseForUUID (const std::string& uuid) const;
00281 uint64_t searchHashesDatabaseForHash (const std::string& hash);
00282 uint64_t searchActiveSessionDatabaseForCookie (const std::string& cookieCode) const;
00283
00284 static std::string getTooltipFilename (const std::string& username, const std::string& srcFile, const std::string& srcFunc, const std::string& srcId);
00285 std::string getUserEmailFromFingerprint (const std::string& fingerprint);
00286
00287
00288 enum {
00289 DB_USERS,
00290 DB_HASHES
00291 };
00292
00293 enum {
00294 MOD_TYPE_UPDATE,
00295 MOD_TYPE_ADD,
00296 MOD_TYPE_DELETE
00297 };
00298
00299 enum {
00300 DB_SAVE_OPEN_AND_CLOSE,
00301 DB_SAVE_OPEN,
00302 DB_SAVE_CLOSE
00303 };
00304
00305 std::unordered_map<std::string, std::string> certFingerprints_;
00306
00307 std::vector<std::string> UsersDatabaseEntryFields,HashesDatabaseEntryFields;
00308 bool CareAboutCookieCodes_;
00309 std::string securityType_;
00310
00311
00312
00313
00314
00315
00316
00317
00318 std::vector<std::string> LoginSessionIdVector, LoginSessionUUIDVector, LoginSessionIpVector;
00319 std::vector<time_t> LoginSessionStartTimeVector;
00320 std::vector<uint8_t> LoginSessionAttemptsVector;
00321 enum {
00322 LOGIN_SESSION_EXPIRATION_TIME = 5*60,
00323 LOGIN_SESSION_ATTEMPTS_MAX = 5,
00324 };
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 std::vector<std::string> ActiveSessionCookieCodeVector, ActiveSessionIpVector;
00336 std::vector<uint64_t> ActiveSessionUserIdVector, ActiveSessionIndex;
00337 std::vector<time_t> ActiveSessionStartTimeVector;
00338 enum {
00339 ACTIVE_SESSION_EXPIRATION_TIME = 120*60,
00340 ACTIVE_SESSION_COOKIE_OVERLAP_TIME = 10*60,
00341 ACTIVE_SESSION_STALE_COOKIE_LIMIT = 10,
00342 };
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 std::vector<std::string> UsersUsernameVector, UsersUserEmailVector, UsersDisplayNameVector, UsersSaltVector, UsersLastModifierUsernameVector;
00364 std::vector< std::map<std::string ,WebUsers::permissionLevel_t> > UsersPermissionsVector;
00365 std::vector<uint64_t> UsersUserIdVector;
00366 std::vector<time_t> UsersLastLoginAttemptVector, UsersAccountCreatedTimeVector, UsersLastModifiedTimeVector;
00367 std::vector<uint8_t> UsersLoginFailureCountVector;
00368 uint64_t usersNextUserId_;
00369 enum {
00370 USERS_LOGIN_HISTORY_SIZE = 20,
00371 USERS_GLOBAL_HISTORY_SIZE = 1000,
00372 USERS_MAX_LOGIN_FAILURES = 20,
00373 };
00374 std::string usersUsernameWithLock_;
00375
00376 std::vector<std::string> UsersLoggedOutUsernames_;
00377
00378
00379
00380 std::vector<std::string> HashesVector;
00381 std::vector<time_t> HashesAccessTimeVector;
00382
00383 enum {
00384 IP_BLACKLIST_COUNT_THRESHOLD = 200,
00385 };
00386 std::map<std::string , uint32_t > ipBlacklistCounts_;
00387 };
00388
00389 }
00390
00391 #endif