qa: Remove lots of superfluous semicolons
[quassel.git] / src / core / core.h
index fd08278..021d9c9 100644 (file)
@@ -24,6 +24,7 @@
 #include <vector>
 
 #include <QDateTime>
+#include <QPointer>
 #include <QString>
 #include <QVariant>
 #include <QTimer>
 #include "authenticator.h"
 #include "bufferinfo.h"
 #include "deferredptr.h"
+#include "identserver.h"
 #include "message.h"
 #include "oidentdconfiggenerator.h"
 #include "sessionthread.h"
+#include "singleton.h"
 #include "storage.h"
 #include "types.h"
 
 class CoreAuthHandler;
 class CoreSession;
-struct NetworkInfo;
+class InternalPeer;
 class SessionThread;
 class SignalProxy;
 
+struct NetworkInfo;
+
 class AbstractSqlMigrationReader;
 class AbstractSqlMigrationWriter;
 
-class Core : public QObject
+class Core : public QObject, public Singleton<Core>
 {
     Q_OBJECT
 
 public:
-    static Core *instance();
-    static void destroy();
+    Core();
+    ~Core() override;
+
+    void init();
+
+    /**
+     * Shuts down active core sessions, saves state and emits the shutdownComplete() signal afterwards.
+     */
+    void shutdown();
 
-    static void saveState();
-    static void restoreState();
 
     /*** Storage access ***/
     // These methods are threadsafe.
@@ -273,6 +283,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<QString, QByteArray> 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
      *
@@ -402,6 +439,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<Message> 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
@@ -414,6 +467,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<Message> 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.
@@ -494,6 +562,13 @@ public:
     }
 
 
+    //! 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
      *  \note This method is threadsafe.
@@ -565,36 +640,63 @@ public:
         return instance()->_storage->bufferActivity(bufferId, lastSeenMsgId);
     }
 
+    //! 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 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.
+     *
+     * \param user      The Owner of the buffers
+     */
+    static inline QHash<BufferId, int> 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 inline QDateTime startTime() { return instance()->_startTime; }
     static inline bool isConfigured() { return instance()->_configured; }
-    static bool sslSupported();
 
     /**
-     * Reloads SSL certificates used for connection with clients
+     * Whether or not strict ident mode is enabled, locking users' idents to Quassel username
      *
-     * @return True if certificates reloaded successfully, otherwise false.
+     * @return True if strict mode enabled, otherwise false
      */
-    static bool reloadCerts();
+    static inline bool strictIdentEnabled() { return instance()->_strictIdentEnabled; }
+
+    static bool sslSupported();
 
     static QVariantList backendInfo();
     static QVariantList authenticatorInfo();
 
     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; }
+    static inline QTimer *syncTimer() { return &instance()->_storageSyncTimer; }
 
     inline OidentdConfigGenerator *oidentdConfigGenerator() const { return _oidentdConfigGenerator; }
+    inline IdentServer *identServer() const { return _identServer; }
 
     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 &authenticator, const QVariantMap &authSetupMap);
-
 signals:
     //! Sent when a BufferInfo is updated in storage.
     void bufferInfoUpdated(UserId user, const BufferInfo &info);
@@ -602,8 +704,39 @@ 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);
+
+    //! Emitted when a fatal error was encountered during async initialization
+    void exitRequested(int exitCode, const QString &reason);
+
+    //! Emitted once core shutdown is complete
+    void shutdownComplete();
+
+public slots:
+    void initAsync();
+
+    /** 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<InternalPeer> peer);
+
 protected:
-    virtual void customEvent(QEvent *event);
+    void customEvent(QEvent *event) override;
 
 private slots:
     bool startListening();
@@ -611,24 +744,26 @@ 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;
+    void onSessionShutdown(SessionThread *session);
 
+private:
     SessionThread *sessionForUser(UserId userId, bool restoreState = false);
     void addClientHelper(RemotePeer *peer, UserId uid);
     //void processCoreSetup(QTcpSocket *socket, QVariantMap &msg);
     QString setupCoreForInternalUsage();
+    void setupInternalClientSession(QPointer<InternalPeer> peer);
 
     bool createUser();
 
@@ -650,14 +785,20 @@ private:
     bool saveBackendSettings(const QString &backend, const QVariantMap &settings);
     void saveAuthenticatorSettings(const QString &backend, const QVariantMap &settings);
 
+    void saveState();
+    void restoreState();
+
     template<typename Backend>
     QVariantMap promptForSettings(const Backend *backend);
 
 private:
+    static Core *_instance;
     QSet<CoreAuthHandler *> _connectingClients;
     QHash<UserId, SessionThread *> _sessions;
     DeferredSharedPtr<Storage>       _storage;        ///< Active storage backend
     DeferredSharedPtr<Authenticator> _authenticator;  ///< Active authenticator
+    QMap<UserId, QString> _authUserNames;
+
     QTimer _storageSyncTimer;
 
 #ifdef HAVE_SSL
@@ -673,7 +814,15 @@ private:
 
     QDateTime _startTime;
 
-    bool _configured;
+    IdentServer *_identServer {nullptr};
+
+    bool _initialized{false};
+    bool _configured{false};
+
+    QPointer<InternalPeer> _pendingInternalConnection;
+
+    /// Whether or not strict ident mode is enabled, locking users' idents to Quassel username
+    bool _strictIdentEnabled;
 
     static std::unique_ptr<AbstractSqlMigrationReader> getMigrationReader(Storage *storage);
     static std::unique_ptr<AbstractSqlMigrationWriter> getMigrationWriter(Storage *storage);