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 { |
Free forum by Nabble | Edit this page |