#ifndef __UserInfo_h_ #define __UserInfo_h_ #include "../shared/ThreadClass.h" #include "../shared/TwoDLookup.h" #include "../shared/DatabaseWithRetry.h" // If you need to track the user info in a new program, please check out // ../oddsmaker/UserInfo.C. That is perfect for a program that only listens // to the micro_proxy. For historical reasons this program has to listen to // the micro_proxy and to some direct connections. class UserInfoThread : public ThreadClass, private ThreadMonitor::Extra { private: enum { mtLogin, mtReload, mtShowAllUsers, mtDisconnectUser, mtDisconnectAll, mtAddLoginListener, mtProxyLogin, mtMultiCast, mtQuit }; RequestQueue _incoming; DatabaseWithRetry _database; UserInfoThread(); ~UserInfoThread(); void loadFile(std::string fileName = ""); static UserInfoThread *instance; pthread_mutex_t _mutex; TwoDArray _data; // Protected by _mutex std::map< SocketInfo *, std::string > _socketToUser; // Protected by _mutex std::map< std::string, SocketInfo * > _userToSocket; struct LoginInfo { SocketInfo *socket; std::string username; std::string password; std::string sessionId; ExternalRequest::MessageId responseMessageId; LoginInfo() : socket(NULL) { } LoginInfo(ExternalRequest *request); }; void loginRequest(ExternalRequest *request); void tryLogin(LoginInfo const &loginInfo); void finishLogin(SocketInfo *socket, std::string const &username); void proxyLoginRequest(ExternalRequest *request); std::string _resetCounter; int64_t _sessionCounter; void resetSessions(); std::string getSessionId(); struct LoginListener { RequestListener *listener; int callbackId; }; std::vector< LoginListener > _loginListeners; class AddLoginListener : public Request { public: const LoginListener loginListener; AddLoginListener(LoginListener const &loginListener) : Request(NULL), loginListener(loginListener) { callbackId = mtAddLoginListener; } }; // From ThreadMonitor::Extra virtual std::string getInfoForThreadMonitor(); protected: virtual void threadFunction(); public: // All public methods are thread safe. std::string getUsername(SocketInfo *socket); void getInfo(SocketInfo *socket, PropertyList &info); std::string getField(SocketInfo *socket, std::string const &name); bool loggedIn(SocketInfo *socket); bool hasAdminPermission(SocketInfo *socket); // If someone logs in directly then the CSV file gives us information about // that user, like the categories of alerts he's allowed to see. If he // logs in via the micro_proxy, then we have no such info, and we should // use a reasonable default. bool comesFromProxy(SocketInfo *socket); class Login : public Request { public: const std::string username; Login(SocketInfo *socket, std::string const &username) : Request(socket), username(username) { } }; void addLoginListener(RequestListener *listener, int callbackId); static UserInfoThread &getInstance(); static void init() { getInstance(); } }; #endif