abd669795823cd669f22425299c2ef894199f006
[quassel.git] / src / core / core.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2015 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 #ifndef CORE_H
22 #define CORE_H
23
24 #include <QDateTime>
25 #include <QString>
26 #include <QVariant>
27 #include <QTimer>
28
29 #ifdef HAVE_SSL
30 #  include <QSslSocket>
31 #  include "sslserver.h"
32 #else
33 #  include <QTcpSocket>
34 #  include <QTcpServer>
35 #endif
36
37 #include "bufferinfo.h"
38 #include "message.h"
39 #include "oidentdconfiggenerator.h"
40 #include "sessionthread.h"
41 #include "storage.h"
42 #include "types.h"
43
44 class CoreAuthHandler;
45 class CoreSession;
46 struct NetworkInfo;
47 class SessionThread;
48 class SignalProxy;
49
50 class AbstractSqlMigrationReader;
51 class AbstractSqlMigrationWriter;
52
53 class Core : public QObject
54 {
55     Q_OBJECT
56
57 public:
58     static Core *instance();
59     static void destroy();
60
61     static void saveState();
62     static void restoreState();
63
64     /*** Storage access ***/
65     // These methods are threadsafe.
66
67     //! Validate user
68     /**
69      * \param userName The user's login name
70      * \param password The user's uncrypted password
71      * \return The user's ID if valid; 0 otherwise
72      */
73     static inline UserId validateUser(const QString &userName, const QString &password) {
74         return instance()->_storage->validateUser(userName, password);
75     }
76
77
78     //! Change a user's password
79     /**
80      * \param userId     The user's ID
81      * \param password   The user's unencrypted new password
82      * \return true, if the password change was successful
83      */
84     static bool changeUserPassword(UserId userId, const QString &password);
85
86     //! Store a user setting persistently
87     /**
88      * \param userId       The users Id
89      * \param settingName  The Name of the Setting
90      * \param data         The Value
91      */
92     static inline void setUserSetting(UserId userId, const QString &settingName, const QVariant &data)
93     {
94         instance()->_storage->setUserSetting(userId, settingName, data);
95     }
96
97
98     //! Retrieve a persistent user setting
99     /**
100      * \param userId       The users Id
101      * \param settingName  The Name of the Setting
102      * \param defaultValue Value to return in case it's unset.
103      * \return the Value of the Setting or the default value if it is unset.
104      */
105     static inline QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &defaultValue = QVariant())
106     {
107         return instance()->_storage->getUserSetting(userId, settingName, defaultValue);
108     }
109
110
111     /* Identity handling */
112     static inline IdentityId createIdentity(UserId user, CoreIdentity &identity)
113     {
114         return instance()->_storage->createIdentity(user, identity);
115     }
116
117
118     static bool updateIdentity(UserId user, const CoreIdentity &identity)
119     {
120         return instance()->_storage->updateIdentity(user, identity);
121     }
122
123
124     static void removeIdentity(UserId user, IdentityId identityId)
125     {
126         instance()->_storage->removeIdentity(user, identityId);
127     }
128
129
130     static QList<CoreIdentity> identities(UserId user)
131     {
132         return instance()->_storage->identities(user);
133     }
134
135
136     //! Create a Network in the Storage and store it's Id in the given NetworkInfo
137     /** \note This method is thredsafe.
138      *
139      *  \param user        The core user
140      *  \param networkInfo a NetworkInfo definition to store the newly created ID in
141      *  \return true if successfull.
142      */
143     static bool createNetwork(UserId user, NetworkInfo &info);
144
145     //! Apply the changes to NetworkInfo info to the storage engine
146     /** \note This method is thredsafe.
147      *
148      *  \param user        The core user
149      *  \param networkInfo The Updated NetworkInfo
150      *  \return true if successfull.
151      */
152     static inline bool updateNetwork(UserId user, const NetworkInfo &info)
153     {
154         return instance()->_storage->updateNetwork(user, info);
155     }
156
157
158     //! Permanently remove a Network and all the data associated with it.
159     /** \note This method is thredsafe.
160      *
161      *  \param user        The core user
162      *  \param networkId   The network to delete
163      *  \return true if successfull.
164      */
165     static inline bool removeNetwork(UserId user, const NetworkId &networkId)
166     {
167         return instance()->_storage->removeNetwork(user, networkId);
168     }
169
170
171     //! Returns a list of all NetworkInfos for the given UserId user
172     /** \note This method is thredsafe.
173      *
174      *  \param user        The core user
175      *  \return QList<NetworkInfo>.
176      */
177     static inline QList<NetworkInfo> networks(UserId user)
178     {
179         return instance()->_storage->networks(user);
180     }
181
182
183     //! Get a list of Networks to restore
184     /** Return a list of networks the user was connected at the time of core shutdown
185      *  \note This method is threadsafe.
186      *
187      *  \param user  The User Id in question
188      */
189     static inline QList<NetworkId> connectedNetworks(UserId user)
190     {
191         return instance()->_storage->connectedNetworks(user);
192     }
193
194
195     //! Update the connected state of a network
196     /** \note This method is threadsafe
197      *
198      *  \param user        The Id of the networks owner
199      *  \param networkId   The Id of the network
200      *  \param isConnected whether the network is connected or not
201      */
202     static inline void setNetworkConnected(UserId user, const NetworkId &networkId, bool isConnected)
203     {
204         return instance()->_storage->setNetworkConnected(user, networkId, isConnected);
205     }
206
207
208     //! Get a hash of channels with their channel keys for a given network
209     /** The keys are channel names and values are passwords (possibly empty)
210      *  \note This method is threadsafe
211      *
212      *  \param user       The id of the networks owner
213      *  \param networkId  The Id of the network
214      */
215     static inline QHash<QString, QString> persistentChannels(UserId user, const NetworkId &networkId)
216     {
217         return instance()->_storage->persistentChannels(user, networkId);
218     }
219
220
221     //! Update the connected state of a channel
222     /** \note This method is threadsafe
223      *
224      *  \param user       The Id of the networks owner
225      *  \param networkId  The Id of the network
226      *  \param channel    The name of the channel
227      *  \param isJoined   whether the channel is connected or not
228      */
229     static inline void setChannelPersistent(UserId user, const NetworkId &networkId, const QString &channel, bool isJoined)
230     {
231         return instance()->_storage->setChannelPersistent(user, networkId, channel, isJoined);
232     }
233
234
235     //! Update the key of a channel
236     /** \note This method is threadsafe
237      *
238      *  \param user       The Id of the networks owner
239      *  \param networkId  The Id of the network
240      *  \param channel    The name of the channel
241      *  \param key        The key of the channel (possibly empty)
242      */
243     static inline void setPersistentChannelKey(UserId user, const NetworkId &networkId, const QString &channel, const QString &key)
244     {
245         return instance()->_storage->setPersistentChannelKey(user, networkId, channel, key);
246     }
247
248
249     //! retrieve last known away message for session restore
250     /** \note This method is threadsafe
251      *
252      *  \param user       The Id of the networks owner
253      *  \param networkId  The Id of the network
254      */
255     static inline QString awayMessage(UserId user, NetworkId networkId)
256     {
257         return instance()->_storage->awayMessage(user, networkId);
258     }
259
260
261     //! Make away message persistent for session restore
262     /** \note This method is threadsafe
263      *
264      *  \param user       The Id of the networks owner
265      *  \param networkId  The Id of the network
266      *  \param awayMsg    The current away message of own user
267      */
268     static inline void setAwayMessage(UserId user, NetworkId networkId, const QString &awayMsg)
269     {
270         return instance()->_storage->setAwayMessage(user, networkId, awayMsg);
271     }
272
273
274     //! retrieve last known user mode for session restore
275     /** \note This method is threadsafe
276      *
277      *  \param user       The Id of the networks owner
278      *  \param networkId  The Id of the network
279      */
280     static inline QString userModes(UserId user, NetworkId networkId)
281     {
282         return instance()->_storage->userModes(user, networkId);
283     }
284
285
286     //! Make our user modes persistent for session restore
287     /** \note This method is threadsafe
288      *
289      *  \param user       The Id of the networks owner
290      *  \param networkId  The Id of the network
291      *  \param userModes  The current user modes of own user
292      */
293     static inline void setUserModes(UserId user, NetworkId networkId, const QString &userModes)
294     {
295         return instance()->_storage->setUserModes(user, networkId, userModes);
296     }
297
298
299     //! Get the unique BufferInfo for the given combination of network and buffername for a user.
300     /** \note This method is threadsafe.
301      *
302      *  \param user      The core user who owns this buffername
303      *  \param networkId The network id
304      *  \param type      The type of the buffer (StatusBuffer, Channel, etc.)
305      *  \param buffer    The buffer name (if empty, the net's status buffer is returned)
306      *  \param create    Whether or not the buffer should be created if it doesnt exist
307      *  \return The BufferInfo corresponding to the given network and buffer name, or 0 if not found
308      */
309     static inline BufferInfo bufferInfo(UserId user, const NetworkId &networkId, BufferInfo::Type type, const QString &buffer = "", bool create = true)
310     {
311         return instance()->_storage->bufferInfo(user, networkId, type, buffer, create);
312     }
313
314
315     //! Get the unique BufferInfo for a bufferId
316     /** \note This method is threadsafe
317      *  \param user      The core user who owns this buffername
318      *  \param bufferId  The id of the buffer
319      *  \return The BufferInfo corresponding to the given buffer id, or an invalid BufferInfo if not found.
320      */
321     static inline BufferInfo getBufferInfo(UserId user, const BufferId &bufferId)
322     {
323         return instance()->_storage->getBufferInfo(user, bufferId);
324     }
325
326
327     //! Store a Message in the storage backend and set it's unique Id.
328     /** \note This method is threadsafe.
329      *
330      *  \param message The message object to be stored
331      *  \return true on success
332      */
333     static inline bool storeMessage(Message &message)
334     {
335         return instance()->_storage->logMessage(message);
336     }
337
338
339     //! Store a list of Messages in the storage backend and set their unique Id.
340     /** \note This method is threadsafe.
341      *
342      *  \param messages The list message objects to be stored
343      *  \return true on success
344      */
345     static inline bool storeMessages(MessageList &messages)
346     {
347         return instance()->_storage->logMessages(messages);
348     }
349
350
351     //! Request a certain number messages stored in a given buffer.
352     /** \param buffer   The buffer we request messages from
353      *  \param first    if != -1 return only messages with a MsgId >= first
354      *  \param last     if != -1 return only messages with a MsgId < last
355      *  \param limit    if != -1 limit the returned list to a max of \limit entries
356      *  \return The requested list of messages
357      */
358     static inline QList<Message> requestMsgs(UserId user, BufferId bufferId, MsgId first = -1, MsgId last = -1, int limit = -1)
359     {
360         return instance()->_storage->requestMsgs(user, bufferId, first, last, limit);
361     }
362
363
364     //! Request a certain number of messages across all buffers
365     /** \param first    if != -1 return only messages with a MsgId >= first
366      *  \param last     if != -1 return only messages with a MsgId < last
367      *  \param limit    Max amount of messages
368      *  \return The requested list of messages
369      */
370     static inline QList<Message> requestAllMsgs(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1)
371     {
372         return instance()->_storage->requestAllMsgs(user, first, last, limit);
373     }
374
375
376     //! Request a list of all buffers known to a user.
377     /** This method is used to get a list of all buffers we have stored a backlog from.
378      *  \note This method is threadsafe.
379      *
380      *  \param user  The user whose buffers we request
381      *  \return A list of the BufferInfos for all buffers as requested
382      */
383     static inline QList<BufferInfo> requestBuffers(UserId user)
384     {
385         return instance()->_storage->requestBuffers(user);
386     }
387
388
389     //! Request a list of BufferIds for a given NetworkId
390     /** \note This method is threadsafe.
391      *
392      *  \param user  The user whose buffers we request
393      *  \param networkId  The NetworkId of the network in question
394      *  \return List of BufferIds belonging to the Network
395      */
396     static inline QList<BufferId> requestBufferIdsForNetwork(UserId user, NetworkId networkId)
397     {
398         return instance()->_storage->requestBufferIdsForNetwork(user, networkId);
399     }
400
401
402     //! Remove permanently a buffer and it's content from the storage backend
403     /** This call cannot be reverted!
404      *  \note This method is threadsafe.
405      *
406      *  \param user      The user who is the owner of the buffer
407      *  \param bufferId  The bufferId
408      *  \return true if successfull
409      */
410     static inline bool removeBuffer(const UserId &user, const BufferId &bufferId)
411     {
412         return instance()->_storage->removeBuffer(user, bufferId);
413     }
414
415
416     //! Rename a Buffer
417     /** \note This method is threadsafe.
418      *  \param user      The id of the buffer owner
419      *  \param bufferId  The bufferId
420      *  \param newName   The new name of the buffer
421      *  \return true if successfull
422      */
423     static inline bool renameBuffer(const UserId &user, const BufferId &bufferId, const QString &newName)
424     {
425         return instance()->_storage->renameBuffer(user, bufferId, newName);
426     }
427
428
429     //! Merge the content of two Buffers permanently. This cannot be reversed!
430     /** \note This method is threadsafe.
431      *  \param user      The id of the buffer owner
432      *  \param bufferId1 The bufferId of the remaining buffer
433      *  \param bufferId2 The buffer that is about to be removed
434      *  \return true if successfulln
435      */
436     static inline bool mergeBuffersPermanently(const UserId &user, const BufferId &bufferId1, const BufferId &bufferId2)
437     {
438         return instance()->_storage->mergeBuffersPermanently(user, bufferId1, bufferId2);
439     }
440
441
442     //! Update the LastSeenDate for a Buffer
443     /** This Method is used to make the LastSeenDate of a Buffer persistent
444      *  \note This method is threadsafe.
445      *
446      * \param user      The Owner of that Buffer
447      * \param bufferId  The buffer id
448      * \param MsgId     The Message id of the message that has been just seen
449      */
450     static inline void setBufferLastSeenMsg(UserId user, const BufferId &bufferId, const MsgId &msgId)
451     {
452         return instance()->_storage->setBufferLastSeenMsg(user, bufferId, msgId);
453     }
454
455
456     //! Get a Hash of all last seen message ids
457     /** This Method is called when the Quassel Core is started to restore the lastSeenMsgIds
458      *  \note This method is threadsafe.
459      *
460      * \param user      The Owner of the buffers
461      */
462     static inline QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user)
463     {
464         return instance()->_storage->bufferLastSeenMsgIds(user);
465     }
466
467
468     //! Update the MarkerLineMsgId for a Buffer
469     /** This Method is used to make the marker line position of a Buffer persistent
470      *  \note This method is threadsafe.
471      *
472      * \param user      The Owner of that Buffer
473      * \param bufferId  The buffer id
474      * \param MsgId     The Message id where the marker line should be placed
475      */
476     static inline void setBufferMarkerLineMsg(UserId user, const BufferId &bufferId, const MsgId &msgId)
477     {
478         return instance()->_storage->setBufferMarkerLineMsg(user, bufferId, msgId);
479     }
480
481
482     //! Get a Hash of all marker line message ids
483     /** This Method is called when the Quassel Core is started to restore the MarkerLineMsgIds
484      *  \note This method is threadsafe.
485      *
486      * \param user      The Owner of the buffers
487      */
488     static inline QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user)
489     {
490         return instance()->_storage->bufferMarkerLineMsgIds(user);
491     }
492
493
494     static inline QDateTime startTime() { return instance()->_startTime; }
495     static inline bool isConfigured() { return instance()->_configured; }
496     static bool sslSupported();
497
498     /**
499      * Reloads SSL certificates used for connection with clients
500      *
501      * @return True if certificates reloaded successfully, otherwise false.
502      */
503     static bool reloadCerts();
504
505     static QVariantList backendInfo();
506
507     static QString setup(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData);
508
509     static inline QTimer &syncTimer() { return instance()->_storageSyncTimer; }
510
511     inline OidentdConfigGenerator *oidentdConfigGenerator() const { return _oidentdConfigGenerator; }
512
513     static const int AddClientEventId;
514
515 public slots:
516     //! Make storage data persistent
517     /** \note This method is threadsafe.
518      */
519     void syncStorage();
520     void setupInternalClientSession(InternalPeer *clientConnection);
521     QString setupCore(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData);
522
523 signals:
524     //! Sent when a BufferInfo is updated in storage.
525     void bufferInfoUpdated(UserId user, const BufferInfo &info);
526
527     //! Relay from CoreSession::sessionState(). Used for internal connection only
528     void sessionState(const Protocol::SessionState &sessionState);
529
530 protected:
531     virtual void customEvent(QEvent *event);
532
533 private slots:
534     bool startListening();
535     void stopListening(const QString &msg = QString());
536     void incomingConnection();
537     void clientDisconnected();
538
539     bool initStorage(const QString &backend, const QVariantMap &settings, bool setup = false);
540
541     void socketError(QAbstractSocket::SocketError err, const QString &errorString);
542     void setupClientSession(RemotePeer *, UserId);
543
544     bool changeUserPass(const QString &username);
545
546 private:
547     Core();
548     ~Core();
549     void init();
550     static Core *instanceptr;
551
552     SessionThread *sessionForUser(UserId userId, bool restoreState = false);
553     void addClientHelper(RemotePeer *peer, UserId uid);
554     //void processCoreSetup(QTcpSocket *socket, QVariantMap &msg);
555     QString setupCoreForInternalUsage();
556
557     void registerStorageBackends();
558     bool registerStorageBackend(Storage *);
559     void unregisterStorageBackends();
560     void unregisterStorageBackend(Storage *);
561     bool selectBackend(const QString &backend);
562     bool createUser();
563     void saveBackendSettings(const QString &backend, const QVariantMap &settings);
564     QVariantMap promptForSettings(const Storage *storage);
565
566 private:
567     QSet<CoreAuthHandler *> _connectingClients;
568     QHash<UserId, SessionThread *> _sessions;
569     Storage *_storage;
570     QTimer _storageSyncTimer;
571
572 #ifdef HAVE_SSL
573     SslServer _server, _v6server;
574 #else
575     QTcpServer _server, _v6server;
576 #endif
577
578     OidentdConfigGenerator *_oidentdConfigGenerator;
579
580     QHash<QString, Storage *> _storageBackends;
581
582     QDateTime _startTime;
583
584     bool _configured;
585
586     static AbstractSqlMigrationReader *getMigrationReader(Storage *storage);
587     static AbstractSqlMigrationWriter *getMigrationWriter(Storage *storage);
588     static void stdInEcho(bool on);
589     static inline void enableStdInEcho() { stdInEcho(true); }
590     static inline void disableStdInEcho() { stdInEcho(false); }
591 };
592
593
594 #endif