cap lifetime rather than reject edits from nodes which only have tmp-rez rights

This commit is contained in:
Seth Alves 2016-06-21 16:48:04 -07:00
parent 5878927bd0
commit 9ca27f267d
4 changed files with 32 additions and 38 deletions

View file

@ -384,7 +384,7 @@
"name": "standard_permissions", "name": "standard_permissions",
"type": "table", "type": "table",
"label": "Domain-Wide User Permissions", "label": "Domain-Wide User Permissions",
"help": "Indicate which users or groups can have which <a data-toggle='tooltip' data-html=true title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the &ldquo;locked&rdquo; property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain&rsquo;s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let&rsquo;s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>domain-wide permissions</a>.", "help": "Indicate which users or groups can have which <a data-toggle='tooltip' data-html=true title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the &ldquo;locked&rdquo; property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain&rsquo;s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let&rsquo;s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>domain-wide permissions</a>.",
"caption": "Standard Permissions", "caption": "Standard Permissions",
"can_add_new_rows": false, "can_add_new_rows": false,
@ -394,7 +394,7 @@
"span": 1 "span": 1
}, },
{ {
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the &ldquo;locked&rdquo; property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain&rsquo;s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let&rsquo;s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>?</a>", "label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the &ldquo;locked&rdquo; property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain&rsquo;s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let&rsquo;s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>?</a>",
"span": 6 "span": 6
} }
], ],
@ -463,7 +463,7 @@
"span": 1 "span": 1
}, },
{ {
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the &ldquo;locked&rdquo; property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain&rsquo;s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let&rsquo;s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>?</a>", "label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the &ldquo;locked&rdquo; property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain&rsquo;s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let&rsquo;s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>?</a>",
"span": 6 "span": 6
} }
], ],

View file

