PL-8698 "Test constraint" in Access group constraints should check Groovy script too

This commit is contained in:
Konstantin Krivopustov 2017-04-04 10:14:53 +04:00
parent 5992c99675
commit 843ab009a5
5 changed files with 53 additions and 17 deletions

View File

@ -141,4 +141,6 @@ public interface Security {
* Check if there are registered memory constraints of specified {@code operationTypes} for the metaClass or it's original metaClass
*/
boolean hasInMemoryConstraints(MetaClass metaClass, ConstraintOperationType... operationTypes);
Object evaluateConstraintScript(Entity entity, String groovyScript);
}

View File

@ -207,13 +207,8 @@ public class SecurityImpl implements Security {
String metaClassName = entity.getMetaClass().getName();
String groovyScript = constraint.getGroovyScript();
if (constraint.getCheckType().memory() && StringUtils.isNotBlank(groovyScript)) {
Map<String, Object> context = new HashMap<>();
context.put("__entity__", metadataTools.deepCopy(entity)); // copy to avoid implicit modification
context.put("parse", new MethodClosure(this, "parseValue"));
context.put("userSession", userSessionSource.getUserSession());
fillGroovyConstraintsContext(context);
try {
Object o = scripting.evaluateGroovy(groovyScript.replace("{E}", "__entity__"), context);
Object o = evaluateConstraintScript(entity, groovyScript);
if (Boolean.FALSE.equals(o)) {
log.trace("Entity does not match security constraint. Entity class [{}]. Entity [{}]. Constraint [{}].",
metaClassName, entity.getId(), constraint.getCheckType());
@ -228,6 +223,16 @@ public class SecurityImpl implements Security {
return true;
}
@Override
public Object evaluateConstraintScript(Entity entity, String groovyScript) {
Map<String, Object> context = new HashMap<>();
context.put("__entity__", metadataTools.deepCopy(entity)); // copy to avoid implicit modification
context.put("parse", new MethodClosure(this, "parseValue"));
context.put("userSession", userSessionSource.getUserSession());
fillGroovyConstraintsContext(context);
return scripting.evaluateGroovy(groovyScript.replace("{E}", "__entity__"), context);
}
/**
* Override if you need specific context variables in Groovy constraints.
*

View File

@ -17,6 +17,7 @@
package com.haulmont.cuba.gui.app.security.constraint.edit;
import com.google.common.base.Strings;
import com.haulmont.bali.util.Dom4j;
import com.haulmont.chile.core.model.MetaClass;
import com.haulmont.cuba.core.global.*;
@ -45,6 +46,7 @@ import com.haulmont.cuba.security.entity.ConstraintCheckType;
import com.haulmont.cuba.security.entity.ConstraintOperationType;
import com.haulmont.cuba.security.entity.FilterEntity;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.dom4j.Element;
import javax.inject.Inject;
@ -117,6 +119,9 @@ public class ConstraintEditor extends AbstractEditor<Constraint> {
@Inject
protected UserManagementService userManagementService;
@Inject
protected Security security;
protected Map<Object, String> entities;
protected static final String SESSION_PREFIX = "session$";
@ -317,12 +322,10 @@ public class ConstraintEditor extends AbstractEditor<Constraint> {
}
public void testConstraint() {
Constraint constraint = (Constraint) getItem();
Constraint constraint = getItem();
String entityName = constraint.getEntityName();
if (validateAll()) {
String baseQueryString = "select e from " + entityName + " e";
String resultQueryStr = null;
try {
QueryTransformer transformer = QueryTransformerFactory.createTransformer(baseQueryString);
if (StringUtils.isNotBlank(constraint.getJoinClause())) {
@ -337,7 +340,6 @@ public class ConstraintEditor extends AbstractEditor<Constraint> {
datasource.setQuery(transformer.getResult());
datasource.refresh();
showNotification(getMessage("notification.success"), NotificationType.HUMANIZED);
} catch (JpqlSyntaxException e) {
StringBuilder stringBuilder = new StringBuilder();
for (ErrorRec rec : e.getErrorRecs()) {
@ -345,10 +347,35 @@ public class ConstraintEditor extends AbstractEditor<Constraint> {
}
showMessageDialog(getMessage("notification.error"),
formatMessage("notification.syntaxErrors", stringBuilder), MessageType.WARNING_HTML);
return;
} catch (Exception e) {
String msg;
Throwable rootCause = ExceptionUtils.getRootCause(e);
if (rootCause == null)
rootCause = e;
if (rootCause instanceof RemoteException) {
List<RemoteException.Cause> causes = ((RemoteException) rootCause).getCauses();
RemoteException.Cause cause = causes.get(causes.size() - 1);
msg = cause.getThrowable() != null ? cause.getThrowable().toString() : cause.getClassName() + ": " + cause.getMessage();
} else {
msg = rootCause.toString();
}
showMessageDialog(getMessage("notification.error"),
formatMessage("notification.runtimeError", msg), MessageType.WARNING_HTML);
return;
}
if (!Strings.isNullOrEmpty(constraint.getGroovyScript())) {
try {
security.evaluateConstraintScript(metadata.create(entityName), constraint.getGroovyScript());
} catch (Exception e) {
showMessageDialog(getMessage("notification.error"),
formatMessage("notification.runtimeError", resultQueryStr, e.getMessage()), MessageType.WARNING_HTML);
}
formatMessage("notification.scriptRuntimeError", e.toString()), MessageType.WARNING_HTML);
return;
}
}
showNotification(getMessage("notification.success"), NotificationType.HUMANIZED);
}
}
}

View File

@ -48,7 +48,8 @@ code=Code
type=Type
notification.entityIsEmpty=Please select entity name
notification.syntaxErrors=The following syntax errors found while parsing 'where' and 'join' clauses:<br> %s
notification.runtimeError=An error occurred while running resulting query <br>[<b>%s</b>]<br>%s
notification.syntaxErrors=Syntax errors found while parsing 'where' and 'join' clauses:<br> %s
notification.runtimeError=An error occurred while running resulting query.<br><br>%s
notification.scriptRuntimeError=An error occurred while evaluating Groovy script.<br><br>%s
notification.error=Error
notification.success=The constraint has been successfully checked
notification.success=The constraint is syntactically correct

View File

@ -45,7 +45,8 @@ code=Код
type=Тип
notification.entityIsEmpty=Пожалуйста выберите имя сущности
notification.syntaxErrors=В операторах Where и Join обнаружены следующие синтаксические ошибки:<br> %s
notification.runtimeError=При запуске результирующего запроса <br>[<b>%s</b>] произошла ошибка:<br>%s
notification.syntaxErrors=В операторах Where и Join обнаружены синтаксические ошибки:<br> %s
notification.runtimeError=При запуске результирующего запроса произошла ошибка.<br><br>%s
notification.scriptRuntimeError=При запуске скрипта Groovy произошла ошибка.<br><br>%s
notification.error=Ошибка
notification.success=Проверка успешно завершена
notification.success=Ограничение синтаксически корректно