mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 18:53:37 +02:00
Allowed Editors setting in DomainServer; domain-list wire protocol includes "you can edit" boolean after uuid; entity server checks canEdit flag of node who sends edit requests; interface does not attempt to do edits if DomainServer sent false for "you can edit"
This commit is contained in:
parent
35430a4c7a
commit
485785be7f
11 changed files with 80 additions and 30 deletions
|
@ -92,6 +92,11 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
|
|||
if (_myServer->getOctree()->handlesEditPacketType(packetType)) {
|
||||
PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket);
|
||||
_receivedPacketCount++;
|
||||
|
||||
if (! sendingNode.data()->getCanEdit()) {
|
||||
qDebug("node %s attempted unpermitted edit", sendingNode->getUUID().toString().toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned char* packetData = reinterpret_cast<const unsigned char*>(packet.data());
|
||||
|
||||
|
|
|
@ -41,6 +41,11 @@ int const DomainServer::EXIT_CODE_REBOOT = 234923;
|
|||
|
||||
const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io";
|
||||
|
||||
|
||||
const QString ALLOWED_USERS_SETTINGS_KEYPATH = "security.allowed_users";
|
||||
const QString ALLOWED_EDITORS_SETTINGS_KEYPATH = "security.allowed_editors";
|
||||
|
||||
|
||||
DomainServer::DomainServer(int argc, char* argv[]) :
|
||||
QCoreApplication(argc, argv),
|
||||
_httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
|
||||
|
@ -638,10 +643,16 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock
|
|||
// we got a packetUUID we didn't recognize, just add the node
|
||||
nodeUUID = QUuid::createUuid();
|
||||
}
|
||||
|
||||
|
||||
SharedNodePointer newNode = DependencyManager::get<LimitedNodeList>()->addOrUpdateNode(nodeUUID, nodeType,
|
||||
publicSockAddr, localSockAddr);
|
||||
// if this user is in the editors list (or if the editors list is empty) set the user's node's canEdit to true
|
||||
const QVariant* allowedEditorsVariant =
|
||||
valueForKeyPath(_settingsManager.getSettingsMap(), ALLOWED_EDITORS_SETTINGS_KEYPATH);
|
||||
QStringList allowedEditors = allowedEditorsVariant ? allowedEditorsVariant->toStringList() : QStringList();
|
||||
bool canEdit = allowedEditors.isEmpty() || allowedEditors.contains(username);
|
||||
|
||||
SharedNodePointer newNode =
|
||||
DependencyManager::get<LimitedNodeList>()->addOrUpdateNode(nodeUUID, nodeType,
|
||||
publicSockAddr, localSockAddr, canEdit);
|
||||
// when the newNode is created the linked data is also created
|
||||
// if this was a static assignment set the UUID, set the sendingSockAddr
|
||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData());
|
||||
|
@ -663,7 +674,6 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock
|
|||
}
|
||||
}
|
||||
|
||||
const QString ALLOWED_USERS_SETTINGS_KEYPATH = "security.allowed_users";
|
||||
|
||||
bool DomainServer::shouldAllowConnectionFromNode(const QString& username,
|
||||
const QByteArray& usernameSignature,
|
||||
|
@ -842,6 +852,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
// always send the node their own UUID back
|
||||
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
|
||||
broadcastDataStream << node->getUUID();
|
||||
broadcastDataStream << node->getCanEdit();
|
||||
|
||||
int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos();
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
|
||||
void setIsAuthenticated(bool isAuthenticated) { _isAuthenticated = isAuthenticated; }
|
||||
bool isAuthenticated() const { return _isAuthenticated; }
|
||||
|
||||
|
||||
QHash<QUuid, QUuid>& getSessionSecretHash() { return _sessionSecretHash; }
|
||||
private:
|
||||
QJsonObject mergeJSONStatsFromNewObject(const QJsonObject& newObject, QJsonObject destinationObject);
|
||||
|
|
|
@ -26,22 +26,32 @@ void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
|||
getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties);
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::canEdit() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
return nodeList->getThisNodeCanEdit();
|
||||
}
|
||||
|
||||
|
||||
EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& properties) {
|
||||
|
||||
|
||||
// The application will keep track of creatorTokenID
|
||||
uint32_t creatorTokenID = EntityItemID::getNextCreatorTokenID();
|
||||
|
||||
EntityItemID id(NEW_ENTITY, creatorTokenID, false );
|
||||
|
||||
// If we have a local entity tree set, then also update it.
|
||||
if (_entityTree) {
|
||||
_entityTree->lockForWrite();
|
||||
_entityTree->addEntity(id, properties);
|
||||
_entityTree->unlock();
|
||||
}
|
||||
if (canEdit()) {
|
||||
// If we have a local entity tree set, then also update it.
|
||||
if (_entityTree) {
|
||||
_entityTree->lockForWrite();
|
||||
_entityTree->addEntity(id, properties);
|
||||
_entityTree->unlock();
|
||||
}
|
||||
|
||||
// queue the packet
|
||||
queueEntityMessage(PacketTypeEntityAddOrEdit, id, properties);
|
||||
// queue the packet
|
||||
queueEntityMessage(PacketTypeEntityAddOrEdit, id, properties);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
@ -94,6 +104,11 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(EntityItemID
|
|||
}
|
||||
|
||||
EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const EntityItemProperties& properties) {
|
||||
|
||||
if (! canEdit()) {
|
||||
return entityID;
|
||||
}
|
||||
|
||||
EntityItemID actualID = entityID;
|
||||
// if the entity is unknown, attempt to look it up
|
||||
if (!entityID.isKnownID) {
|
||||
|
|
|
@ -59,6 +59,8 @@ public:
|
|||
|
||||
void setEntityTree(EntityTree* modelTree) { _entityTree = modelTree; }
|
||||
EntityTree* getEntityTree(EntityTree*) { return _entityTree; }
|
||||
|
||||
bool canEdit();
|
||||
|
||||
public slots:
|
||||
/// adds a model with the specific properties
|
||||
|
|
|
@ -411,7 +411,8 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) {
|
|||
}
|
||||
|
||||
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||
bool canEdit) {
|
||||
NodeHash::const_iterator it = _nodeHash.find(uuid);
|
||||
|
||||
if (it != _nodeHash.end()) {
|
||||
|
@ -419,11 +420,12 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
|
|||
|
||||
matchingNode->setPublicSocket(publicSocket);
|
||||
matchingNode->setLocalSocket(localSocket);
|
||||
matchingNode->setCanEdit(canEdit);
|
||||
|
||||
return matchingNode;
|
||||
} else {
|
||||
// we didn't have this node, so add them
|
||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket);
|
||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canEdit);
|
||||
SharedNodePointer newNodePointer(newNode);
|
||||
|
||||
_nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer));
|
||||
|
|
|
@ -76,6 +76,9 @@ class LimitedNodeList : public QObject, public Dependency {
|
|||
public:
|
||||
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
||||
void setSessionUUID(const QUuid& sessionUUID);
|
||||
|
||||
bool getThisNodeCanEdit() { return _thisNodeCanEdit; }
|
||||
void setThisNodeCanEdit(bool canEdit) { _thisNodeCanEdit = canEdit; }
|
||||
|
||||
void rebindNodeSocket();
|
||||
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
||||
|
@ -106,7 +109,7 @@ public:
|
|||
SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
|
||||
|
||||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canEdit);
|
||||
|
||||
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
|
||||
const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; }
|
||||
|
@ -201,6 +204,7 @@ protected:
|
|||
void handleNodeKill(const SharedNodePointer& node);
|
||||
|
||||
QUuid _sessionUUID;
|
||||
bool _thisNodeCanEdit;
|
||||
NodeHash _nodeHash;
|
||||
QReadWriteLock _nodeMutex;
|
||||
QUdpSocket _nodeSocket;
|
||||
|
|
|
@ -41,8 +41,9 @@ const QString& NodeType::getNodeTypeName(NodeType_t nodeType) {
|
|||
return matchedTypeName != TypeNameHash.end() ? matchedTypeName.value() : UNKNOWN_NodeType_t_NAME;
|
||||
}
|
||||
|
||||
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) :
|
||||
NetworkPeer(uuid, publicSocket, localSocket),
|
||||
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
||||
const HifiSockAddr& localSocket, bool canEdit) :
|
||||
NetworkPeer(uuid, publicSocket, localSocket),
|
||||
_type(type),
|
||||
_activeSocket(NULL),
|
||||
_symmetricSocket(),
|
||||
|
@ -52,7 +53,8 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
|||
_pingMs(-1), // "Uninitialized"
|
||||
_clockSkewUsec(0),
|
||||
_mutex(),
|
||||
_clockSkewMovingPercentile(30, 0.8f) // moving 80th percentile of 30 samples
|
||||
_clockSkewMovingPercentile(30, 0.8f), // moving 80th percentile of 30 samples
|
||||
_canEdit(canEdit)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -131,6 +133,7 @@ QDataStream& operator<<(QDataStream& out, const Node& node) {
|
|||
out << node._uuid;
|
||||
out << node._publicSocket;
|
||||
out << node._localSocket;
|
||||
out << node._canEdit;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
@ -140,6 +143,7 @@ QDataStream& operator>>(QDataStream& in, Node& node) {
|
|||
in >> node._uuid;
|
||||
in >> node._publicSocket;
|
||||
in >> node._localSocket;
|
||||
in >> node._canEdit;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace NodeType {
|
|||
class Node : public NetworkPeer {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||
Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canEdit);
|
||||
~Node();
|
||||
|
||||
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
|
||||
|
@ -76,6 +76,9 @@ public:
|
|||
virtual void setSymmetricSocket(const HifiSockAddr& symmetricSocket);
|
||||
|
||||
const HifiSockAddr* getActiveSocket() const { return _activeSocket; }
|
||||
|
||||
void setCanEdit(bool canEdit) { _canEdit = canEdit; }
|
||||
bool getCanEdit() { return _canEdit; }
|
||||
|
||||
void activatePublicSocket();
|
||||
void activateLocalSocket();
|
||||
|
@ -101,6 +104,7 @@ private:
|
|||
int _clockSkewUsec;
|
||||
QMutex _mutex;
|
||||
MovingPercentile _clockSkewMovingPercentile;
|
||||
bool _canEdit;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, const Node &message);
|
||||
|
|
|
@ -370,13 +370,6 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
|||
|
||||
int readNodes = 0;
|
||||
|
||||
// setup variables to read into from QDataStream
|
||||
qint8 nodeType;
|
||||
|
||||
QUuid nodeUUID, connectionUUID;
|
||||
|
||||
HifiSockAddr nodePublicSocket;
|
||||
HifiSockAddr nodeLocalSocket;
|
||||
|
||||
QDataStream packetStream(packet);
|
||||
packetStream.skipRawData(numBytesForPacketHeader(packet));
|
||||
|
@ -385,10 +378,20 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
|||
QUuid newUUID;
|
||||
packetStream >> newUUID;
|
||||
setSessionUUID(newUUID);
|
||||
|
||||
bool thisNodeCanEdit;
|
||||
packetStream >> thisNodeCanEdit;
|
||||
setThisNodeCanEdit(thisNodeCanEdit);
|
||||
|
||||
// pull each node in the packet
|
||||
while(packetStream.device()->pos() < packet.size()) {
|
||||
packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket;
|
||||
// setup variables to read into from QDataStream
|
||||
qint8 nodeType;
|
||||
QUuid nodeUUID, connectionUUID;
|
||||
HifiSockAddr nodePublicSocket, nodeLocalSocket;
|
||||
bool canEdit;
|
||||
|
||||
packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> canEdit;
|
||||
|
||||
// if the public socket address is 0 then it's reachable at the same IP
|
||||
// as the domain server
|
||||
|
@ -396,7 +399,7 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
|||
nodePublicSocket.setAddress(_domainHandler.getIP());
|
||||
}
|
||||
|
||||
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket);
|
||||
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket, canEdit);
|
||||
|
||||
packetStream >> connectionUUID;
|
||||
node->setConnectionSecret(connectionUUID);
|
||||
|
|
|
@ -64,7 +64,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
|||
return 2;
|
||||
case PacketTypeDomainList:
|
||||
case PacketTypeDomainListRequest:
|
||||
return 3;
|
||||
return 4;
|
||||
case PacketTypeCreateAssignment:
|
||||
case PacketTypeRequestAssignment:
|
||||
return 2;
|
||||
|
|
Loading…
Reference in a new issue