Author: adrianc
Date: Mon Dec 2 04:19:48 2013
New Revision: 1546891
URL: http://svn.apache.org/r1546891
Log:
Added a new attribute to the ofbiz-component.xml <webapp> element -
access-permission. It is used to specify an explicit permission to allow access
to the web application, instead of the implied permissions specified in the
base-permission attribute (which causes unpredictable behavior).
Also moved web access authorization code from the Flat Grey visual theme to
LoginWorker.java. This change needs to be copied to other visual themes as well.
Modified:
ofbiz/trunk/framework/base/dtd/ofbiz-component.xsd
ofbiz/trunk/framework/base/src/org/ofbiz/base/component/ComponentConfig.java
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java
ofbiz/trunk/themes/flatgrey/includes/appbar.ftl
Modified: ofbiz/trunk/framework/base/dtd/ofbiz-component.xsd
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/dtd/ofbiz-component.xsd?rev=1546891&r1=1546890&r2=1546891&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/dtd/ofbiz-component.xsd (original)
+++ ofbiz/trunk/framework/base/dtd/ofbiz-component.xsd Mon Dec 2 04:19:48 2013
@@ -198,8 +198,24 @@ under the License.
<xs:attribute type="xs:string" name="server" use="required"/>
<xs:attribute type="xs:string" name="location" use="required"/>
<xs:attribute type="xs:string" name="mount-point"/>
+ <xs:attribute type="xs:string" name="access-permission">
+ <xs:annotation>
+ <xs:documentation>
+ A user must have this permission to access the application.
+ When omitted, the application can be used by anyone. This
+ attribute takes precedence over the base-permission
attribute -
+ if both attributes are not empty, this attribute will be
used.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
<xs:attribute type="xs:string" name="base-permission">
- <xs:annotation><xs:documentation>A user must have ALL of the
permissions in the list to access the
application</xs:documentation></xs:annotation>
+ <xs:annotation>
+ <xs:documentation>
+ Deprecated - use access-permission.
+ A user must have ALL of the permissions in the list to
access the application.
+ When set to "NONE", the application can be used by anyone.
+ </xs:documentation>
+ </xs:annotation>
</xs:attribute>
<xs:attribute name="privileged" default="false">
<xs:simpleType>
Modified:
ofbiz/trunk/framework/base/src/org/ofbiz/base/component/ComponentConfig.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/component/ComponentConfig.java?rev=1546891&r1=1546890&r2=1546891&view=diff
==============================================================================
---
ofbiz/trunk/framework/base/src/org/ofbiz/base/component/ComponentConfig.java
(original)
+++
ofbiz/trunk/framework/base/src/org/ofbiz/base/component/ComponentConfig.java
Mon Dec 2 04:19:48 2013
@@ -829,6 +829,7 @@ public final class ComponentConfig {
public final boolean privileged;
// CatalinaContainer modifies this field.
private volatile boolean appBarDisplay;
+ private final String accessPermission;
private WebappInfo(ComponentConfig componentConfig, Element element) {
this.componentConfig = componentConfig;
@@ -872,6 +873,7 @@ public final class ComponentConfig {
this.appBarDisplay =
!"false".equals(element.getAttribute("app-bar-display"));
this.sessionCookieAccepted =
!"false".equals(element.getAttribute("session-cookie-accepted"));
this.privileged =
!"false".equals(element.getAttribute("privileged"));
+ this.accessPermission = element.getAttribute("access-permission");
String basePermStr = element.getAttribute("base-permission");
if (!basePermStr.isEmpty()) {
this.basePermission = basePermStr.split(",");
@@ -921,6 +923,10 @@ public final class ComponentConfig {
return this.appBarDisplay;
}
+ public String getAccessPermission() {
+ return this.accessPermission;
+ }
+
public String[] getBasePermission() {
return this.basePermission;
}
Modified:
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java?rev=1546891&r1=1546890&r2=1546891&view=diff
==============================================================================
--- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java
(original)
+++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java
Mon Dec 2 04:19:48 2013
@@ -23,6 +23,8 @@ import static org.ofbiz.base.util.UtilGe
import java.math.BigInteger;
import java.security.cert.X509Certificate;
import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
@@ -1058,35 +1060,70 @@ public class LoginWorker {
"Y".equalsIgnoreCase(userLogin.getString("hasLoggedOut")) :
false);
}
+ /**
+ * Returns <code>true</code> if the specified user is authorized to access
the specified web application.
+ * @param info
+ * @param security
+ * @param userLogin
+ * @return <code>true</code> if the specified user is authorized to access
the specified web application
+ */
+ public static boolean hasApplicationPermission(ComponentConfig.WebappInfo
info, Security security, GenericValue userLogin) {
+ // New authorization attribute takes precedence.
+ String accessPermission = info.getAccessPermission();
+ if (!accessPermission.isEmpty()) {
+ return security.hasPermission(accessPermission, userLogin);
+ }
+ for (String permission: info.getBasePermission()) {
+ if (!"NONE".equals(permission) &&
!security.hasEntityPermission(permission, "_VIEW", userLogin)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static boolean hasBasePermission(GenericValue userLogin,
HttpServletRequest request) {
Security security = (Security) request.getAttribute("security");
if (security != null) {
ServletContext context = (ServletContext)
request.getAttribute("servletContext");
String serverId = (String) context.getAttribute("_serverId");
-
// get a context path from the request, if it is empty then assume
it is the root mount point
String contextPath = request.getContextPath();
if (UtilValidate.isEmpty(contextPath)) {
contextPath = "/";
}
-
ComponentConfig.WebappInfo info =
ComponentConfig.getWebAppInfo(serverId, contextPath);
if (info != null) {
- for (String permission: info.getBasePermission()) {
- if (!"NONE".equals(permission) &&
!security.hasEntityPermission(permission, "_VIEW", userLogin)) {
- return false;
- }
- }
+ return hasApplicationPermission(info, security, userLogin);
} else {
Debug.logInfo("No webapp configuration found for : " +
serverId + " / " + contextPath, module);
}
} else {
Debug.logWarning("Received a null Security object from
HttpServletRequest", module);
}
-
return true;
}
+ /**
+ * Returns a <code>Collection</code> of <code>WebappInfo</code> instances
that the specified
+ * user is authorized to access.
+ * @param security
+ * @param userLogin
+ * @param serverName
+ * @param menuName
+ * @return A <code>Collection</code> <code>WebappInfo</code> instances
that the specified
+ * user is authorized to access
+ */
+ public static Collection<ComponentConfig.WebappInfo>
getAppBarWebInfos(Security security, GenericValue userLogin, String serverName,
String menuName) {
+ Collection<ComponentConfig.WebappInfo> allInfos =
ComponentConfig.getAppBarWebInfos(serverName, menuName);
+ Collection<ComponentConfig.WebappInfo> allowedInfos = new
ArrayList<ComponentConfig.WebappInfo>(allInfos.size());
+ for (ComponentConfig.WebappInfo info : allInfos) {
+ if (hasApplicationPermission(info, security, userLogin)) {
+ allowedInfos.add(info);
+ }
+ }
+ return allowedInfos;
+ }
+
public static Map<String, Object> getUserLoginSession(GenericValue
userLogin) {
Delegator delegator = userLogin.getDelegator();
GenericValue userLoginSession;
Modified: ofbiz/trunk/themes/flatgrey/includes/appbar.ftl
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/themes/flatgrey/includes/appbar.ftl?rev=1546891&r1=1546890&r2=1546891&view=diff
==============================================================================
--- ofbiz/trunk/themes/flatgrey/includes/appbar.ftl (original)
+++ ofbiz/trunk/themes/flatgrey/includes/appbar.ftl Mon Dec 2 04:19:48 2013
@@ -21,8 +21,8 @@ under the License.
<#if (externalLoginKey)?exists><#assign externalKeyParam =
"?externalLoginKey=" + requestAttributes.externalLoginKey?if_exists></#if>
<#assign ofbizServerName =
application.getAttribute("_serverId")?default("default-server")>
<#assign contextPath = request.getContextPath()>
-<#assign displayApps =
Static["org.ofbiz.base.component.ComponentConfig"].getAppBarWebInfos(ofbizServerName,
"main")>
-<#assign displaySecondaryApps =
Static["org.ofbiz.base.component.ComponentConfig"].getAppBarWebInfos(ofbizServerName,
"secondary")>
+<#assign displayApps =
Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security,
userLogin, ofbizServerName, "main")>
+<#assign displaySecondaryApps =
Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security,
userLogin, ofbizServerName, "secondary")>
<#if userLogin?has_content>
<div id="main-navigation">
@@ -31,53 +31,34 @@ under the License.
<#assign firstApp = true>
<#list displayApps as display>
<#assign thisApp = display.getContextRoot()>
- <#assign permission = true>
<#assign selected = false>
- <#assign permissions = display.getBasePermission()>
- <#list permissions as perm>
- <#if (perm != "NONE" && !security.hasEntityPermission(perm, "_VIEW",
session))>
- <#-- User must have ALL permissions in the base-permission list -->
- <#assign permission = false>
- </#if>
- </#list>
- <#if permission == true>
- <#if thisApp == contextPath || contextPath + "/" == thisApp>
- <#assign selected = true>
- </#if>
- <#assign servletPath =
Static["org.ofbiz.webapp.WebAppUtil"].getControlServletPath(display)>
- <#assign thisURL = StringUtil.wrapString(servletPath)>
- <#if thisApp != "/">
- <#assign thisURL = thisURL + "main">
- </#if>
- <#if layoutSettings.suppressTab?exists && display.name ==
layoutSettings.suppressTab>
- <#-- do not display this component-->
- <#else>
- <#if appCount % 4 == 0>
- <#if firstApp>
- <li class="first">
- <#assign firstApp = false>
- <#else>
- </li>
- <li>
- </#if>
+ <#if thisApp == contextPath || contextPath + "/" == thisApp>
+ <#assign selected = true>
+ </#if>
+ <#assign servletPath =
Static["org.ofbiz.webapp.WebAppUtil"].getControlServletPath(display)>
+ <#assign thisURL = StringUtil.wrapString(servletPath)>
+ <#if thisApp != "/">
+ <#assign thisURL = thisURL + "main">
+ </#if>
+ <#if layoutSettings.suppressTab?exists && display.name ==
layoutSettings.suppressTab>
+ <#-- do not display this component-->
+ <#else>
+ <#if appCount % 4 == 0>
+ <#if firstApp>
+ <li class="first">
+ <#assign firstApp = false>
+ <#else>
+ </li>
+ <li>
</#if>
- <a href="${thisURL}${externalKeyParam}"<#if selected>
class="selected"</#if><#if uiLabelMap?exists>
title="${uiLabelMap[display.description]}">${uiLabelMap[display.title]}<#else>
title="${display.description}">${display.title}</#if></a>
- <#assign appCount = appCount + 1>
</#if>
+ <a href="${thisURL}${externalKeyParam}"<#if selected>
class="selected"</#if><#if uiLabelMap?exists>
title="${uiLabelMap[display.description]}">${uiLabelMap[display.title]}<#else>
title="${display.description}">${display.title}</#if></a>
+ <#assign appCount = appCount + 1>
</#if>
</#list>
<#list displaySecondaryApps as display>
- <#assign thisApp = display.getContextRoot()>
- <#assign permission = true>
- <#assign selected = false>
- <#assign permissions = display.getBasePermission()>
- <#list permissions as perm>
- <#if (perm != "NONE" && !security.hasEntityPermission(perm, "_VIEW",
session))>
- <#-- User must have ALL permissions in the base-permission list -->
- <#assign permission = false>
- </#if>
- </#list>
- <#if permission == true>
+ <#assign thisApp = display.getContextRoot()>
+ <#assign selected = false>
<#if thisApp == contextPath || contextPath + "/" == thisApp>
<#assign selected = true>
</#if>
@@ -97,12 +78,11 @@ under the License.
</#if>
<a href="${thisURL}${externalKeyParam}"<#if selected>
class="selected"</#if><#if uiLabelMap?exists>
title="${uiLabelMap[display.description]}">${uiLabelMap[display.title]}<#else>
title="${display.description}">${display.title}</#if></a>
<#assign appCount = appCount + 1>
+ </#list>
+ <#if appCount != 0>
+ </li>
+ <li class="last"></li>
</#if>
- </#list>
- <#if appCount != 0>
- </li>
- <li class="last"></li>
- </#if>
</ul>
</div>
</#if>