svn commit: r1339291 - in /ofbiz/trunk/framework/minilang: dtd/simple-methods-v2.xsd src/org/ofbiz/minilang/method/ifops/CheckPermission.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1339291 - in /ofbiz/trunk/framework/minilang: dtd/simple-methods-v2.xsd src/org/ofbiz/minilang/method/ifops/CheckPermission.java

adrianc
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".
                 &lt;br/&gt;&lt;br/&gt;
                 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".
-                        &lt;br/&gt;&lt;br/&gt;
-                        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.
-                        &lt;br/&gt;&lt;br/&gt;
-                        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.
-                        &lt;br/&gt;&lt;br/&gt;
-                        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.
+                    &lt;br/&gt;&lt;br/&gt;
+                    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),
+                    &lt;br/&gt;&lt;br/&gt;
+                    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 {