Author: adrianc
Date: Wed May 16 18:05:20 2012
New Revision: 1339291
URL: http://svn.apache.org/viewvc?rev=1339291&view=rev
Log:
Overhauled Mini-language <check-permission> element.
Modified:
ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java
Modified: ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd?rev=1339291&r1=1339290&r2=1339291&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Wed May 16
18:05:20 2012
@@ -76,7 +76,8 @@ under the License.
<xs:attribute type="xs:string" name="error-list-name">
<xs:annotation>
<xs:documentation>
- The name of the error message list. Defaults to "error_list".
+ The name of the error message list. It will be created if it
does not exist.
+ Defaults to "error_list".
<br/><br/>
Optional. Attribute type: constant
</xs:documentation>
@@ -517,17 +518,7 @@ under the License.
</xs:documentation>
</xs:annotation>
</xs:attribute>
- <xs:attribute type="xs:string" name="error-list-name">
- <xs:annotation>
- <xs:documentation>
- The name of a list in the method environment that the
error messages will be added to.
- Will be created if it does not exist.
- Defaults to "error_list".
- <br/><br/>
- Optional. Attribute type: constant.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
+ <xs:attribute ref="error-list-name" />
</xs:complexType>
</xs:element>
<xs:element name="set-service-fields" substitutionGroup="CallOperations">
@@ -4156,8 +4147,8 @@ under the License.
<xs:element name="if-has-permission" substitutionGroup="IfBasicOperations">
<xs:annotation>
<xs:documentation>
- The operations contained by the if-has-permission tag will
only be executed if the user has the specified permission, and optionally the
action.
- This tag can contain any of the simple-method operations,
including the conditional/if operations.
+ The operations contained by the if-has-permission element will
only be executed if the user has the specified permission, and optionally the
action.
+ This element can contain any of the simple-method operations,
including the conditional/if operations.
</xs:documentation>
</xs:annotation>
<xs:complexType>
@@ -4165,54 +4156,38 @@ under the License.
<xs:group minOccurs="0" maxOccurs="unbounded"
ref="AllOperations" />
<xs:element minOccurs="0" ref="else" />
</xs:sequence>
- <xs:attribute type="xs:string" name="permission" use="required">
- <xs:annotation>
- <xs:documentation>
- The name of the permission.
- The user must belong to a security group that includes
this permission.
- <br/><br/>
- Required. Attribute type: constant+expr.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="action">
- <xs:annotation>
- <xs:documentation>
- If an action is specified the user can have one of two
permissions: the permission + "_ADMIN" or permission + action.
- Examples of actions include "_CREATE", "_VIEW", etc.
- <br/><br/>
- Optional. Attribute type: constant+expr.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
+ <xs:attributeGroup ref="attlist.check-permission" />
</xs:complexType>
</xs:element>
<xs:element name="check-permission" substitutionGroup="IfOtherOperations">
<xs:annotation>
<xs:documentation>
- The check-permission tag checks to see if the current user has
the specified permission.
- The the user does not have the specified permission or there
is no user associated with the context
- then the failure message from fail-message or file-property
will be added to the specified error list.
+ Checks to see if the current user has the specified permission.
+ If the user does not have the specified permission or if there
is no user associated with the context
+ then the failure message from fail-message or fail-property
will be added to the
+ specified error list.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
- <xs:element minOccurs="0" maxOccurs="1"
ref="accept-userlogin-party"/>
- <xs:element minOccurs="0" maxOccurs="unbounded"
ref="alt-permission"/>
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="alt-permission" />
<xs:choice>
- <xs:element ref="fail-message"/>
- <xs:element ref="fail-property"/>
+ <xs:element ref="fail-message" />
+ <xs:element ref="fail-property" />
</xs:choice>
</xs:sequence>
- <xs:attributeGroup ref="attlist.check-permission"/>
+ <xs:attributeGroup ref="attlist.check-permission" />
+ <xs:attribute ref="error-list-name"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="attlist.check-permission">
<xs:attribute type="xs:string" name="permission" use="required">
<xs:annotation>
<xs:documentation>
- The name of the permission in the database.
- The user must belong to a security group that has this
permission.
+ The name of the permission.
+ The user must belong to a security group that includes
this permission.
+ <br/><br/>
+ Required. Attribute type: constant+expr.
</xs:documentation>
</xs:annotation>
</xs:attribute>
@@ -4221,36 +4196,8 @@ under the License.
<xs:documentation>
If an action is specified the user can have one of two
permissions: the permission + "_ADMIN" or permission + action.
Examples of actions include "_CREATE", "_VIEW", etc.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="error-list-name"
default="error_list">
- <xs:annotation>
- <xs:documentation>
- The name of a list in the method environment that the
error messages will be added to.
- Will be created if does not exist.
- Defaults to "error_list".
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
- <xs:element name="accept-userlogin-party">
- <xs:annotation>
- <xs:documentation>
- If that tag is present userlogin party is accepted, rather
than requiring that the user have the permission.
-
- Often used in cases where you want to allow a user to for
example see their own order, or update their own contact information.
- </xs:documentation>
- </xs:annotation>
- <xs:complexType>
- <xs:attributeGroup ref="attlist.accept-userlogin-party"/>
- </xs:complexType>
- </xs:element>
- <xs:attributeGroup name="attlist.accept-userlogin-party">
- <xs:attribute type="xs:string" name="party-id-env-name"
default="partyId">
- <xs:annotation>
- <xs:documentation>
- Environment variable name used (defaults to partyId),
+ <br/><br/>
+ Optional. Attribute type: constant+expr.
</xs:documentation>
</xs:annotation>
</xs:attribute>
@@ -4258,36 +4205,13 @@ under the License.
<xs:element name="alt-permission">
<xs:annotation>
<xs:documentation>
- Allows to specify a number of alternate permissions, any of
which will satisfy this check permission.
- If the current userLogin does not have any of these
permissions the error will be added to the list.
- If the user has any of the alt-permissions, they subsume
standard permissions.
-
- This tag basically has the same attributes as the
check-permission tag, permission and action.
- Just as the corresponding attributes for the check-permission
element.
+ Specifies an alternate permission. Alternate permissions are
checked when the primary permission check fails.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attributeGroup ref="attlist.alt-permission"/>
+ <xs:attributeGroup ref="attlist.check-permission"/>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.alt-permission">
- <xs:attribute type="xs:string" name="permission" use="required">
- <xs:annotation>
- <xs:documentation>
- The name of the permission in the database.
- The user must belong to a security group that has this
permission.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="action">
- <xs:annotation>
- <xs:documentation>
- If an action is specified the user can have one of two
permissions: the permission + "_ADMIN" or permission + action.
- Examples of actions include "_CREATE", "_VIEW", etc.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<xs:element name="check-id" substitutionGroup="EnvOperations">
<xs:annotation>
<xs:documentation>
Modified:
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java?rev=1339291&r1=1339290&r2=1339291&view=diff
==============================================================================
---
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java
(original)
+++
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java
Wed May 16 18:05:20 2012
@@ -18,18 +18,20 @@
*******************************************************************************/
package org.ofbiz.minilang.method.ifops;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
-import java.util.Map;
import javolution.util.FastList;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.MiniLangValidate;
import org.ofbiz.minilang.SimpleMethod;
-import org.ofbiz.minilang.method.ContextAccessor;
+import org.ofbiz.minilang.method.MessageElement;
import org.ofbiz.minilang.method.MethodContext;
import org.ofbiz.minilang.method.MethodOperation;
import org.ofbiz.security.Security;
@@ -39,84 +41,46 @@ import org.w3c.dom.Element;
/**
* If the user does not have the specified permission the fail-message or
fail-property sub-elements are used to add a message to the error-list.
*/
-public class CheckPermission extends MethodOperation {
+public final class CheckPermission extends MethodOperation {
- /** If null no partyId env-name will be checked against the
userLogin.partyId and accepted as permission */
- ContextAccessor<String> acceptUlPartyIdEnvNameAcsr = null;
- List<PermissionInfo> altPermissions = null;
- ContextAccessor<List<Object>> errorListAcsr;
- boolean isProperty = false;
- String message = null;
- PermissionInfo permissionInfo;
- String propertyResource = null;
+ private final List<PermissionInfo> altPermissionInfoList;
+ private final FlexibleMapAccessor<List<String>> errorListFma;
+ private final MessageElement messageElement;
+ private final PermissionInfo primaryPermissionInfo;
public CheckPermission(Element element, SimpleMethod simpleMethod) throws
MiniLangException {
super(element, simpleMethod);
- permissionInfo = new PermissionInfo(element);
- this.errorListAcsr = new
ContextAccessor<List<Object>>(element.getAttribute("error-list-name"),
"error_list");
- Element acceptUserloginPartyElement =
UtilXml.firstChildElement(element, "accept-userlogin-party");
- if (acceptUserloginPartyElement != null) {
- acceptUlPartyIdEnvNameAcsr = new
ContextAccessor<String>(acceptUserloginPartyElement.getAttribute("party-id-env-name"),
"partyId");
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element,
"permission", "action", "error-list-name");
+ MiniLangValidate.constantAttributes(simpleMethod, element,
"error-list-name");
+ MiniLangValidate.childElements(simpleMethod, element,
"alt-permission", "fail-message", "fail-property");
+ MiniLangValidate.requireAnyChildElement(simpleMethod, element,
"fail-message", "fail-property");
}
+ errorListFma =
FlexibleMapAccessor.getInstance(MiniLangValidate.checkAttribute(element.getAttribute("error-list-name"),
"error_list"));
+ primaryPermissionInfo = new PermissionInfo(element);
List<? extends Element> altPermElements =
UtilXml.childElementList(element, "alt-permission");
if (!altPermElements.isEmpty()) {
- altPermissions = FastList.newInstance();
- }
- for (Element altPermElement : altPermElements) {
- altPermissions.add(new PermissionInfo(altPermElement));
- }
- Element failMessage = UtilXml.firstChildElement(element,
"fail-message");
- Element failProperty = UtilXml.firstChildElement(element,
"fail-property");
- if (failMessage != null) {
- this.message = failMessage.getAttribute("message");
- this.isProperty = false;
- } else if (failProperty != null) {
- this.propertyResource = failProperty.getAttribute("resource");
- this.message = failProperty.getAttribute("property");
- this.isProperty = true;
- }
- }
-
- public void addMessage(List<Object> messages, MethodContext methodContext)
{
- String message = methodContext.expandString(this.message);
- String propertyResource =
methodContext.expandString(this.propertyResource);
- if (!isProperty && message != null) {
- messages.add(message);
- // if (Debug.infoOn())
Debug.logInfo("[SimpleMapOperation.addMessage] Adding message: " + message,
module);
- } else if (isProperty && propertyResource != null && message != null) {
- // String propMsg =
UtilProperties.getPropertyValue(UtilURL.fromResource(propertyResource, loader),
message);
- String propMsg = UtilProperties.getMessage(propertyResource,
message, methodContext.getEnvMap(), methodContext.getLocale());
- if (UtilValidate.isEmpty(propMsg)) {
- messages.add("Simple Method Permission error occurred, but no
message was found, sorry.");
- } else {
- messages.add(methodContext.expandString(propMsg));
+ List<PermissionInfo> permissionInfoList = new
ArrayList<PermissionInfo>(altPermElements.size());
+ for (Element altPermElement : altPermElements) {
+ permissionInfoList.add(new PermissionInfo(altPermElement));
}
- // if (Debug.infoOn())
Debug.logInfo("[SimpleMapOperation.addMessage] Adding property message: " +
propMsg, module);
+ altPermissionInfoList =
Collections.unmodifiableList(permissionInfoList);
} else {
- messages.add("Simple Method Permission error occurred, but no
message was found, sorry.");
- // if (Debug.infoOn())
Debug.logInfo("[SimpleMapOperation.addMessage] ERROR: No message found",
module);
+ altPermissionInfoList = null;
}
+ messageElement = MessageElement.fromParentElement(element,
simpleMethod);
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
boolean hasPermission = false;
- List<Object> messages = errorListAcsr.get(methodContext);
- if (messages == null) {
- messages = FastList.newInstance();
- errorListAcsr.put(methodContext, messages);
- }
- // if no user is logged in, treat as if the user does not have
permission: do not run subops
GenericValue userLogin = methodContext.getUserLogin();
if (userLogin != null) {
Authorization authz = methodContext.getAuthz();
Security security = methodContext.getSecurity();
- if (this.permissionInfo.hasPermission(methodContext, userLogin,
authz, security)) {
- hasPermission = true;
- }
- // if failed, check alternate permissions
- if (!hasPermission && altPermissions != null) {
- for (PermissionInfo altPermInfo : altPermissions) {
+ hasPermission =
this.primaryPermissionInfo.hasPermission(methodContext, userLogin, authz,
security);
+ if (!hasPermission && altPermissionInfoList != null) {
+ for (PermissionInfo altPermInfo : altPermissionInfoList) {
if (altPermInfo.hasPermission(methodContext, userLogin,
authz, security)) {
hasPermission = true;
break;
@@ -124,35 +88,43 @@ public class CheckPermission extends Met
}
}
}
- if (!hasPermission && acceptUlPartyIdEnvNameAcsr != null) {
- String acceptPartyId =
acceptUlPartyIdEnvNameAcsr.get(methodContext);
- if (UtilValidate.isEmpty(acceptPartyId)) {
- // try the parameters Map
- Map<String, Object> parameters =
methodContext.getEnv("parameters");
- if (parameters != null) {
- acceptPartyId = acceptUlPartyIdEnvNameAcsr.get(parameters,
methodContext);
- }
+ if (!hasPermission && messageElement != null) {
+ List<String> messages =
errorListFma.get(methodContext.getEnvMap());
+ if (messages == null) {
+ messages = FastList.newInstance();
+ errorListFma.put(methodContext.getEnvMap(), messages);
}
- if (UtilValidate.isNotEmpty(acceptPartyId) &&
UtilValidate.isNotEmpty(userLogin.getString("partyId")) &&
acceptPartyId.equals(userLogin.getString("partyId"))) {
- hasPermission = true;
- }
- }
- if (!hasPermission) {
- this.addMessage(messages, methodContext);
+ messages.add(messageElement.getMessage(methodContext));
}
return true;
}
@Override
public String expandedString(MethodContext methodContext) {
- // TODO: something more than a stub/dummy
- return this.rawString();
+ return FlexibleStringExpander.expandString(toString(),
methodContext.getEnvMap());
}
@Override
public String rawString() {
- // TODO: add all attributes and other info
- return "<check-permission/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<check-permission ");
+
sb.append("permission=\"").append(this.primaryPermissionInfo.permissionFse).append("\"
");
+ if (!this.primaryPermissionInfo.actionFse.isEmpty()) {
+
sb.append("action=\"").append(this.primaryPermissionInfo.actionFse).append("\"
");
+ }
+ if (!"error_list".equals(this.errorListFma.getOriginalName())) {
+
sb.append("error-list-name=\"").append(this.errorListFma).append("\" ");
+ }
+ if (messageElement != null) {
+
sb.append(">").append(messageElement).append("</check-permission>");
+ } else {
+ sb.append("/>");
+ }
+ return sb.toString();
}
public static final class CheckPermissionFactory implements
Factory<CheckPermission> {
@@ -165,20 +137,23 @@ public class CheckPermission extends Met
}
}
- public static class PermissionInfo {
- String action;
- String permission;
-
- public PermissionInfo(Element altPermissionElement) {
- this.permission = altPermissionElement.getAttribute("permission");
- this.action = altPermissionElement.getAttribute("action");
- }
-
- public boolean hasPermission(MethodContext methodContext, GenericValue
userLogin, Authorization authz, Security security) {
- String permission = methodContext.expandString(this.permission);
- String action = methodContext.expandString(this.action);
-
- if (UtilValidate.isNotEmpty(action)) {
+ private class PermissionInfo {
+ private final FlexibleStringExpander actionFse;
+ private final FlexibleStringExpander permissionFse;
+
+ private PermissionInfo(Element element) throws MiniLangException {
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element,
"permission", "action");
+ MiniLangValidate.requiredAttributes(simpleMethod, element,
"permission");
+ }
+ this.permissionFse =
FlexibleStringExpander.getInstance(element.getAttribute("permission"));
+ this.actionFse =
FlexibleStringExpander.getInstance(element.getAttribute("action"));
+ }
+
+ private boolean hasPermission(MethodContext methodContext,
GenericValue userLogin, Authorization authz, Security security) {
+ String permission =
permissionFse.expandString(methodContext.getEnvMap());
+ String action = actionFse.expandString(methodContext.getEnvMap());
+ if (!action.isEmpty()) {
// run hasEntityPermission
return security.hasEntityPermission(permission, action,
userLogin);
} else {