otsdaq  v2_00_00
WebUsers.h
1 #ifndef _ots_Utilities_WebUsers_h_
2 #define _ots_Utilities_WebUsers_h_
3 
4 #include "otsdaq-core/MessageFacility/MessageFacility.h"
5 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
6 #include "otsdaq-core/SOAPUtilities/SOAPMessenger.h"
7 
8 #include <string>
9 #include <vector>
10 #include <iostream>
11 #include <unordered_map>
12 
13 #define WEB_LOGIN_DB_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/LoginData/"
14 #define WEB_LOGIN_CERTDATA_PATH std::string(getenv("CERT_DATA_PATH"))
15 #define HASHES_DB_PATH "HashesData/"
16 #define USERS_DB_PATH "UsersData/"
17 #define USERS_LOGIN_HISTORY_PATH USERS_DB_PATH + "UserLoginHistoryData/"
18 #define USERS_PREFERENCES_PATH USERS_DB_PATH + "UserPreferencesData/"
19 #define TOOLTIP_DB_PATH USERS_DB_PATH + "/TooltipData/"
20 
21 
22 
23 //TODO -- include IP address handling!? Note from RAR -- I think IP addresses are being recorded now upon login.
24 
25 namespace ots
26 {
27 
28 class HttpXmlDocument;
29 
30 class WebUsers
31 {
32 public:
33  WebUsers();
34 
35  enum {
36  SESSION_ID_LENGTH = 512,
37  COOKIE_CODE_LENGTH = 512,
38  NOT_FOUND_IN_DATABASE = uint64_t(-1),
39  USERNAME_LENGTH = 4,
40  DISPLAY_NAME_LENGTH = 4,
41  };
42 
43  enum {
44  DB_SAVE_OPEN_AND_CLOSE,
45  DB_SAVE_OPEN,
46  DB_SAVE_CLOSE
47  };
48 
49  enum {
50  DB_USERS,
51  DB_HASHES
52  };
53 
54  enum {
55  MOD_TYPE_UPDATE,
56  MOD_TYPE_ADD,
57  MOD_TYPE_DELETE
58  };
59 
60  static const std::string DEFAULT_ADMIN_USERNAME;
61  static const std::string DEFAULT_ADMIN_DISPLAY_NAME;
62  static const std::string DEFAULT_ADMIN_EMAIL;
63  static const std::string DEFAULT_ITERATOR_USERNAME;
64  static const std::string DEFAULT_STATECHANGER_USERNAME;
65 
66  static const std::string REQ_NO_LOGIN_RESPONSE;
67  static const std::string REQ_NO_PERMISSION_RESPONSE;
68  static const std::string REQ_USER_LOCKOUT_RESPONSE;
69 
70  static const std::string SECURITY_TYPE_NONE;
71  static const std::string SECURITY_TYPE_DIGEST_ACCESS;
72 
73  bool createNewAccount (std::string username, std::string displayName, std::string email);
74  void cleanupExpiredEntries (std::vector<std::string> *loggedOutUsernames = 0);
75  std::string createNewLoginSession (std::string uuid, std::string ip = "0");
76 
77  uint64_t attemptActiveSession(std::string uuid, std::string &jumbledUser, std::string jumbledPw, std::string &newAccountCode);
78  uint64_t attemptActiveSessionWithCert(std::string uuid, std::string &jumbledEmail, std::string &cookieCode, std::string& username);
79  uint64_t isCookieCodeActiveForLogin (std::string uuid, std::string &cookieCode,std::string &username);
80  bool cookieCodeIsActiveForRequest (std::string &cookieCode, uint8_t *userPermissions = 0, uint64_t *uid = 0, std::string ip = "0", bool refresh = true, std::string *userWithLock = 0);
81  uint64_t cookieCodeLogout (std::string cookieCode, bool logoutOtherUserSessions, uint64_t *uid = 0, std::string ip = "0");
82 
83  std::string getUsersDisplayName (uint64_t uid);
84  std::string getUsersUsername (uint64_t uid);
85  uint64_t getActiveSessionCountForUser (uint64_t uid);
86  uint8_t getPermissionsForUser (uint64_t uid);
87  void insertSettingsForUser (uint64_t uid, HttpXmlDocument *xmldoc,bool includeAccounts=false);
88  std::string getGenericPreference (uint64_t uid, const std::string &preferenceName, HttpXmlDocument *xmldoc = 0) const;
89 
90  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);
91  void setGenericPreference (uint64_t uid, const std::string &preferenceName, const std::string &preferenceValue);
92  static void tooltipCheckForUsername (const std::string& username, HttpXmlDocument *xmldoc, const std::string &srcFile, const std::string &srcFunc, const std::string &srcId);
93  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);
94 
95  void modifyAccountSettings (uint64_t uid_master, uint8_t cmd_type, std::string username, std::string displayname, std::string email, std::string permissions);
96  bool setUserWithLock (uint64_t uid_master, bool lock, std::string username);
97  std::string getUserWithLock () { return usersUsernameWithLock_; }
98 
99  std::string getActiveUsersString ();
100 
101  bool getUserInfoForCookie (std::string &cookieCode, std::string *userName, std::string *displayName = 0, uint64_t *activeSessionIndex = 0);
102 
103  bool isUsernameActive (std::string username) const;
104  bool isUserIdActive (uint64_t uid) const;
105  uint64_t getAdminUserID ();
106  std::string getSecurity ();
107 
108  static void deleteUserData ();
109  static void resetAllUserTooltips (const std::string &userNeedle = "*");
110 
111  static void NACDisplayThread (std::string nac, std::string user);
112 
113  void saveActiveSessions ();
114  void loadActiveSessions ();
115 
116 private:
117  void loadSecuritySelection ();
118  void loadUserWithLock ();
119  unsigned int hexByteStrToInt (const char *h);
120  void intToHexStr (uint8_t i, char *h);
121  std::string sha512 (std::string user, std::string password, std::string &salt);
122  std::string dejumble (std::string jumbledUser, std::string sessionId);
123  std::string createNewActiveSession (uint64_t uid,std::string ip = "0", uint64_t asIndex = 0);
124  bool addToHashesDatabase (std::string hash);
125  std::string genCookieCode ();
126  std::string refreshCookieCode (unsigned int i, bool enableRefresh = true);
127  void removeActiveSessionEntry (unsigned int i);
128  void removeLoginSessionEntry (unsigned int i);
129  bool deleteAccount (std::string username, std::string displayName);
130 
131  void saveToDatabase (FILE * fp, std::string field, std::string value, uint8_t type = DB_SAVE_OPEN_AND_CLOSE, bool addNewLine = true);
132  bool saveDatabaseToFile (uint8_t db);
133  bool loadDatabases ();
134 
135  uint64_t searchUsersDatabaseForUsername (std::string username) const;
136  uint64_t searchUsersDatabaseForUserEmail (std::string useremail) const;
137  uint64_t searchUsersDatabaseForUserId (uint64_t uid) const;
138  uint64_t searchLoginSessionDatabaseForUUID (std::string uuid) const;
139  uint64_t searchHashesDatabaseForHash (std::string hash);
140  uint64_t searchActiveSessionDatabaseForCookie (std::string cookieCode) const;
141 
142  static std::string getTooltipFilename (const std::string& username, const std::string &srcFile, const std::string &srcFunc, const std::string &srcId);
143 
144  std::unordered_map<std::string, std::string> certFingerprints_;
145  std::string getUserEmailFromFingerprint(std::string fingerprint);
146 
147  std::vector<std::string> UsersDatabaseEntryFields,HashesDatabaseEntryFields;
148  bool CareAboutCookieCodes_;
149  std::string securityType_;
150 
151  //"Login Session" database associations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
152  //Generate random sessionId when receive a unique user ID (UUID)
153  //reject UUID that have been used recently (e.g. last 5 minutes)
154  //Maintain list of active sessionIds and associated UUID
155  //remove from list if been idle after some time or login attempts (e.g. 5 minutes or 3 login attempts)
156  //maybe track IP address, to block multiple failed login attempts from same IP.
157  //Use sessionId to un-jumble login attempts, lookup using UUID
158  std::vector<std::string> LoginSessionIdVector, LoginSessionUUIDVector, LoginSessionIpVector;
159  std::vector<time_t> LoginSessionStartTimeVector;
160  std::vector<uint8_t> LoginSessionAttemptsVector;
161  enum {
162  LOGIN_SESSION_EXPIRATION_TIME = 5*60, //5 minutes
163  LOGIN_SESSION_ATTEMPTS_MAX = 5, //5 attempts on same session, forces new session
164  };
165 
166  //"Active Session" database associations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167  //Maintain list of valid cookieCodes and associated user
168  //all request must come with a valid cookieCode, else server fails request
169  //On logout request, invalidate cookieCode
170  //cookieCode expires after some idle time (e.g. 5 minutes) and
171  //is renewed and possibly changed each request
172  //"single user - multiple locations" issue resolved using ActiveSessionIndex
173  //where each independent login starts a new thread of cookieCodes tagged with ActiveSessionIndex
174  //if cookieCode not refreshed, then return most recent cookie code
175  std::vector<std::string> ActiveSessionCookieCodeVector, ActiveSessionIpVector;
176  std::vector<uint64_t> ActiveSessionUserIdVector, ActiveSessionIndex;
177  std::vector<time_t> ActiveSessionStartTimeVector;
178  enum {
179  ACTIVE_SESSION_EXPIRATION_TIME = 120*60, //120 minutes, cookie is changed every half period of ACTIVE_SESSION_EXPIRATION_TIME
180  ACTIVE_SESSION_COOKIE_OVERLAP_TIME = 10*60, //10 minutes of overlap when new cookie is generated
181  ACTIVE_SESSION_STALE_COOKIE_LIMIT = 10, //10 stale cookies allowed for each active user
182  };
183 
184  //"Users" database associations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185  //Maintain list of acceptable Usernames and associate:
186  //permissions index (e.g. users, experts, masters) 0 to 255
187  //0 := account inactive, not allowed to login (could be due to too many failed login attempts)
188  //Last Login attempt time, and last USERS_LOGIN_HISTORY_SIZE successful logins
189  //Name to display
190  //random salt, before first login salt is empty string ""
191  //Keep count of login attempt failures. Limit failures per unit time (e.g. 5 per hour)
192  //Preferences (e.g. color scheme, etc)
193  //Username appends to preferences file, and login history file
194  //UsersLastModifierUsernameVector - is username of last master user to modify something about account
195  //UsersLastModifierTimeVector - is time of last modify by a master user
196  std::vector<std::string> UsersUsernameVector, UsersUserEmailVector, UsersDisplayNameVector, UsersSaltVector, UsersLastModifierUsernameVector;
197  std::vector<uint8_t> UsersPermissionsVector;
198  std::vector<uint64_t> UsersUserIdVector;
199  std::vector<time_t> UsersLastLoginAttemptVector, UsersAccountCreatedTimeVector, UsersLastModifiedTimeVector;
200  std::vector<uint8_t> UsersLoginFailureCountVector;
201  uint64_t usersNextUserId_;
202  enum {
203  USERS_LOGIN_HISTORY_SIZE = 20,
204  USERS_GLOBAL_HISTORY_SIZE = 1000,
205  USERS_MAX_LOGIN_FAILURES = 20,
206  };
207  std::string usersUsernameWithLock_;
208 
209  std::vector<std::string> UsersLoggedOutUsernames_;
210 
211  //"Hashes" database associations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212  //Maintain list of acceptable encoded (SHA-512) salt+user+pw's
213  std::vector<std::string> HashesVector;
214  std::vector<time_t> HashesAccessTimeVector;
215 };
216 
217 }
218 
219 #endif