From d4cc4bf1e4d7c84efa7272e2ab06d0aa4ae7f8ed Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 27 Jun 2016 14:55:13 -0700 Subject: [PATCH] represent node permissions as a bitfield rather than a list of bools --- .../resources/describe-settings.json | 8 +- domain-server/src/DomainGatekeeper.cpp | 20 ++-- domain-server/src/DomainMetadata.cpp | 8 +- domain-server/src/DomainServer.cpp | 2 +- .../src/DomainServerSettingsManager.cpp | 25 +++-- libraries/networking/src/LimitedNodeList.cpp | 20 ++-- libraries/networking/src/LimitedNodeList.h | 8 +- libraries/networking/src/Node.h | 8 +- libraries/networking/src/NodePermissions.cpp | 97 ++++++++----------- libraries/networking/src/NodePermissions.h | 25 +++-- 10 files changed, 116 insertions(+), 105 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index b24acd1bce..44d2c025a7 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -409,7 +409,7 @@ "label": "Connect", "type": "checkbox", "editable": true, - "default": true + "default": false }, { "name": "id_can_adjust_locks", @@ -478,7 +478,7 @@ "label": "Connect", "type": "checkbox", "editable": true, - "default": true + "default": false }, { "name": "id_can_adjust_locks", @@ -549,7 +549,7 @@ "label": "Connect", "type": "checkbox", "editable": true, - "default": true + "default": false }, { "name": "id_can_adjust_locks", @@ -620,7 +620,7 @@ "label": "Connect", "type": "checkbox", "editable": true, - "default": true + "default": false }, { "name": "id_can_adjust_locks", diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index b5372ea9bc..9d121cb0ab 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -140,7 +140,7 @@ NodePermissions DomainGatekeeper::applyPermissionsForUser(bool isLocalUser, } else { // they are logged into metaverse, but we don't have specific permissions for them. userPerms |= _server->_settingsManager.getStandardPermissionsForName(NodePermissions::standardNameLoggedIn); - qDebug() << "user-permissions: user is logged-into metavers, so:" << userPerms; + qDebug() << "user-permissions: user is logged-into metaverse, so:" << userPerms; // if this user is a friend of the domain-owner, give them friend's permissions if (_domainOwnerFriends.contains(verifiedUsername)) { @@ -188,9 +188,9 @@ void DomainGatekeeper::updateNodePermissions() { if (node->getPermissions().isAssignment) { // this node is an assignment-client userPerms.isAssignment = true; - userPerms.canAdjustLocks = true; - userPerms.canRezPermanentEntities = true; - userPerms.canRezTemporaryEntities = true; + userPerms.permissions |= NodePermissions::Permission::canAdjustLocks; + userPerms.permissions |= NodePermissions::Permission::canRezPermanentEntities; + userPerms.permissions |= NodePermissions::Permission::canRezTemporaryEntities; } else { // this node is an agent const QHostAddress& addr = node->getLocalSocket().getAddress(); @@ -201,7 +201,7 @@ void DomainGatekeeper::updateNodePermissions() { node->setPermissions(userPerms); - if (!userPerms.canConnectToDomain) { + if (!userPerms.can(NodePermissions::Permission::canConnectToDomain)) { qDebug() << "node" << node->getUUID() << "no longer has permission to connect."; // hang up on this node nodesToKill << node; @@ -257,9 +257,9 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo // always allow assignment clients to create and destroy entities NodePermissions userPerms; userPerms.isAssignment = true; - userPerms.canAdjustLocks = true; - userPerms.canRezPermanentEntities = true; - userPerms.canRezTemporaryEntities = true; + userPerms.permissions |= NodePermissions::Permission::canAdjustLocks; + userPerms.permissions |= NodePermissions::Permission::canRezPermanentEntities; + userPerms.permissions |= NodePermissions::Permission::canRezTemporaryEntities; newNode->setPermissions(userPerms); return newNode; } @@ -306,13 +306,13 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect userPerms = applyPermissionsForUser(isLocalUser, userPerms, verifiedUsername); - if (!userPerms.canConnectToDomain) { + if (!userPerms.can(NodePermissions::Permission::canConnectToDomain)) { sendConnectionDeniedPacket("You lack the required permissions to connect to this domain.", nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::TooManyUsers); return SharedNodePointer(); } - if (!userPerms.canConnectPastMaxCapacity && !isWithinMaxCapacity()) { + if (!userPerms.can(NodePermissions::Permission::canConnectPastMaxCapacity) && !isWithinMaxCapacity()) { // we can't allow this user to connect because we are at max capacity sendConnectionDeniedPacket("Too many connected users.", nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::TooManyUsers); diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index c5048ea9d8..927a14cab1 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -184,10 +184,10 @@ void DomainMetadata::securityChanged(bool send) { QString restriction; const auto& settingsManager = static_cast(parent())->_settingsManager; - bool hasAnonymousAccess = - settingsManager.getStandardPermissionsForName(NodePermissions::standardNameAnonymous).canConnectToDomain; - bool hasHifiAccess = - settingsManager.getStandardPermissionsForName(NodePermissions::standardNameLoggedIn).canConnectToDomain; + bool hasAnonymousAccess = settingsManager.getStandardPermissionsForName(NodePermissions::standardNameAnonymous).can( + NodePermissions::Permission::canConnectToDomain); + bool hasHifiAccess = settingsManager.getStandardPermissionsForName(NodePermissions::standardNameLoggedIn).can( + NodePermissions::Permission::canConnectToDomain); if (hasAnonymousAccess) { restriction = hasHifiAccess ? RESTRICTION_OPEN : RESTRICTION_ANON; } else if (hasHifiAccess) { diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d75a2c3245..923a82d184 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1099,7 +1099,7 @@ void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) { // consider the domain to be "restricted" if anonymous connections are disallowed static const QString RESTRICTED_ACCESS_FLAG = "restricted"; NodePermissions anonymousPermissions = _settingsManager.getPermissionsForName(NodePermissions::standardNameAnonymous); - domainObject[RESTRICTED_ACCESS_FLAG] = !anonymousPermissions.canConnectToDomain; + domainObject[RESTRICTED_ACCESS_FLAG] = !anonymousPermissions.can(NodePermissions::Permission::canConnectToDomain); const auto& temporaryDomainKey = DependencyManager::get()->getTemporaryDomainKey(getID()); if (!temporaryDomainKey.isEmpty()) { diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 2411dbdf09..943f0517dc 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -223,14 +223,16 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList if (isRestrictedAccess) { // only users in allow-users list can connect - _standardAgentPermissions[NodePermissions::standardNameAnonymous]->canConnectToDomain = false; - _standardAgentPermissions[NodePermissions::standardNameLoggedIn]->canConnectToDomain = false; + _standardAgentPermissions[NodePermissions::standardNameAnonymous]->clear( + NodePermissions::Permission::canConnectToDomain); + _standardAgentPermissions[NodePermissions::standardNameLoggedIn]->clear( + NodePermissions::Permission::canConnectToDomain); } // else anonymous and logged-in retain default of canConnectToDomain = true foreach (QString allowedUser, allowedUsers) { // even if isRestrictedAccess is false, we have to add explicit rows for these users. - // defaults to canConnectToDomain = true _agentPermissions[allowedUser].reset(new NodePermissions(allowedUser)); + _agentPermissions[allowedUser]->set(NodePermissions::Permission::canConnectToDomain); } foreach (QString allowedEditor, allowedEditors) { @@ -238,10 +240,10 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList _agentPermissions[allowedEditor].reset(new NodePermissions(allowedEditor)); if (isRestrictedAccess) { // they can change locks, but can't connect. - _agentPermissions[allowedEditor]->canConnectToDomain = false; + _agentPermissions[allowedEditor]->clear(NodePermissions::Permission::canConnectToDomain); } } - _agentPermissions[allowedEditor]->canAdjustLocks = true; + _agentPermissions[allowedEditor]->set(NodePermissions::Permission::canAdjustLocks); } QList> permissionsSets; @@ -249,11 +251,16 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList foreach (auto permissionsSet, permissionsSets) { foreach (QString userName, permissionsSet.keys()) { if (onlyEditorsAreRezzers) { - permissionsSet[userName]->canRezPermanentEntities = permissionsSet[userName]->canAdjustLocks; - permissionsSet[userName]->canRezTemporaryEntities = permissionsSet[userName]->canAdjustLocks; + if (permissionsSet[userName]->can(NodePermissions::Permission::canAdjustLocks)) { + permissionsSet[userName]->set(NodePermissions::Permission::canRezPermanentEntities); + permissionsSet[userName]->set(NodePermissions::Permission::canRezTemporaryEntities); + } else { + permissionsSet[userName]->clear(NodePermissions::Permission::canRezPermanentEntities); + permissionsSet[userName]->clear(NodePermissions::Permission::canRezTemporaryEntities); + } } else { - permissionsSet[userName]->canRezPermanentEntities = true; - permissionsSet[userName]->canRezTemporaryEntities = true; + permissionsSet[userName]->set(NodePermissions::Permission::canRezPermanentEntities); + permissionsSet[userName]->set(NodePermissions::Permission::canRezTemporaryEntities); } } } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index d7a2d47fab..151b6c5012 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -135,17 +135,21 @@ void LimitedNodeList::setPermissions(const NodePermissions& newPermissions) { _permissions = newPermissions; - if (originalPermissions.canAdjustLocks != newPermissions.canAdjustLocks) { - emit isAllowedEditorChanged(_permissions.canAdjustLocks); + if (originalPermissions.can(NodePermissions::Permission::canAdjustLocks) != + newPermissions.can(NodePermissions::Permission::canAdjustLocks)) { + emit isAllowedEditorChanged(_permissions.can(NodePermissions::Permission::canAdjustLocks)); } - if (originalPermissions.canRezPermanentEntities != newPermissions.canRezPermanentEntities) { - emit canRezChanged(_permissions.canRezPermanentEntities); + if (originalPermissions.can(NodePermissions::Permission::canRezPermanentEntities) != + newPermissions.can(NodePermissions::Permission::canRezPermanentEntities)) { + emit canRezChanged(_permissions.can(NodePermissions::Permission::canRezPermanentEntities)); } - if (originalPermissions.canRezTemporaryEntities != newPermissions.canRezTemporaryEntities) { - emit canRezTmpChanged(_permissions.canRezTemporaryEntities); + if (originalPermissions.can(NodePermissions::Permission::canRezTemporaryEntities) != + newPermissions.can(NodePermissions::Permission::canRezTemporaryEntities)) { + emit canRezTmpChanged(_permissions.can(NodePermissions::Permission::canRezTemporaryEntities)); } - if (originalPermissions.canWriteToAssetServer != newPermissions.canWriteToAssetServer) { - emit canWriteAssetsChanged(_permissions.canWriteToAssetServer); + if (originalPermissions.can(NodePermissions::Permission::canWriteToAssetServer) != + newPermissions.can(NodePermissions::Permission::canWriteToAssetServer)) { + emit canWriteAssetsChanged(_permissions.can(NodePermissions::Permission::canWriteToAssetServer)); } } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 483aa0734c..3242b7d178 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -105,10 +105,10 @@ public: void setSessionUUID(const QUuid& sessionUUID); void setPermissions(const NodePermissions& newPermissions); - bool isAllowedEditor() const { return _permissions.canAdjustLocks; } - bool getThisNodeCanRez() const { return _permissions.canRezPermanentEntities; } - bool getThisNodeCanRezTmp() const { return _permissions.canRezTemporaryEntities; } - bool getThisNodeCanWriteAssets() const { return _permissions.canWriteToAssetServer; } + bool isAllowedEditor() const { return _permissions.can(NodePermissions::Permission::canAdjustLocks); } + bool getThisNodeCanRez() const { return _permissions.can(NodePermissions::Permission::canRezPermanentEntities); } + bool getThisNodeCanRezTmp() const { return _permissions.can(NodePermissions::Permission::canRezTemporaryEntities); } + bool getThisNodeCanWriteAssets() const { return _permissions.can(NodePermissions::Permission::canWriteToAssetServer); } quint16 getSocketLocalPort() const { return _nodeSocket.localPort(); } QUdpSocket& getDTLSSocket(); diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index b277ac0083..08eb9829f8 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -61,10 +61,10 @@ public: void setPermissions(const NodePermissions& newPermissions) { _permissions = newPermissions; } NodePermissions getPermissions() const { return _permissions; } - bool isAllowedEditor() const { return _permissions.canAdjustLocks; } - bool getCanRez() const { return _permissions.canRezPermanentEntities; } - bool getCanRezTmp() const { return _permissions.canRezTemporaryEntities; } - bool getCanWriteToAssetServer() const { return _permissions.canWriteToAssetServer; } + bool isAllowedEditor() const { return _permissions.can(NodePermissions::Permission::canAdjustLocks); } + bool getCanRez() const { return _permissions.can(NodePermissions::Permission::canRezPermanentEntities); } + bool getCanRezTmp() const { return _permissions.can(NodePermissions::Permission::canRezTemporaryEntities); } + bool getCanWriteToAssetServer() const { return _permissions.can(NodePermissions::Permission::canWriteToAssetServer); } friend QDataStream& operator<<(QDataStream& out, const Node& node); friend QDataStream& operator>>(QDataStream& in, Node& node); diff --git a/libraries/networking/src/NodePermissions.cpp b/libraries/networking/src/NodePermissions.cpp index a6e502ff59..023e3cb04a 100644 --- a/libraries/networking/src/NodePermissions.cpp +++ b/libraries/networking/src/NodePermissions.cpp @@ -31,12 +31,14 @@ NodePermissions::NodePermissions(QMap perms) { _groupID = perms["group_id"].toUuid(); } - canConnectToDomain = perms["id_can_connect"].toBool(); - canAdjustLocks = perms["id_can_adjust_locks"].toBool(); - canRezPermanentEntities = perms["id_can_rez"].toBool(); - canRezTemporaryEntities = perms["id_can_rez_tmp"].toBool(); - canWriteToAssetServer = perms["id_can_write_to_asset_server"].toBool(); - canConnectPastMaxCapacity = perms["id_can_connect_past_max_capacity"].toBool(); + permissions = NodePermissions::Permissions(); + permissions |= perms["id_can_connect"].toBool() ? Permission::canConnectToDomain : Permission::none; + permissions |= perms["id_can_adjust_locks"].toBool() ? Permission::canAdjustLocks : Permission::none; + permissions |= perms["id_can_rez"].toBool() ? Permission::canRezPermanentEntities : Permission::none; + permissions |= perms["id_can_rez_tmp"].toBool() ? Permission::canRezTemporaryEntities : Permission::none; + permissions |= perms["id_can_write_to_asset_server"].toBool() ? Permission::canWriteToAssetServer : Permission::none; + permissions |= perms["id_can_connect_past_max_capacity"].toBool() ? + Permission::canConnectPastMaxCapacity : Permission::none; } QVariant NodePermissions::toVariant() { @@ -45,31 +47,24 @@ QVariant NodePermissions::toVariant() { if (_groupIDSet) { values["group_id"] = _groupID; } - values["id_can_connect"] = canConnectToDomain; - values["id_can_adjust_locks"] = canAdjustLocks; - values["id_can_rez"] = canRezPermanentEntities; - values["id_can_rez_tmp"] = canRezTemporaryEntities; - values["id_can_write_to_asset_server"] = canWriteToAssetServer; - values["id_can_connect_past_max_capacity"] = canConnectPastMaxCapacity; + values["id_can_connect"] = can(Permission::canConnectToDomain); + values["id_can_adjust_locks"] = can(Permission::canAdjustLocks); + values["id_can_rez"] = can(Permission::canRezPermanentEntities); + values["id_can_rez_tmp"] = can(Permission::canRezTemporaryEntities); + values["id_can_write_to_asset_server"] = can(Permission::canWriteToAssetServer); + values["id_can_connect_past_max_capacity"] = can(Permission::canConnectPastMaxCapacity); return QVariant(values); } void NodePermissions::setAll(bool value) { - canConnectToDomain = value; - canAdjustLocks = value; - canRezPermanentEntities = value; - canRezTemporaryEntities = value; - canWriteToAssetServer = value; - canConnectPastMaxCapacity = value; + permissions = NodePermissions::Permissions(); + if (value) { + permissions = ~permissions; + } } NodePermissions& NodePermissions::operator|=(const NodePermissions& rhs) { - this->canConnectToDomain |= rhs.canConnectToDomain; - this->canAdjustLocks |= rhs.canAdjustLocks; - this->canRezPermanentEntities |= rhs.canRezPermanentEntities; - this->canRezTemporaryEntities |= rhs.canRezTemporaryEntities; - this->canWriteToAssetServer |= rhs.canWriteToAssetServer; - this->canConnectPastMaxCapacity |= rhs.canConnectPastMaxCapacity; + permissions |= rhs.permissions; return *this; } NodePermissions& NodePermissions::operator|=(const NodePermissionsPointer& rhs) { @@ -84,14 +79,15 @@ NodePermissionsPointer& operator|=(NodePermissionsPointer& lhs, const NodePermis } return lhs; } +NodePermissionsPointer& operator|=(NodePermissionsPointer& lhs, NodePermissions::Permission rhs) { + if (lhs) { + lhs.get()->permissions |= rhs; + } + return lhs; +} NodePermissions& NodePermissions::operator&=(const NodePermissions& rhs) { - this->canConnectToDomain &= rhs.canConnectToDomain; - this->canAdjustLocks &= rhs.canAdjustLocks; - this->canRezPermanentEntities &= rhs.canRezPermanentEntities; - this->canRezTemporaryEntities &= rhs.canRezTemporaryEntities; - this->canWriteToAssetServer &= rhs.canWriteToAssetServer; - this->canConnectPastMaxCapacity &= rhs.canConnectPastMaxCapacity; + permissions &= rhs.permissions; return *this; } NodePermissions& NodePermissions::operator&=(const NodePermissionsPointer& rhs) { @@ -106,15 +102,16 @@ NodePermissionsPointer& operator&=(NodePermissionsPointer& lhs, const NodePermis } return lhs; } +NodePermissionsPointer& operator&=(NodePermissionsPointer& lhs, NodePermissions::Permission rhs) { + if (lhs) { + lhs.get()->permissions &= rhs; + } + return lhs; +} NodePermissions NodePermissions::operator~() { NodePermissions result = *this; - result.canConnectToDomain = !result.canConnectToDomain; - result.canAdjustLocks = !result.canAdjustLocks; - result.canRezPermanentEntities = !result.canRezPermanentEntities; - result.canRezTemporaryEntities = !result.canRezTemporaryEntities; - result.canWriteToAssetServer = !result.canWriteToAssetServer; - result.canConnectPastMaxCapacity = !result.canConnectPastMaxCapacity; + result.permissions = ~permissions; return result; } @@ -128,43 +125,35 @@ NodePermissionsPointer operator~(NodePermissionsPointer& lhs) { } QDataStream& operator<<(QDataStream& out, const NodePermissions& perms) { - out << perms.canConnectToDomain; - out << perms.canAdjustLocks; - out << perms.canRezPermanentEntities; - out << perms.canRezTemporaryEntities; - out << perms.canWriteToAssetServer; - out << perms.canConnectPastMaxCapacity; + out << (uint)perms.permissions; return out; } QDataStream& operator>>(QDataStream& in, NodePermissions& perms) { - in >> perms.canConnectToDomain; - in >> perms.canAdjustLocks; - in >> perms.canRezPermanentEntities; - in >> perms.canRezTemporaryEntities; - in >> perms.canWriteToAssetServer; - in >> perms.canConnectPastMaxCapacity; + uint permissionsInt; + in >> permissionsInt; + perms.permissions = (NodePermissions::Permissions)permissionsInt; return in; } QDebug operator<<(QDebug debug, const NodePermissions& perms) { debug.nospace() << "[permissions: " << perms.getID() << " --"; - if (perms.canConnectToDomain) { + if (perms.can(NodePermissions::Permission::canConnectToDomain)) { debug << " connect"; } - if (perms.canAdjustLocks) { + if (perms.can(NodePermissions::Permission::canAdjustLocks)) { debug << " locks"; } - if (perms.canRezPermanentEntities) { + if (perms.can(NodePermissions::Permission::canRezPermanentEntities)) { debug << " rez"; } - if (perms.canRezTemporaryEntities) { + if (perms.can(NodePermissions::Permission::canRezTemporaryEntities)) { debug << " rez-tmp"; } - if (perms.canWriteToAssetServer) { + if (perms.can(NodePermissions::Permission::canWriteToAssetServer)) { debug << " asset-server"; } - if (perms.canConnectPastMaxCapacity) { + if (perms.can(NodePermissions::Permission::canConnectPastMaxCapacity)) { debug << " ignore-max-cap"; } debug.nospace() << "]"; diff --git a/libraries/networking/src/NodePermissions.h b/libraries/networking/src/NodePermissions.h index e0713e5ce3..1dea560543 100644 --- a/libraries/networking/src/NodePermissions.h +++ b/libraries/networking/src/NodePermissions.h @@ -46,13 +46,17 @@ public: static QString standardNameFriends; static QStringList standardNames; - // the initializations here should match the defaults in describe-settings.json - bool canConnectToDomain { true }; - bool canAdjustLocks { false }; - bool canRezPermanentEntities { false }; - bool canRezTemporaryEntities { false }; - bool canWriteToAssetServer { false }; - bool canConnectPastMaxCapacity { false }; + enum class Permission { + none = 0, + canConnectToDomain = 1, + canAdjustLocks = 2, + canRezPermanentEntities = 4, + canRezTemporaryEntities = 8, + canWriteToAssetServer = 16, + canConnectPastMaxCapacity = 32 + }; + Q_DECLARE_FLAGS(Permissions, Permission) + Permissions permissions; QVariant toVariant(); @@ -66,6 +70,10 @@ public: friend QDataStream& operator<<(QDataStream& out, const NodePermissions& perms); friend QDataStream& operator>>(QDataStream& in, NodePermissions& perms); + void clear(Permission p) { permissions &= (Permission) (~(uint)p); } + void set(Permission p) { permissions |= p; } + bool can(Permission p) const { return permissions.testFlag(p); } + protected: QString _id; QString _userName; @@ -73,6 +81,7 @@ protected: bool _groupIDSet { false }; QUuid _groupID; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(NodePermissions::Permissions) // wrap QHash in a class that forces all keys to be lowercase @@ -96,7 +105,9 @@ const NodePermissions DEFAULT_AGENT_PERMISSIONS; QDebug operator<<(QDebug debug, const NodePermissions& perms); QDebug operator<<(QDebug debug, const NodePermissionsPointer& perms); NodePermissionsPointer& operator|=(NodePermissionsPointer& lhs, const NodePermissionsPointer& rhs); +NodePermissionsPointer& operator|=(NodePermissionsPointer& lhs, NodePermissions::Permission rhs); NodePermissionsPointer& operator&=(NodePermissionsPointer& lhs, const NodePermissionsPointer& rhs); +NodePermissionsPointer& operator&=(NodePermissionsPointer& lhs, NodePermissions::Permission rhs); NodePermissionsPointer operator~(NodePermissionsPointer& lhs); #endif // hifi_NodePermissions_h