Filter failure mode updated

The decision here is that all failed filters (syntax errors, 404s,
bad urls etc...) lock out all edits for those without lock rights.
If it is the domain-wide one, then that applies to entire domain.
If a zone filter, then that applies to all edits in that zone.

Also - zone filters don't apply to the zone itself.  Other zone filters
whose zones lie within that zone _do_ apply, in addition to the global
one.
This commit is contained in:
David Kelly 2017-02-14 13:05:12 -07:00
parent 156e365eff
commit 342584b2a8
4 changed files with 31 additions and 25 deletions

View file

@ -302,22 +302,16 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio
// connect the filterAdded signal, and block edits until you hear back
connect(entityEditFilters.data(), &EntityEditFilters::filterAdded, this, &EntityServer::entityFilterAdded);
entityEditFilters->rejectAll(true);
entityEditFilters->addFilter(EntityItemID(), filterURL);
}
}
void EntityServer::entityFilterAdded(EntityItemID id, bool success) {
if (id.isInvalidID()) {
// this is the domain-wide entity filter, which we want to stop
// the world for
auto entityEditFilters = qobject_cast<EntityEditFilters*>(sender());
if (success) {
qDebug() << "entity edit filter for " << id << "added successfully";
entityEditFilters->rejectAll(false);
} else {
qDebug() << "entity edit filter unsuccessfully added, stopping...";
stop();
qDebug() << "entity edit filter unsuccessfully added, all edits will be rejected for those without lock rights.";
}
}
}

View file

@ -42,20 +42,18 @@ QList<EntityItemID> EntityEditFilters::getZonesByPosition(glm::vec3& position) {
return zones;
}
bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, EntityTree::FilterType filterType) {
bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged,
EntityTree::FilterType filterType, EntityItemID& itemID) {
qCDebug(entities) << "in EntityEditFilters";
// allows us to start entity server and reject all edits until filter is setup
if (_rejectAll) {
qCDebug(entities) << "rejecting all edits";
return false;
}
// get the ids of all the zones (plus the global entity edit filter) that the position
// lies within
auto zoneIDs = getZonesByPosition(position);
for (auto id : zoneIDs) {
if (id == itemID) {
qCDebug(entities) << "zone filter not applied to its own edit";
continue;
}
qCDebug(entities) << "applying filter for zone" << id;
// get the filter pair, etc...
@ -64,7 +62,10 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper
_lock.unlock();
if (filterData.valid()) {
if (filterData.rejectAll) {
qCDebug(entities) << "rejecting all edits";
return false;
}
auto oldProperties = propertiesIn.getDesiredProperties();
auto specifiedProperties = propertiesIn.getChangedProperties();
propertiesIn.setDesiredProperties(specifiedProperties);
@ -81,7 +82,6 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper
result = QScriptValue();
}
if (result.isObject()){
qCDebug(entities) << "filter result accepted";
// make propertiesIn reflect the changes, for next filter...
@ -131,7 +131,15 @@ void EntityEditFilters::addFilter(EntityItemID entityID, QString filterURL) {
// first remove any existing info for this entity
removeFilter(entityID);
// reject all edits until we load the script
FilterData filterData;
filterData.rejectAll = true;
_lock.lockForWrite();
_filterDataMap.insert(entityID, filterData);
_lock.unlock();
auto scriptRequest = ResourceManager::createResourceRequest(this, scriptURL);
if (!scriptRequest) {
qWarning() << "Could not create ResourceRequest for Entity Edit filter script at" << scriptURL.toString();
@ -195,6 +203,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) {
// put the engine in the engine map (so we don't leak them, etc...)
FilterData filterData;
filterData.engine = engine;
filterData.rejectAll = false;
// define the uncaughtException function
QScriptEngine& engineRef = *engine;
@ -209,10 +218,11 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) {
global.setProperty("Entities", entitiesObject);
filterData.filterFn = global.property("filter");
if (!filterData.filterFn.isFunction()) {
qDebug() << "Filter function specified but not found. Ignoring filter";
qDebug() << "Filter function specified but not found. Will reject all edits for those without lock rights.";
delete engine;
return;
filterData.rejectAll=true;
}
_lock.lockForWrite();
_filterDataMap.insert(entityID, filterData);

View file

@ -30,8 +30,10 @@ public:
QScriptValue filterFn;
std::function<bool()> uncaughtExceptions;
QScriptEngine* engine;
bool valid() { return (engine != nullptr && filterFn.isFunction() && uncaughtExceptions); }
bool rejectAll;
FilterData(): engine(nullptr), rejectAll(false) {};
bool valid() { return (rejectAll || (engine != nullptr && filterFn.isFunction() && uncaughtExceptions)); }
};
EntityEditFilters() {};
@ -40,8 +42,8 @@ public:
void addFilter(EntityItemID entityID, QString filterURL);
void removeFilter(EntityItemID entityID);
bool filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, EntityTree::FilterType filterType);
void rejectAll(bool state) {_rejectAll = state; }
bool filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged,
EntityTree::FilterType filterType, EntityItemID& entityID);
signals:
void filterAdded(EntityItemID id, bool success);

View file

@ -928,9 +928,9 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList<Q
bool EntityTree::filterProperties(EntityItemPointer& existingEntity, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, FilterType filterType) {
bool accepted = true;
auto entityEditFilters = DependencyManager::get<EntityEditFilters>();
if (entityEditFilters) {
if (entityEditFilters && existingEntity) {
auto position = existingEntity->getPosition();
accepted = entityEditFilters->filter(position, propertiesIn, propertiesOut, wasChanged, filterType);
accepted = entityEditFilters->filter(position, propertiesIn, propertiesOut, wasChanged, filterType, existingEntity->getEntityItemID());
}
return accepted;