@ -148,11 +148,11 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
return false; return false;
} }
if (!canRezPermanentEntities && (entity->getLifetime() != properties.getLifetime())) { if (!canRezPermanentEntities) {
// we don't allow a Node that can't create permanent entities to adjust lifetimes on existing ones // we don't allow a Node that can't create permanent entities to raise lifetimes on existing ones
if (properties.lifetimeChanged()) { if (properties.getLifetime() == ENTITY_ITEM_IMMORTAL_LIFETIME || properties.getLifetime() > _maxTmpEntityLifetime) {
qCDebug(entities) << "Refusing disallowed entity lifetime adjustment."; qCDebug(entities) << "Capping disallowed entity lifetime adjustment.";
return false; properties.setLifetime(_maxTmpEntityLifetime);
} }
} }
@ -321,26 +321,9 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
return true; return true;
} }
bool EntityTree::permissionsAllowRez(const EntityItemProperties& properties, bool canRez, bool canRezTmp) {
float lifeTime = properties.getLifetime();
if (lifeTime == ENTITY_ITEM_IMMORTAL_LIFETIME || lifeTime > _maxTmpEntityLifetime) {
// this is an attempt to rez a permanent or non-temporary entity.
if (!canRez) {
return false;
}
} else {
// this is an attempt to rez a temporary entity.
if (!canRezTmp) {
return false;
}
}
return true;
}
EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
EntityItemPointer result = NULL; EntityItemPointer result = NULL;
EntityItemProperties props = properties;
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
if (!nodeList) { if (!nodeList) {
@ -348,16 +331,19 @@ EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const Enti
return nullptr; return nullptr;
} }
bool clientOnly = properties.getClientOnly(); bool clientOnly = props.getClientOnly();
if (!clientOnly && getIsClient() && if (!clientOnly && getIsClient() && !nodeList->getThisNodeCanRez() && nodeList->getThisNodeCanRezTmp()) {
!permissionsAllowRez(properties, nodeList->getThisNodeCanRez(), nodeList->getThisNodeCanRezTmp())) { // we are a client which is only allowed to rez temporary entities. cap the lifetime.
// if our Node isn't allowed to create entities in this domain, don't try. if (props.getLifetime() == ENTITY_ITEM_IMMORTAL_LIFETIME) {
return nullptr; props.setLifetime(_maxTmpEntityLifetime);
} else {
props.setLifetime(glm::min(props.getLifetime(), _maxTmpEntityLifetime));
}
} }
bool recordCreationTime = false; bool recordCreationTime = false;
if (properties.getCreated() == UNKNOWN_CREATED_TIME) { if (props.getCreated() == UNKNOWN_CREATED_TIME) {
// the entity's creation time was not specified in properties, which means this is a NEW entity // the entity's creation time was not specified in properties, which means this is a NEW entity
// and we must record its creation time // and we must record its creation time
recordCreationTime = true; recordCreationTime = true;
@ -372,8 +358,8 @@ EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const Enti
} }
// construct the instance of the entity // construct the instance of the entity
EntityTypes::EntityType type = properties.getType(); EntityTypes::EntityType type = props.getType();
result = EntityTypes::constructEntityItem(type, entityID, properties); result = EntityTypes::constructEntityItem(type, entityID, props);
if (result) { if (result) {
if (recordCreationTime) { if (recordCreationTime) {
@ -922,11 +908,20 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
EntityItemID entityItemID; EntityItemID entityItemID;
EntityItemProperties properties; EntityItemProperties properties;
startDecode = usecTimestampNow(); startDecode = usecTimestampNow();
bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength, processedBytes, bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength, processedBytes,
entityItemID, properties); entityItemID, properties);
endDecode = usecTimestampNow(); endDecode = usecTimestampNow();
if (!senderNode->getCanRez() && senderNode->getCanRezTmp()) {
// this node is only allowed to rez temporary entities. cap the lifetime.
if (properties.getLifetime() == ENTITY_ITEM_IMMORTAL_LIFETIME) {
properties.setLifetime(_maxTmpEntityLifetime);
} else {
properties.setLifetime(glm::min(properties.getLifetime(), _maxTmpEntityLifetime));
}
}
// If we got a valid edit packet, then it could be a new entity or it could be an update to // If we got a valid edit packet, then it could be a new entity or it could be an update to
// an existing entity... handle appropriately // an existing entity... handle appropriately
if (validEditPacket) { if (validEditPacket) {
@ -955,7 +950,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
endUpdate = usecTimestampNow(); endUpdate = usecTimestampNow();
_totalUpdates++; _totalUpdates++;
} else if (message.getType() == PacketType::EntityAdd) { } else if (message.getType() == PacketType::EntityAdd) {
if (permissionsAllowRez(properties, senderNode->getCanRez(), senderNode->getCanRezTmp())) { if (senderNode->getCanRez() || senderNode->getCanRezTmp()) {
// this is a new entity... assign a new entityID // this is a new entity... assign a new entityID
properties.setCreated(properties.getLastEdited()); properties.setCreated(properties.getLastEdited());
startCreate = usecTimestampNow(); startCreate = usecTimestampNow();

View file

@ -64,7 +64,6 @@ public:
void setEntityMaxTmpLifetime(float maxTmpEntityLifetime) { _maxTmpEntityLifetime = maxTmpEntityLifetime; } void setEntityMaxTmpLifetime(float maxTmpEntityLifetime) { _maxTmpEntityLifetime = maxTmpEntityLifetime; }
bool permissionsAllowRez(const EntityItemProperties& properties, bool canRez, bool canRezTmp);
/// Implements our type specific root element factory /// Implements our type specific root element factory
virtual OctreeElementPointer createNewElement(unsigned char* octalCode = NULL) override; virtual OctreeElementPointer createNewElement(unsigned char* octalCode = NULL) override;

View file

@ -332,7 +332,7 @@ var toolBar = (function() {
that.setActive = function(active) { that.setActive = function(active) {
if (active != isActive) { if (active != isActive) {
if (active && !Entities.canAdjustLocks()) { if (active && !Entities.canRez() && !Entities.canRezTmp()) {
Window.alert(INSUFFICIENT_PERMISSIONS_ERROR_MSG); Window.alert(INSUFFICIENT_PERMISSIONS_ERROR_MSG);
} else { } else {
Messages.sendLocalMessage("edit-events", JSON.stringify({ Messages.sendLocalMessage("edit-events", JSON.stringify({