X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fcore.h;h=01bf477fbda0f2b2e52394ee9fcaed4e7164b940;hp=ff226a8fdd5434e4959bc295c84f3b0409552153;hb=aec9c711900a443bfa7860fa86c6e9c86b81a3e7;hpb=931e5280abc6738f94ac052af2a7e31e82487cf1 diff --git a/src/core/core.h b/src/core/core.h index ff226a8f..01bf477f 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2016 by the Quassel Project * + * Copyright (C) 2005-2018 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -18,10 +18,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef CORE_H -#define CORE_H +#pragma once + +#include +#include #include +#include #include #include #include @@ -36,6 +39,7 @@ #include "authenticator.h" #include "bufferinfo.h" +#include "deferredptr.h" #include "message.h" #include "oidentdconfiggenerator.h" #include "sessionthread.h" @@ -44,10 +48,12 @@ class CoreAuthHandler; class CoreSession; -struct NetworkInfo; +class InternalPeer; class SessionThread; class SignalProxy; +struct NetworkInfo; + class AbstractSqlMigrationReader; class AbstractSqlMigrationWriter; @@ -57,10 +63,9 @@ class Core : public QObject public: static Core *instance(); - static void destroy(); - static void saveState(); - static void restoreState(); + Core(); + ~Core() override; /*** Storage access ***/ // These methods are threadsafe. @@ -84,15 +89,26 @@ public: static inline UserId authenticateUser(const QString &userName, const QString &password) { return instance()->_authenticator->validateUser(userName, password); } - + //! Add a new user, exposed so auth providers can call this without being the storage. /** * \param userName The user's login name * \param password The user's uncrypted password + * \param authenticator The name of the auth provider service used to log the user in, defaults to "Database". * \return The user's ID if valid; 0 otherwise */ - static inline UserId addUser(const QString &userName, const QString &password) { - return instance()->_storage->addUser(userName, password); + static inline UserId addUser(const QString &userName, const QString &password, const QString &authenticator = "Database") { + return instance()->_storage->addUser(userName, password, authenticator); + } + + //! Does a comparison test against the authenticator in the database and the authenticator currently in use for a UserID. + /** + * \param userid The user's ID (note: not login name). + * \param authenticator The name of the auth provider service used to log the user in, defaults to "Database". + * \return True if the userid was configured with the passed authenticator, false otherwise. + */ + static inline bool checkAuthProvider(const UserId userid, const QString &authenticator) { + return instance()->_storage->getUserAuthenticator(userid) == authenticator; } //! Change a user's password @@ -103,6 +119,13 @@ public: */ static bool changeUserPassword(UserId userId, const QString &password); + //! Check if we can change a user password. + /** + * \param userID The user's ID + * \return true, if we can change their password, false otherwise + */ + static bool canChangeUserPassword(UserId userId); + //! Store a user setting persistently /** * \param userId The users Id @@ -252,6 +275,33 @@ public: } + //! Get a hash of buffers with their ciphers for a given network + /** The keys are channel names and values are ciphers (possibly empty) + * \note This method is threadsafe + * + * \param user The id of the networks owner + * \param networkId The Id of the network + */ + static inline QHash bufferCiphers(UserId user, const NetworkId &networkId) + { + return instance()->_storage->bufferCiphers(user, networkId); + } + + + //! Update the cipher of a buffer + /** \note This method is threadsafe + * + * \param user The Id of the networks owner + * \param networkId The Id of the network + * \param bufferName The Cname of the buffer + * \param cipher The cipher for the buffer + */ + static inline void setBufferCipher(UserId user, const NetworkId &networkId, const QString &bufferName, const QByteArray &cipher) + { + return instance()->_storage->setBufferCipher(user, networkId, bufferName, cipher); + } + + //! Update the key of a channel /** \note This method is threadsafe * @@ -381,6 +431,22 @@ public: } + //! Request a certain number messages stored in a given buffer, matching certain filters + /** \param buffer The buffer we request messages from + * \param first if != -1 return only messages with a MsgId >= first + * \param last if != -1 return only messages with a MsgId < last + * \param limit if != -1 limit the returned list to a max of \limit entries + * \param type The Message::Types that should be returned + * \return The requested list of messages + */ + static inline QList requestMsgsFiltered(UserId user, BufferId bufferId, MsgId first = -1, MsgId last = -1, + int limit = -1, Message::Types type = Message::Types{-1}, + Message::Flags flags = Message::Flags{-1}) + { + return instance()->_storage->requestMsgsFiltered(user, bufferId, first, last, limit, type, flags); + } + + //! Request a certain number of messages across all buffers /** \param first if != -1 return only messages with a MsgId >= first * \param last if != -1 return only messages with a MsgId < last @@ -393,6 +459,21 @@ public: } + //! Request a certain number of messages across all buffers, matching certain filters + /** \param first if != -1 return only messages with a MsgId >= first + * \param last if != -1 return only messages with a MsgId < last + * \param limit Max amount of messages + * \param type The Message::Types that should be returned + * \return The requested list of messages + */ + static inline QList requestAllMsgsFiltered(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1, + Message::Types type = Message::Types{-1}, + Message::Flags flags = Message::Flags{-1}) + { + return instance()->_storage->requestAllMsgsFiltered(user, first, last, limit, type, flags); + } + + //! Request a list of all buffers known to a user. /** This method is used to get a list of all buffers we have stored a backlog from. * \note This method is threadsafe. @@ -472,6 +553,20 @@ public: return instance()->_storage->setBufferLastSeenMsg(user, bufferId, msgId); } + //! Get the auth username associated with a userId + /** \param user The user to retrieve the username for + * \return The username for the user + */ + static inline QString getAuthUserName(UserId user) { + return instance()->_storage->getAuthUserName(user); + } + + //! Get a usable sysident for the given user in oidentd-strict mode + /** \param user The user to retrieve the sysident for + * \return The authusername + */ + QString strictSysIdent(UserId user) const; + //! Get a Hash of all last seen message ids /** This Method is called when the Quassel Core is started to restore the lastSeenMsgIds @@ -510,50 +605,96 @@ public: return instance()->_storage->bufferMarkerLineMsgIds(user); } + //! Update the BufferActivity for a Buffer + /** This Method is used to make the activity state of a Buffer persistent + * \note This method is threadsafe. + * + * \param user The Owner of that Buffer + * \param bufferId The buffer id + * \param MsgId The Message id where the marker line should be placed + */ + static inline void setBufferActivity(UserId user, BufferId bufferId, Message::Types activity) { + return instance()->_storage->setBufferActivity(user, bufferId, activity); + } - static inline QDateTime startTime() { return instance()->_startTime; } - static inline bool isConfigured() { return instance()->_configured; } - static bool sslSupported(); - /** - * Reloads SSL certificates used for connection with clients + //! Get a Hash of all buffer activity states + /** This Method is called when the Quassel Core is started to restore the BufferActivity + * \note This method is threadsafe. * - * @return True if certificates reloaded successfully, otherwise false. + * \param user The Owner of the buffers */ - static bool reloadCerts(); + static inline QHash bufferActivities(UserId user) { + return instance()->_storage->bufferActivities(user); + } - static QVariantList backendInfo(); - static QVariantList authenticatorInfo(); + //! Get the bitset of buffer activity states for a buffer + /** This method is used to load the activity state of a buffer when its last seen message changes. + * \note This method is threadsafe. + * + * \param bufferId The buffer + * \param lastSeenMsgId The last seen message + */ + static inline Message::Types bufferActivity(BufferId bufferId, MsgId lastSeenMsgId) { + return instance()->_storage->bufferActivity(bufferId, lastSeenMsgId); + } - /** - * Checks if a storage backend is the default storage backend. This - * hardcodes this information into the core (not the client). + //! Update the highlight count for a Buffer + /** This Method is used to make the highlight count state of a Buffer persistent + * \note This method is threadsafe. * - * \param backend The backend to check. + * \param user The Owner of that Buffer + * \param bufferId The buffer id + * \param MsgId The Message id where the marker line should be placed + */ + static inline void setHighlightCount(UserId user, BufferId bufferId, int highlightCount) { + return instance()->_storage->setHighlightCount(user, bufferId, highlightCount); + } + + + //! Get a Hash of all highlight count states + /** This Method is called when the Quassel Core is started to restore the highlight count + * \note This method is threadsafe. * - * @return True if storage backend is default, false otherwise. + * \param user The Owner of the buffers */ - static inline bool isStorageBackendDefault(const Storage *backend) - { - return (backend->displayName() == "SQLite") ? true : false; + static inline QHash highlightCounts(UserId user) { + return instance()->_storage->highlightCounts(user); + } + //! Get the highlight count states for a buffer + /** This method is used to load the highlight count of a buffer when its last seen message changes. + * \note This method is threadsafe. + * + * \param bufferId The buffer + * \param lastSeenMsgId The last seen message + */ + static inline int highlightCount(BufferId bufferId, MsgId lastSeenMsgId) { + return instance()->_storage->highlightCount(bufferId, lastSeenMsgId); } - static QString setup(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authBackend, const QVariantMap &authSetupMap); + static inline QDateTime startTime() { return instance()->_startTime; } + static inline bool isConfigured() { return instance()->_configured; } + + /** + * Whether or not strict ident mode is enabled, locking users' idents to Quassel username + * + * @return True if strict mode enabled, otherwise false + */ + static inline bool strictIdentEnabled() { return instance()->_strictIdentEnabled; } + + static bool sslSupported(); + + static QVariantList backendInfo(); + static QVariantList authenticatorInfo(); - static inline QTimer &syncTimer() { return instance()->_storageSyncTimer; } + static QString setup(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authenticator, const QVariantMap &authSetupMap); + + static inline QTimer *syncTimer() { return &instance()->_storageSyncTimer; } inline OidentdConfigGenerator *oidentdConfigGenerator() const { return _oidentdConfigGenerator; } static const int AddClientEventId; -public slots: - //! Make storage data persistent - /** \note This method is threadsafe. - */ - void syncStorage(); - void setupInternalClientSession(InternalPeer *clientConnection); - QString setupCore(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authBackend, const QVariantMap &authSetupMap); - signals: //! Sent when a BufferInfo is updated in storage. void bufferInfoUpdated(UserId user, const BufferInfo &info); @@ -561,8 +702,33 @@ signals: //! Relay from CoreSession::sessionState(). Used for internal connection only void sessionState(const Protocol::SessionState &sessionState); + //! Emitted when database schema upgrade starts or ends + void dbUpgradeInProgress(bool inProgress); + +public slots: + bool init(); + + /** Persist storage. + * + * @note This method is threadsafe. + */ + void syncStorage(); + + /** + * Reload SSL certificates used for connection with clients. + * + * @return True if certificates reloaded successfully, otherwise false. + */ + bool reloadCerts(); + + void cacheSysIdent(); + + QString setupCore(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authenticator, const QVariantMap &authSetupMap); + + void connectInternalPeer(QPointer peer); + protected: - virtual void customEvent(QEvent *event); + void customEvent(QEvent *event) override; private slots: bool startListening(); @@ -570,48 +736,59 @@ private slots: void incomingConnection(); void clientDisconnected(); - bool initStorage(const QString &backend, const QVariantMap &settings, bool setup = false); - bool initAuthenticator(const QString &backend, const QVariantMap &settings, bool setup = false); - + bool initStorage(const QString &backend, const QVariantMap &settings, + const QProcessEnvironment &environment, bool loadFromEnvironment, + bool setup = false); + bool initAuthenticator(const QString &backend, const QVariantMap &settings, + const QProcessEnvironment &environment, bool loadFromEnvironment, + bool setup = false); + void socketError(QAbstractSocket::SocketError err, const QString &errorString); void setupClientSession(RemotePeer *, UserId); bool changeUserPass(const QString &username); private: - Core(); - ~Core(); - void init(); - static Core *instanceptr; - SessionThread *sessionForUser(UserId userId, bool restoreState = false); void addClientHelper(RemotePeer *peer, UserId uid); //void processCoreSetup(QTcpSocket *socket, QVariantMap &msg); QString setupCoreForInternalUsage(); + void setupInternalClientSession(QPointer peer); + + bool createUser(); + + template + void registerStorageBackend(); + + template + void registerAuthenticator(); void registerStorageBackends(); - bool registerStorageBackend(Storage *); - void unregisterStorageBackends(); - void unregisterStorageBackend(Storage *); - - void registerAuthenticatorBackends(); - bool registerAuthenticatorBackend(Authenticator *); - void unregisterAuthenticatorBackends(); - void unregisterAuthenticatorBackend(Authenticator *); - + void registerAuthenticators(); + + DeferredSharedPtr storageBackend(const QString& backendId) const; + DeferredSharedPtr authenticator(const QString& authenticatorId) const; + bool selectBackend(const QString &backend); - bool createUser(); + bool selectAuthenticator(const QString &backend); + bool saveBackendSettings(const QString &backend, const QVariantMap &settings); - void saveAuthBackendSettings(const QString &backend, const QVariantMap &settings); - QVariantMap promptForSettings(const Storage *storage); + void saveAuthenticatorSettings(const QString &backend, const QVariantMap &settings); + + void saveState(); + void restoreState(); + + template + QVariantMap promptForSettings(const Backend *backend); private: + static Core *_instance; QSet _connectingClients; QHash _sessions; + DeferredSharedPtr _storage; ///< Active storage backend + DeferredSharedPtr _authenticator; ///< Active authenticator + QMap _authUserNames; - // Have both a storage backend and an authenticator backend. - Storage *_storage; - Authenticator *_authenticator; QTimer _storageSyncTimer; #ifdef HAVE_SSL @@ -620,21 +797,24 @@ private: QTcpServer _server, _v6server; #endif - OidentdConfigGenerator *_oidentdConfigGenerator; + OidentdConfigGenerator *_oidentdConfigGenerator {nullptr}; - QHash _storageBackends; - QHash _authenticatorBackends; + std::vector> _registeredStorageBackends; + std::vector> _registeredAuthenticators; QDateTime _startTime; - bool _configured; + bool _initialized{false}; + bool _configured{false}; + + QPointer _pendingInternalConnection; - static AbstractSqlMigrationReader *getMigrationReader(Storage *storage); - static AbstractSqlMigrationWriter *getMigrationWriter(Storage *storage); + /// Whether or not strict ident mode is enabled, locking users' idents to Quassel username + bool _strictIdentEnabled; + + static std::unique_ptr getMigrationReader(Storage *storage); + static std::unique_ptr getMigrationWriter(Storage *storage); static void stdInEcho(bool on); static inline void enableStdInEcho() { stdInEcho(true); } static inline void disableStdInEcho() { stdInEcho(false); } }; - - -#endif