1 /* 2 Drawpile - a collaborative drawing program. 3 4 Copyright (C) 2017-2018 Calle Laakkonen 5 6 Drawpile is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 Drawpile is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with Drawpile. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef DP_SERVER_FILEDHISTORY_H 21 #define DP_SERVER_FILEDHISTORY_H 22 23 #include "sessionhistory.h" 24 #include "../libshared/net/protover.h" 25 26 #include <QDir> 27 #include <QVector> 28 #include <QSet> 29 30 namespace server { 31 32 class FiledHistory : public SessionHistory 33 { 34 Q_OBJECT 35 public: 36 ~FiledHistory(); 37 38 /** 39 * @brief Start a new file backed history 40 * @param dir where to put the session files 41 * @param id session ID 42 * @param alias ID alias 43 * @param version full protocol version 44 * @param founder name of the session founder 45 * @param parent 46 * @return FiledHistory object or nullptr on error 47 */ 48 static FiledHistory *startNew(const QDir &dir, const QString &id, const QString &alias, const protocol::ProtocolVersion &version, const QString &founder, QObject *parent=nullptr); 49 50 /** 51 * @brief Load a session from file 52 * @param path 53 * @param parent 54 * @return 55 */ 56 static FiledHistory *load(const QString &path, QObject *parent=nullptr); 57 58 /** 59 * @brief Close the currently open block (if any) and start a new one 60 */ 61 void closeBlock(); 62 63 /** 64 * @brief Enable archival mode 65 * 66 * In archive mode, files are not deleted when session ends or is reset. 67 * Instead, ".archived" is appended to the end of the journal file on termination. 68 * @param archive 69 */ setArchive(bool archive)70 void setArchive(bool archive) { m_archive = archive; } 71 72 //! Get the metadata journal file name for the given session ID 73 static QString journalFilename(const QString &id); 74 idAlias()75 QString idAlias() const override { return m_alias; } founderName()76 QString founderName() const override { return m_founder; } protocolVersion()77 protocol::ProtocolVersion protocolVersion() const override { return m_version; } passwordHash()78 QByteArray passwordHash() const override { return m_password; } opwordHash()79 QByteArray opwordHash() const override { return m_opword; } maxUsers()80 int maxUsers() const override { return m_maxUsers; } title()81 QString title() const override { return m_title; } autoResetThreshold()82 uint autoResetThreshold() const override { return m_autoResetThreshold; } flags()83 Flags flags() const override { return m_flags; } 84 85 void setPasswordHash(const QByteArray &password) override; 86 void setOpwordHash(const QByteArray &opword) override; 87 void setMaxUsers(int max) override; 88 void setTitle(const QString &title) override; 89 void setFlags(Flags f) override; 90 void setAutoResetThreshold(uint limit) override; 91 void joinUser(uint8_t id, const QString &name) override; 92 93 void terminate() override; 94 void cleanupBatches(int before) override; 95 std::tuple<protocol::MessageList, int> getBatch(int after) const override; 96 97 void addAnnouncement(const QString &) override; 98 void removeAnnouncement(const QString &url) override; announcements()99 QStringList announcements() const override { return m_announcements; } 100 101 void setAuthenticatedOperator(const QString &authId, bool op) override; 102 void setAuthenticatedTrust(const QString &authId, bool trusted) override; isOperator(const QString & authId)103 bool isOperator(const QString &authId) const override { return m_ops.contains(authId); } isTrusted(const QString & authId)104 bool isTrusted(const QString &authId) const override { return m_trusted.contains(authId); } isAuthenticatedOperators()105 bool isAuthenticatedOperators() const override { return !m_ops.isEmpty(); } 106 107 protected: 108 void historyAdd(const protocol::MessagePtr &msg) override; 109 void historyReset(const protocol::MessageList &newHistory) override; 110 void historyAddBan(int id, const QString &username, const QHostAddress &ip, const QString &extAuthId, const QString &bannedBy) override; 111 void historyRemoveBan(int id) override; 112 113 void timerEvent(QTimerEvent *event) override; 114 115 private: 116 FiledHistory(const QDir &dir, QFile *journal, const QString &id, const QString &alias, const protocol::ProtocolVersion &version, const QString &founder, QObject *parent); 117 FiledHistory(const QDir &dir, QFile *journal, const QString &id, QObject *parent); 118 119 struct Block { 120 qint64 startOffset; 121 int startIndex; 122 int count; 123 qint64 endOffset; 124 protocol::MessageList messages; 125 }; 126 127 bool create(); 128 bool load(); 129 bool scanBlocks(); 130 bool initRecording(); 131 132 QDir m_dir; 133 QFile *m_journal; 134 QFile *m_recording; 135 136 // Current state: 137 QString m_alias; 138 QString m_founder; 139 QString m_title; 140 protocol::ProtocolVersion m_version; 141 QByteArray m_password; 142 QByteArray m_opword; 143 int m_maxUsers; 144 uint m_autoResetThreshold; 145 Flags m_flags; 146 QStringList m_announcements; 147 QSet<QString> m_ops; 148 QSet<QString> m_trusted; 149 150 QVector<Block> m_blocks; 151 int m_fileCount; 152 bool m_archive; 153 }; 154 155 } 156 157 #endif 158