01bf477fbda0f2b2e52394ee9fcaed4e7164b940
[quassel.git] / src / core / core.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2018 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #pragma once
22
23 #include <memory>
24 #include <vector>
25
26 #include <QDateTime>
27 #include <QPointer>
28 #include <QString>
29 #include <QVariant>
30 #include <QTimer>
31
32 #ifdef HAVE_SSL
33 #  include <QSslSocket>
34 #  include "sslserver.h"
35 #else
36 #  include <QTcpSocket>
37 #  include <QTcpServer>
38 #endif
39
40 #include "authenticator.h"
41 #include "bufferinfo.h"
42 #include "deferredptr.h"
43 #include "message.h"
44 #include "oidentdconfiggenerator.h"
45 #include "sessionthread.h"
46 #include "storage.h"
47 #include "types.h"
48
49 class CoreAuthHandler;
50 class CoreSession;
51 class InternalPeer;
52 class SessionThread;
53 class SignalProxy;
54
55 struct NetworkInfo;
56
57 class AbstractSqlMigrationReader;
58 class AbstractSqlMigrationWriter;
59
60 class Core : public QObject
61 {
62     Q_OBJECT
63
64 public:
65     static Core *instance();
66
67     Core();
68     ~Core() override;
69
70     /*** Storage access ***/
71     // These methods are threadsafe.
72
73     //! Validate user
74     /**
75      * \param userName The user's login name
76      * \param password The user's uncrypted password
77      * \return The user's ID if valid; 0 otherwise
78      */
79     static inline UserId validateUser(const QString &userName, const QString &password) {
80         return instance()->_storage->validateUser(userName, password);
81     }
82
83     //! Authenticate user against auth backend
84     /**
85      * \param userName The user's login name
86      * \param password The user's uncrypted password
87      * \return The user's ID if valid; 0 otherwise
88      */
89     static inline UserId authenticateUser(const QString &userName, const QString &password) {
90         return instance()->_authenticator->validateUser(userName, password);
91     }
92
93     //! Add a new user, exposed so auth providers can call this without being the storage.
94     /**
95      * \param userName The user's login name
96      * \param password The user's uncrypted password
97      * \param authenticator The name of the auth provider service used to log the user in, defaults to "Database".
98      * \return The user's ID if valid; 0 otherwise
99      */
100     static inline UserId addUser(const QString &userName, const QString &password, const QString &authenticator = "Database") {
101         return instance()->_storage->addUser(userName, password, authenticator);
102     }
103
104     //! Does a comparison test against the authenticator in the database and the authenticator currently in use for a UserID.
105     /**
106      * \param userid The user's ID (note: not login name).
107      * \param authenticator The name of the auth provider service used to log the user in, defaults to "Database".
108      * \return True if the userid was configured with the passed authenticator, false otherwise.
109      */
110     static inline bool checkAuthProvider(const UserId userid, const QString &authenticator) {
111         return instance()->_storage->getUserAuthenticator(userid) == authenticator;
112     }
113
114     //! Change a user's password
115     /**
116      * \param userId     The user's ID
117      * \param password   The user's unencrypted new password
118      * \return true, if the password change was successful
119      */
120     static bool changeUserPassword(UserId userId, const QString &password);
121
122     //! Check if we can change a user password.
123     /**
124      * \param userID     The user's ID
125      * \return true, if we can change their password, false otherwise
126      */
127     static bool canChangeUserPassword(UserId userId);
128
129     //! Store a user setting persistently
130     /**
131      * \param userId       The users Id
132      * \param settingName  The Name of the Setting
133      * \param data         The Value
134      */
135     static inline void setUserSetting(UserId userId, const QString &settingName, const QVariant &data)
136     {
137         instance()->_storage->setUserSetting(userId, settingName, data);
138     }
139
140
141     //! Retrieve a persistent user setting
142     /**
143      * \param userId       The users Id
144      * \param settingName  The Name of the Setting
145      * \param defaultValue Value to return in case it's unset.
146      * \return the Value of the Setting or the default value if it is unset.
147      */
148     static inline QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &defaultValue = QVariant())
149     {
150         return instance()->_storage->getUserSetting(userId, settingName, defaultValue);
151     }
152
153
154     /* Identity handling */
155     static inline IdentityId createIdentity(UserId user, CoreIdentity &identity)
156     {
157         return instance()->_storage->createIdentity(user, identity);
158     }
159
160
161     static bool updateIdentity(UserId user, const CoreIdentity &identity)
162     {
163         return instance()->_storage->updateIdentity(user, identity);
164     }
165
166
167     static void removeIdentity(UserId user, IdentityId identityId)
168     {
169         instance()->_storage->removeIdentity(user, identityId);
170     }
171
172
173     static QList<CoreIdentity> identities(UserId user)
174     {
175         return instance()->_storage->identities(user);
176     }
177
178
179     //! Create a Network in the Storage and store it's Id in the given NetworkInfo
180     /** \note This method is thredsafe.
181      *
182      *  \param user        The core user
183      *  \param networkInfo a NetworkInfo definition to store the newly created ID in
184      *  \return true if successfull.
185      */
186     static bool createNetwork(UserId user, NetworkInfo &info);
187
188     //! Apply the changes to NetworkInfo info to the storage engine
189     /** \note This method is thredsafe.
190      *
191      *  \param user        The core user
192      *  \param networkInfo The Updated NetworkInfo
193      *  \return true if successfull.
194      */
195     static inline bool updateNetwork(UserId user, const NetworkInfo &info)
196     {
197         return instance()->_storage->updateNetwork(user, info);
198     }
199
200
201     //! Permanently remove a Network and all the data associated with it.
202     /** \note This method is thredsafe.
203      *
204      *  \param user        The core user
205      *  \param networkId   The network to delete
206      *  \return true if successfull.
207      */
208     static inline bool removeNetwork(UserId user, const NetworkId &networkId)
209     {
210         return instance()->_storage->removeNetwork(user, networkId);
211     }
212
213
214     //! Returns a list of all NetworkInfos for the given UserId user
215     /** \note This method is thredsafe.
216      *
217      *  \param user        The core user
218      *  \return QList<NetworkInfo>.
219      */
220     static inline QList<NetworkInfo> networks(UserId user)
221     {
222         return instance()->_storage->networks(user);
223     }
224
225
226     //! Get a list of Networks to restore
227     /** Return a list of networks the user was connected at the time of core shutdown
228      *  \note This method is threadsafe.
229      *
230      *  \param user  The User Id in question
231      */
232     static inline QList<NetworkId> connectedNetworks(UserId user)
233     {
234         return instance()->_storage->connectedNetworks(user);
235     }
236
237
238     //! Update the connected state of a network
239     /** \note This method is threadsafe
240      *
241      *  \param user        The Id of the networks owner
242      *  \param networkId   The Id of the network
243      *  \param isConnected whether the network is connected or not
244      */
245     static inline void setNetworkConnected(UserId user, const NetworkId &networkId, bool isConnected)
246     {
247         return instance()->_storage->setNetworkConnected(user, networkId, isConnected);
248     }
249
250
251     //! Get a hash of channels with their channel keys for a given network
252     /** The keys are channel names and values are passwords (possibly empty)
253      *  \note This method is threadsafe
254      *
255      *  \param user       The id of the networks owner
256      *  \param networkId  The Id of the network
257      */
258     static inline QHash<QString, QString> persistentChannels(UserId user, const NetworkId &networkId)
259     {
260         return instance()->_storage->persistentChannels(user, networkId);
261     }
262
263
264     //! Update the connected state of a channel
265     /** \note This method is threadsafe
266      *
267      *  \param user       The Id of the networks owner
268      *  \param networkId  The Id of the network
269      *  \param channel    The name of the channel
270      *  \param isJoined   whether the channel is connected or not
271      */
272     static inline void setChannelPersistent(UserId user, const NetworkId &networkId, const QString &channel, bool isJoined)
273     {
274         return instance()->_storage->setChannelPersistent(user, networkId, channel, isJoined);
275     }
276
277
278     //! Get a hash of buffers with their ciphers for a given network
279     /** The keys are channel names and values are ciphers (possibly empty)
280      *  \note This method is threadsafe
281      *
282      *  \param user       The id of the networks owner
283      *  \param networkId  The Id of the network
284      */
285     static inline QHash<QString, QByteArray> bufferCiphers(UserId user, const NetworkId &networkId)
286     {
287         return instance()->_storage->bufferCiphers(user, networkId);
288     }
289
290
291     //! Update the cipher of a buffer
292     /** \note This method is threadsafe
293      *
294      *  \param user        The Id of the networks owner
295      *  \param networkId   The Id of the network
296      *  \param bufferName The Cname of the buffer
297      *  \param cipher      The cipher for the buffer
298      */
299     static inline void setBufferCipher(UserId user, const NetworkId &networkId, const QString &bufferName, const QByteArray &cipher)
300     {
301         return instance()->_storage->setBufferCipher(user, networkId, bufferName, cipher);
302     }
303
304
305     //! Update the key of a channel
306     /** \note This method is threadsafe
307      *
308      *  \param user       The Id of the networks owner
309      *  \param networkId  The Id of the network
310      *  \param channel    The name of the channel
311      *  \param key        The key of the channel (possibly empty)
312      */
313     static inline void setPersistentChannelKey(UserId user, const NetworkId &networkId, const QString &channel, const QString &key)
314     {
315         return instance()->_storage->setPersistentChannelKey(user, networkId, channel, key);
316     }
317
318
319     //! retrieve last known away message for session restore
320     /** \note This method is threadsafe
321      *
322      *  \param user       The Id of the networks owner
323      *  \param networkId  The Id of the network
324      */
325     static inline QString awayMessage(UserId user, NetworkId networkId)
326     {
327         return instance()->_storage->awayMessage(user, networkId);
328     }
329
330
331     //! Make away message persistent for session restore
332     /** \note This method is threadsafe
333      *
334      *  \param user       The Id of the networks owner
335      *  \param networkId  The Id of the network
336      *  \param awayMsg    The current away message of own user
337      */
338     static inline void setAwayMessage(UserId user, NetworkId networkId, const QString &awayMsg)
339     {
340         return instance()->_storage->setAwayMessage(user, networkId, awayMsg);
341     }
342
343
344     //! retrieve last known user mode for session restore
345     /** \note This method is threadsafe
346      *
347      *  \param user       The Id of the networks owner
348      *  \param networkId  The Id of the network
349      */
350     static inline QString userModes(UserId user, NetworkId networkId)
351     {
352         return instance()->_storage->userModes(user, networkId);
353     }
354
355
356     //! Make our user modes persistent for session restore
357     /** \note This method is threadsafe
358      *
359      *  \param user       The Id of the networks owner
360      *  \param networkId  The Id of the network
361      *  \param userModes  The current user modes of own user
362      */
363     static inline void setUserModes(UserId user, NetworkId networkId, const QString &userModes)
364     {
365         return instance()->_storage->setUserModes(user, networkId, userModes);
366     }
367
368
369     //! Get the unique BufferInfo for the given combination of network and buffername for a user.
370     /** \note This method is threadsafe.
371      *
372      *  \param user      The core user who owns this buffername
373      *  \param networkId The network id
374      *  \param type      The type of the buffer (StatusBuffer, Channel, etc.)
375      *  \param buffer    The buffer name (if empty, the net's status buffer is returned)
376      *  \param create    Whether or not the buffer should be created if it doesnt exist
377      *  \return The BufferInfo corresponding to the given network and buffer name, or 0 if not found
378      */
379     static inline BufferInfo bufferInfo(UserId user, const NetworkId &networkId, BufferInfo::Type type, const QString &buffer = "", bool create = true)
380     {
381         return instance()->_storage->bufferInfo(user, networkId, type, buffer, create);
382     }
383
384
385     //! Get the unique BufferInfo for a bufferId
386     /** \note This method is threadsafe
387      *  \param user      The core user who owns this buffername
388      *  \param bufferId  The id of the buffer
389      *  \return The BufferInfo corresponding to the given buffer id, or an invalid BufferInfo if not found.
390      */
391     static inline BufferInfo getBufferInfo(UserId user, const BufferId &bufferId)
392     {
393         return instance()->_storage->getBufferInfo(user, bufferId);
394     }
395
396
397     //! Store a Message in the storage backend and set it's unique Id.
398     /** \note This method is threadsafe.
399      *
400      *  \param message The message object to be stored
401      *  \return true on success
402      */
403     static inline bool storeMessage(Message &message)
404     {
405         return instance()->_storage->logMessage(message);
406     }
407
408
409     //! Store a list of Messages in the storage backend and set their unique Id.
410     /** \note This method is threadsafe.
411      *
412      *  \param messages The list message objects to be stored
413      *  \return true on success
414      */
415     static inline bool storeMessages(MessageList &messages)
416     {
417         return instance()->_storage->logMessages(messages);
418     }
419
420
421     //! Request a certain number messages stored in a given buffer.
422     /** \param buffer   The buffer we request messages from
423      *  \param first    if != -1 return only messages with a MsgId >= first
424      *  \param last     if != -1 return only messages with a MsgId < last
425      *  \param limit    if != -1 limit the returned list to a max of \limit entries
426      *  \return The requested list of messages
427      */
428     static inline QList<Message> requestMsgs(UserId user, BufferId bufferId, MsgId first = -1, MsgId last = -1, int limit = -1)
429     {
430         return instance()->_storage->requestMsgs(user, bufferId, first, last, limit);
431     }
432
433
434     //! Request a certain number messages stored in a given buffer, matching certain filters
435     /** \param buffer   The buffer we request messages from
436      *  \param first    if != -1 return only messages with a MsgId >= first
437      *  \param last     if != -1 return only messages with a MsgId < last
438      *  \param limit    if != -1 limit the returned list to a max of \limit entries
439      *  \param type     The Message::Types that should be returned
440      *  \return The requested list of messages
441      */
442     static inline QList<Message> requestMsgsFiltered(UserId user, BufferId bufferId, MsgId first = -1, MsgId last = -1,
443                                                      int limit = -1, Message::Types type = Message::Types{-1},
444                                                      Message::Flags flags = Message::Flags{-1})
445     {
446         return instance()->_storage->requestMsgsFiltered(user, bufferId, first, last, limit, type, flags);
447     }
448
449
450     //! Request a certain number of messages across all buffers
451     /** \param first    if != -1 return only messages with a MsgId >= first
452      *  \param last     if != -1 return only messages with a MsgId < last
453      *  \param limit    Max amount of messages
454      *  \return The requested list of messages
455      */
456     static inline QList<Message> requestAllMsgs(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1)
457     {
458         return instance()->_storage->requestAllMsgs(user, first, last, limit);
459     }
460
461
462     //! Request a certain number of messages across all buffers, matching certain filters
463     /** \param first    if != -1 return only messages with a MsgId >= first
464      *  \param last     if != -1 return only messages with a MsgId < last
465      *  \param limit    Max amount of messages
466      *  \param type     The Message::Types that should be returned
467      *  \return The requested list of messages
468      */
469     static inline QList<Message> requestAllMsgsFiltered(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1,
470                                                         Message::Types type = Message::Types{-1},
471                                                         Message::Flags flags = Message::Flags{-1})
472     {
473         return instance()->_storage->requestAllMsgsFiltered(user, first, last, limit, type, flags);
474     }
475
476
477     //! Request a list of all buffers known to a user.
478     /** This method is used to get a list of all buffers we have stored a backlog from.
479      *  \note This method is threadsafe.
480      *
481      *  \param user  The user whose buffers we request
482      *  \return A list of the BufferInfos for all buffers as requested
483      */
484     static inline QList<BufferInfo> requestBuffers(UserId user)
485     {
486         return instance()->_storage->requestBuffers(user);
487     }
488
489
490     //! Request a list of BufferIds for a given NetworkId
491     /** \note This method is threadsafe.
492      *
493      *  \param user  The user whose buffers we request
494      *  \param networkId  The NetworkId of the network in question
495      *  \return List of BufferIds belonging to the Network
496      */
497     static inline QList<BufferId> requestBufferIdsForNetwork(UserId user, NetworkId networkId)
498     {
499         return instance()->_storage->requestBufferIdsForNetwork(user, networkId);
500     }
501
502
503     //! Remove permanently a buffer and it's content from the storage backend
504     /** This call cannot be reverted!
505      *  \note This method is threadsafe.
506      *
507      *  \param user      The user who is the owner of the buffer
508      *  \param bufferId  The bufferId
509      *  \return true if successfull
510      */
511     static inline bool removeBuffer(const UserId &user, const BufferId &bufferId)
512     {
513         return instance()->_storage->removeBuffer(user, bufferId);
514     }
515
516
517     //! Rename a Buffer
518     /** \note This method is threadsafe.
519      *  \param user      The id of the buffer owner
520      *  \param bufferId  The bufferId
521      *  \param newName   The new name of the buffer
522      *  \return true if successfull
523      */
524     static inline bool renameBuffer(const UserId &user, const BufferId &bufferId, const QString &newName)
525     {
526         return instance()->_storage->renameBuffer(user, bufferId, newName);
527     }
528
529
530     //! Merge the content of two Buffers permanently. This cannot be reversed!
531     /** \note This method is threadsafe.
532      *  \param user      The id of the buffer owner
533      *  \param bufferId1 The bufferId of the remaining buffer
534      *  \param bufferId2 The buffer that is about to be removed
535      *  \return true if successfulln
536      */
537     static inline bool mergeBuffersPermanently(const UserId &user, const BufferId &bufferId1, const BufferId &bufferId2)
538     {
539         return instance()->_storage->mergeBuffersPermanently(user, bufferId1, bufferId2);
540     }
541
542
543     //! Update the LastSeenDate for a Buffer
544     /** This Method is used to make the LastSeenDate of a Buffer persistent
545      *  \note This method is threadsafe.
546      *
547      * \param user      The Owner of that Buffer
548      * \param bufferId  The buffer id
549      * \param MsgId     The Message id of the message that has been just seen
550      */
551     static inline void setBufferLastSeenMsg(UserId user, const BufferId &bufferId, const MsgId &msgId)
552     {
553         return instance()->_storage->setBufferLastSeenMsg(user, bufferId, msgId);
554     }
555
556     //! Get the auth username associated with a userId
557     /** \param user  The user to retrieve the username for
558      *  \return      The username for the user
559      */
560     static inline QString getAuthUserName(UserId user) {
561         return instance()->_storage->getAuthUserName(user);
562     }
563
564     //! Get a usable sysident for the given user in oidentd-strict mode
565     /** \param user    The user to retrieve the sysident for
566      *  \return The authusername
567      */
568     QString strictSysIdent(UserId user) const;
569
570
571     //! Get a Hash of all last seen message ids
572     /** This Method is called when the Quassel Core is started to restore the lastSeenMsgIds
573      *  \note This method is threadsafe.
574      *
575      * \param user      The Owner of the buffers
576      */
577     static inline QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user)
578     {
579         return instance()->_storage->bufferLastSeenMsgIds(user);
580     }
581
582
583     //! Update the MarkerLineMsgId for a Buffer
584     /** This Method is used to make the marker line position of a Buffer persistent
585      *  \note This method is threadsafe.
586      *
587      * \param user      The Owner of that Buffer
588      * \param bufferId  The buffer id
589      * \param MsgId     The Message id where the marker line should be placed
590      */
591     static inline void setBufferMarkerLineMsg(UserId user, const BufferId &bufferId, const MsgId &msgId)
592     {
593         return instance()->_storage->setBufferMarkerLineMsg(user, bufferId, msgId);
594     }
595
596
597     //! Get a Hash of all marker line message ids
598     /** This Method is called when the Quassel Core is started to restore the MarkerLineMsgIds
599      *  \note This method is threadsafe.
600      *
601      * \param user      The Owner of the buffers
602      */
603     static inline QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user)
604     {
605         return instance()->_storage->bufferMarkerLineMsgIds(user);
606     }
607
608     //! Update the BufferActivity for a Buffer
609     /** This Method is used to make the activity state of a Buffer persistent
610      *  \note This method is threadsafe.
611      *
612      * \param user      The Owner of that Buffer
613      * \param bufferId  The buffer id
614      * \param MsgId     The Message id where the marker line should be placed
615      */
616     static inline void setBufferActivity(UserId user, BufferId bufferId, Message::Types activity) {
617         return instance()->_storage->setBufferActivity(user, bufferId, activity);
618     }
619
620
621     //! Get a Hash of all buffer activity states
622     /** This Method is called when the Quassel Core is started to restore the BufferActivity
623      *  \note This method is threadsafe.
624      *
625      * \param user      The Owner of the buffers
626      */
627     static inline QHash<BufferId, Message::Types> bufferActivities(UserId user) {
628         return instance()->_storage->bufferActivities(user);
629     }
630
631     //! Get the bitset of buffer activity states for a buffer
632     /** This method is used to load the activity state of a buffer when its last seen message changes.
633      *  \note This method is threadsafe.
634      *
635      * \param bufferId The buffer
636      * \param lastSeenMsgId     The last seen message
637      */
638     static inline Message::Types bufferActivity(BufferId bufferId, MsgId lastSeenMsgId) {
639         return instance()->_storage->bufferActivity(bufferId, lastSeenMsgId);
640     }
641
642     //! Update the highlight count for a Buffer
643     /** This Method is used to make the highlight count state of a Buffer persistent
644      *  \note This method is threadsafe.
645      *
646      * \param user      The Owner of that Buffer
647      * \param bufferId  The buffer id
648      * \param MsgId     The Message id where the marker line should be placed
649      */
650     static inline void setHighlightCount(UserId user, BufferId bufferId, int highlightCount) {
651         return instance()->_storage->setHighlightCount(user, bufferId, highlightCount);
652     }
653
654
655     //! Get a Hash of all highlight count states
656     /** This Method is called when the Quassel Core is started to restore the highlight count
657      *  \note This method is threadsafe.
658      *
659      * \param user      The Owner of the buffers
660      */
661     static inline QHash<BufferId, int> highlightCounts(UserId user) {
662         return instance()->_storage->highlightCounts(user);
663     }
664     //! Get the highlight count states for a buffer
665     /** This method is used to load the highlight count of a buffer when its last seen message changes.
666      *  \note This method is threadsafe.
667      *
668      * \param bufferId The buffer
669      * \param lastSeenMsgId     The last seen message
670      */
671     static inline int highlightCount(BufferId bufferId, MsgId lastSeenMsgId) {
672         return instance()->_storage->highlightCount(bufferId, lastSeenMsgId);
673     }
674
675     static inline QDateTime startTime() { return instance()->_startTime; }
676     static inline bool isConfigured() { return instance()->_configured; }
677
678     /**
679      * Whether or not strict ident mode is enabled, locking users' idents to Quassel username
680      *
681      * @return True if strict mode enabled, otherwise false
682      */
683     static inline bool strictIdentEnabled() { return instance()->_strictIdentEnabled; }
684
685     static bool sslSupported();
686
687     static QVariantList backendInfo();
688     static QVariantList authenticatorInfo();
689
690     static QString setup(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authenticator, const QVariantMap &authSetupMap);
691
692     static inline QTimer *syncTimer() { return &instance()->_storageSyncTimer; }
693
694     inline OidentdConfigGenerator *oidentdConfigGenerator() const { return _oidentdConfigGenerator; }
695
696     static const int AddClientEventId;
697
698 signals:
699     //! Sent when a BufferInfo is updated in storage.
700     void bufferInfoUpdated(UserId user, const BufferInfo &info);
701
702     //! Relay from CoreSession::sessionState(). Used for internal connection only
703     void sessionState(const Protocol::SessionState &sessionState);
704
705     //! Emitted when database schema upgrade starts or ends
706     void dbUpgradeInProgress(bool inProgress);
707
708 public slots:
709     bool init();
710
711     /** Persist storage.
712      *
713      * @note This method is threadsafe.
714      */
715     void syncStorage();
716
717     /**
718      * Reload SSL certificates used for connection with clients.
719      *
720      * @return True if certificates reloaded successfully, otherwise false.
721      */
722     bool reloadCerts();
723
724     void cacheSysIdent();
725
726     QString setupCore(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authenticator, const QVariantMap &authSetupMap);
727
728     void connectInternalPeer(QPointer<InternalPeer> peer);
729
730 protected:
731     void customEvent(QEvent *event) override;
732
733 private slots:
734     bool startListening();
735     void stopListening(const QString &msg = QString());
736     void incomingConnection();
737     void clientDisconnected();
738
739     bool initStorage(const QString &backend, const QVariantMap &settings,
740                      const QProcessEnvironment &environment, bool loadFromEnvironment,
741                      bool setup = false);
742     bool initAuthenticator(const QString &backend, const QVariantMap &settings,
743                            const QProcessEnvironment &environment, bool loadFromEnvironment,
744                            bool setup = false);
745
746     void socketError(QAbstractSocket::SocketError err, const QString &errorString);
747     void setupClientSession(RemotePeer *, UserId);
748
749     bool changeUserPass(const QString &username);
750
751 private:
752     SessionThread *sessionForUser(UserId userId, bool restoreState = false);
753     void addClientHelper(RemotePeer *peer, UserId uid);
754     //void processCoreSetup(QTcpSocket *socket, QVariantMap &msg);
755     QString setupCoreForInternalUsage();
756     void setupInternalClientSession(QPointer<InternalPeer> peer);
757
758     bool createUser();
759
760     template<typename Storage>
761     void registerStorageBackend();
762
763     template<typename Authenticator>
764     void registerAuthenticator();
765
766     void registerStorageBackends();
767     void registerAuthenticators();
768
769     DeferredSharedPtr<Storage>       storageBackend(const QString& backendId) const;
770     DeferredSharedPtr<Authenticator> authenticator(const QString& authenticatorId) const;
771
772     bool selectBackend(const QString &backend);
773     bool selectAuthenticator(const QString &backend);
774
775     bool saveBackendSettings(const QString &backend, const QVariantMap &settings);
776     void saveAuthenticatorSettings(const QString &backend, const QVariantMap &settings);
777
778     void saveState();
779     void restoreState();
780
781     template<typename Backend>
782     QVariantMap promptForSettings(const Backend *backend);
783
784 private:
785     static Core *_instance;
786     QSet<CoreAuthHandler *> _connectingClients;
787     QHash<UserId, SessionThread *> _sessions;
788     DeferredSharedPtr<Storage>       _storage;        ///< Active storage backend
789     DeferredSharedPtr<Authenticator> _authenticator;  ///< Active authenticator
790     QMap<UserId, QString> _authUserNames;
791
792     QTimer _storageSyncTimer;
793
794 #ifdef HAVE_SSL
795     SslServer _server, _v6server;
796 #else
797     QTcpServer _server, _v6server;
798 #endif
799
800     OidentdConfigGenerator *_oidentdConfigGenerator {nullptr};
801
802     std::vector<DeferredSharedPtr<Storage>>       _registeredStorageBackends;
803     std::vector<DeferredSharedPtr<Authenticator>> _registeredAuthenticators;
804
805     QDateTime _startTime;
806
807     bool _initialized{false};
808     bool _configured{false};
809
810     QPointer<InternalPeer> _pendingInternalConnection;
811
812     /// Whether or not strict ident mode is enabled, locking users' idents to Quassel username
813     bool _strictIdentEnabled;
814
815     static std::unique_ptr<AbstractSqlMigrationReader> getMigrationReader(Storage *storage);
816     static std::unique_ptr<AbstractSqlMigrationWriter> getMigrationWriter(Storage *storage);
817     static void stdInEcho(bool on);
818     static inline void enableStdInEcho() { stdInEcho(true); }
819     static inline void disableStdInEcho() { stdInEcho(false); }
820 };