1 /* 2 Drawpile - a collaborative drawing program. 3 4 Copyright (C) 2015-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 ACLFILTER_H 21 #define ACLFILTER_H 22 23 #include "features.h" 24 25 #include <QObject> 26 #include <QHash> 27 #include <QSet> 28 #include <bitset> 29 30 namespace protocol { 31 class Message; 32 class SessionOwner; 33 class TrustedUsers; 34 } 35 36 namespace canvas { 37 38 class UserSet { 39 public: 40 UserSet() = default; 41 contains(uint8_t id)42 bool contains(uint8_t id) const { return m_users[id]; } set(uint8_t id)43 void set(uint8_t id) { m_users[id] = true; } unset(uint8_t id)44 bool unset(uint8_t id) { bool wasSet = m_users[id]; m_users[id] = false; return wasSet; } reset()45 void reset() { m_users.reset(); } 46 setFromList(const QList<uint8_t> ids)47 void setFromList(const QList<uint8_t> ids) { 48 m_users.reset(); 49 for(int i=0;i<ids.size();++i) 50 m_users[ids[i]] = true; 51 } 52 toList()53 QList<uint8_t> toList() const { 54 QList<uint8_t> lst; 55 for(int i=0;i<256;++i) 56 if(m_users[i]) 57 lst << i; 58 return lst; 59 } 60 61 private: 62 std::bitset<256> m_users; 63 }; 64 65 class AclFilter : public QObject 66 { 67 Q_OBJECT 68 public: 69 struct LayerAcl { 70 bool locked; // layer is locked for all users 71 Tier tier; // layer access tier (if not exclusive) 72 QList<uint8_t> exclusive; // if not empty, only these users can draw on this layer 73 }; 74 75 explicit AclFilter(QObject *parent=nullptr); 76 AclFilter *clone(QObject *newParent=nullptr) const; 77 78 //! Reset all access controls 79 void reset(uint8_t myId, bool localMode); 80 81 //! Go online mode: refresh status bits 82 void setOnlineMode(uint8_t myId); 83 84 /** 85 * @brief Filter a message 86 * 87 * This will also update the filter state. 88 * 89 * @param msg the message 90 * @return false if message must be dropped 91 */ 92 bool filterMessage(const protocol::Message &msg); 93 94 //! Does the local user have operator privileges? isLocalUserOperator()95 bool isLocalUserOperator() const { return m_isOperator; } 96 97 //! Has the local user been tagged as trusted? isLocalUserTrusted()98 bool isLocalUserTrusted() const { return m_isTrusted; } 99 100 //! Is there a general session lock in place? isSessionLocked()101 bool isSessionLocked() const { return m_sessionLocked; } 102 103 //! Has the local user been locked individually? isLocalUserLocked()104 bool isLocalUserLocked() const { return m_localUserLocked; } 105 106 //! Is the local user locked for any reason? isLocked()107 bool isLocked() const { return m_sessionLocked | m_localUserLocked; } 108 109 //! Check if the local user can draw on the given layer isLayerLocked(int layerId)110 bool isLayerLocked(int layerId) const { 111 return isLocked() || isLayerLockedFor(layerId, m_myId, userTier(m_myId)); 112 } 113 114 //! Can the local user use this feature? canUseFeature(Feature f)115 bool canUseFeature(Feature f) const { return localUserTier() <= featureTier(f); } 116 117 //! Get the local user's feature access tier localUserTier()118 Tier localUserTier() const { return userTier(m_myId); } 119 120 //! Get the given feature's access tier featureTier(Feature f)121 Tier featureTier(Feature f) const { Q_ASSERT(int(f)>=0 && int(f) < FeatureCount); return m_featureTiers[int(f)]; } 122 123 /** 124 * @brief Get the access controls for an individual layer 125 * If the layer has not been configured, an unlocked set will be returned. 126 */ 127 LayerAcl layerAcl(int id) const; 128 129 //! Get the list of locked users lockedUsers()130 QList<uint8_t> lockedUsers() const { return m_userlocks.toList(); } 131 132 signals: 133 void localOpChanged(bool op); 134 void localLockChanged(bool lock); 135 void layerAclChanged(int id); 136 137 void userLocksChanged(const QList<uint8_t> lockedUsers); 138 void operatorListChanged(const QList<uint8_t> opUsers); 139 void trustedUserListChanged(const QList<uint8_t> trustedUsers); 140 141 //! The local user's access to a feature just changed 142 void featureAccessChanged(Feature feature, bool canUse); 143 144 //! A feature's access tier was changed 145 void featureTierChanged(Feature feature, Tier tier); 146 147 private: 148 void setOperator(bool op); 149 void setTrusted(bool trusted); 150 void setSessionLock(bool lock); 151 void setUserLock(bool lock); 152 void setLockByDefault(bool lock); 153 void setFeature(Feature feature, Tier tier); 154 155 void updateSessionOwnership(const protocol::SessionOwner &msg); 156 void updateTrustedUserList(const protocol::TrustedUsers &msg); 157 158 bool isLayerLockedFor(int layerId, uint8_t userId, Tier userTier) const; 159 userTier(int id)160 Tier userTier(int id) const { 161 if(id == 0) // only the server can use ID 0 162 return Tier::Op; 163 if(m_ops.contains(id)) 164 return Tier::Op; 165 if(m_trusted.contains(id)) 166 return Tier::Trusted; 167 if(m_auth.contains(id)) 168 return Tier::Auth; 169 return Tier::Guest; 170 } 171 172 int m_myId = 1; // the ID of the local user 173 174 bool m_isOperator = false; // is the local user an operator? 175 bool m_isTrusted = false; // does the local user have trusted status? 176 bool m_sessionLocked = false; // is the session locked? 177 bool m_localUserLocked = false; // is the local user locked individually? 178 179 QHash<int,LayerAcl> m_layers; // layer access controls 180 UserSet m_ops; // list of operators 181 UserSet m_trusted; // list of trusted users 182 UserSet m_auth; // list of registered users 183 UserSet m_userlocks; // list of individually locked users 184 QSet<uint16_t> m_protectedAnnotations; // list of protected annotations 185 Tier m_featureTiers[FeatureCount] = {Tier::Guest}; // feature access tiers 186 }; 187 188 } 189 190 #endif // ACLFILTER_H 191