Author: sohil.shah(a)jboss.com
Date: 2006-12-11 23:59:21 -0500 (Mon, 11 Dec 2006)
New Revision: 5806
Added:
trunk/cms/src/main/org/jboss/portal/cms/impl/interceptors/ACLInterceptor.java
trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ACLEnforcer.java
trunk/cms/src/main/org/jboss/portal/cms/security/
trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProvider.java
trunk/cms/src/main/org/jboss/portal/cms/security/Criteria.java
trunk/cms/src/main/org/jboss/portal/cms/security/PermRoleAssoc.java
trunk/cms/src/main/org/jboss/portal/cms/security/PermUserAssoc.java
trunk/cms/src/main/org/jboss/portal/cms/security/Permission.java
trunk/cms/src/main/org/jboss/portal/cms/security/PermissionManager.java
trunk/cms/src/main/org/jboss/portal/cms/security/PortalSecurityContext.java
trunk/cms/src/main/org/jboss/portal/cms/security/SecurityContext.java
trunk/cms/src/main/org/jboss/portal/test/cms/commands/CMSInterceptorStackFactory.java
trunk/cms/src/main/org/jboss/portal/test/cms/commands/SecureCommandTestCase.java
trunk/cms/src/main/org/jboss/portal/test/cms/commands/TestSecureFileGet.java
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/back.gif
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/check.gif
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_cornerelement.gif
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_jbosslogo.gif
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_main.jpg
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/logo.gif
trunk/cms/src/resources/portal-cms-sar/default-content/default/private/
trunk/cms/src/resources/portal-cms-sar/default-content/default/private/license.html
trunk/cms/src/resources/portal-cms-sar/default-content/default/project.html
trunk/cms/src/resources/portal-cms-sar/default-content/default/support.html
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/code.html
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/confidential/
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/confidential/license.html
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/license.html
trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/ehcache.xml
Modified:
trunk/
trunk/cms/build.xml
trunk/cms/src/main/org/jboss/portal/cms/CMSException.java
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/JBossCachePersistenceManager.java
trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/JCRCMS.java
trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/composite/NewFileCommand.java
trunk/cms/src/resources/hibernate/domain.hbm.xml
trunk/cms/src/resources/portal-cms-sar/default-content/default/index.html
trunk/core/src/main/org/jboss/portal/core/aspects/controller/PageCustomizerInterceptor.java
trunk/core/src/main/org/jboss/portal/core/aspects/server/UserInterceptor.java
trunk/core/src/main/org/jboss/portal/core/cms/CMSObjectCommandFactory.java
trunk/core/src/main/org/jboss/portal/core/portlet/cms/CMSPortlet.java
trunk/core/src/main/org/jboss/portal/core/portlet/cms/admin/CMSAdminPortlet.java
trunk/core/src/resources/portal-cms-sar/META-INF/jboss-service.xml
trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/domain.hbm.xml
trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/hibernate.cfg.xml
trunk/core/src/resources/portal-core-sar/conf/data/default-object.xml
trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/main.jsp
trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/securenode.jsp
trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/viewfile.jsp
trunk/core/src/resources/portal-core-war/WEB-INF/portlet-instances.xml
Log:
Fine grained security integration into PortalCMS - [JBPORTAL-532],[JBPORTAL-328]
Property changes on: trunk
___________________________________________________________________
Name: svn:ignore
- .project
.classpath
thirdparty
eclipseBin
+ .project
.classpath
thirdparty
eclipseBin
myworkspace
Modified: trunk/cms/build.xml
===================================================================
--- trunk/cms/build.xml 2006-12-12 01:24:50 UTC (rev 5805)
+++ trunk/cms/build.xml 2006-12-12 04:59:21 UTC (rev 5806)
@@ -127,6 +127,8 @@
<path refid="jboss.portal-common.classpath"/>
<path refid="jboss.portal-jems.classpath"/>
<path refid="jboss.portal-test.classpath"/>
+ <!-- fine grained security integration -->
+ <path refid="jboss.portal-identity.classpath"/>
<!-- clustered testcases related -->
<path refid="jboss.portal-portlet.classpath"/>
<path refid="jboss.portlet-api.classpath"/>
@@ -380,19 +382,22 @@
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileCreate"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileUpdate"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileArchiveUpload"/>
- <test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileGet"/>
+ <test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileGet"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileGetVersion"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileGetList"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileCopy"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileCreateFailed"/>
- <test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileDelete"/>
+ <test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFileDelete"/>
<!-- cms folder command tests -->
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFolderCopy"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFolderCreate"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFolderDelete"/>
<test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFolderGet"/>
- <test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFolderUpdate"/>
+ <test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestFolderUpdate"/>
+
+ <!-- cms fine grained security related tests -->
+ <!--test todir="${test.reports}"
name="org.jboss.portal.test.cms.commands.TestSecureFileGet"/-->
</x-test>
<x-classpath>
<path refid="apache.logging.classpath"/>
Modified: trunk/cms/src/main/org/jboss/portal/cms/CMSException.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/CMSException.java 2006-12-12 01:24:50 UTC (rev
5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/CMSException.java 2006-12-12 04:59:21 UTC (rev
5806)
@@ -26,7 +26,7 @@
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision$
*/
-public class CMSException extends Exception
+public class CMSException extends RuntimeException
{
/** The serialVersionUID */
private static final long serialVersionUID = 3646107693814633408L;
Modified:
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/JBossCachePersistenceManager.java
===================================================================
---
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/JBossCachePersistenceManager.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/cms/src/main/org/jboss/portal/cms/hibernate/state/JBossCachePersistenceManager.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -470,7 +470,8 @@
{
session = Tools.getOpenSession();
tx = session.beginTransaction();
-
+
+
InputStream in = new ByteArrayInputStream(nodeData);
//setup the propertyState
@@ -1306,7 +1307,7 @@
Session session = Tools.getOpenSession();
try
{
- List rs = session.createQuery(query).setCacheable(true).setString(0,
id).list();
+ List rs = session.createQuery(query).setString(0, id).list();
Iterator iter = rs.iterator();
return iter.hasNext();
}
@@ -1361,7 +1362,7 @@
Session session = Tools.getCurrentSession();
try
{
- List rs = session.createQuery(blobSelectData).setCacheable(true).setString(0,
blobId).list();
+ List rs = session.createQuery(blobSelectData).setString(0, blobId).list();
Iterator iter = rs.iterator();
java.sql.Blob blob = (java.sql.Blob)iter.next();
InputStream is = blob.getBinaryStream();
@@ -1393,7 +1394,7 @@
try
{
- Query query = session.createQuery(blobSelect).setCacheable(true);
+ Query query = session.createQuery(blobSelect);
if
(schemaObjectPrefix.equalsIgnoreCase(HibernateStoreConstants.versionPrefix))
{
query.setString(0, blobId);
@@ -1459,7 +1460,7 @@
Session session = Tools.getCurrentSession();
try
{
- Query query =
session.createQuery(nodeBinValSelect).setCacheable(true).setString(0, blobId);
+ Query query = session.createQuery(nodeBinValSelect).setString(0, blobId);
Object result = query.uniqueResult();
if (result != null)
{
Added: trunk/cms/src/main/org/jboss/portal/cms/impl/interceptors/ACLInterceptor.java
===================================================================
---
trunk/cms/src/main/org/jboss/portal/cms/impl/interceptors/ACLInterceptor.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/cms/src/main/org/jboss/portal/cms/impl/interceptors/ACLInterceptor.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,453 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.cms.impl.interceptors;
+
+import org.w3c.dom.*;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.InitialContext;
+
+import org.jboss.portal.cms.CMSException;
+import org.jboss.portal.cms.CMSInterceptor;
+import org.jboss.portal.cms.impl.jcr.JCRCommand;
+import org.jboss.portal.cms.impl.jcr.JCRCMS;
+import org.jboss.portal.cms.model.File;
+import org.jboss.portal.cms.model.Folder;
+import org.jboss.portal.cms.hibernate.state.Tools;
+import org.jboss.portal.common.invocation.InvocationException;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.Query;
+
+import org.jboss.portal.cms.security.*;
+
+import org.jboss.portal.identity.User;
+import org.jboss.portal.identity.Role;
+import org.jboss.portal.identity.db.RoleImpl;
+import org.jboss.portal.identity.RoleModule;
+
+/**
+ * ACLInterceptor is plugged into the CMS system to enforce fine grained security access
control
+ * on resources stored in the CMS system.
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 27, 2006
+ *
+ */
+public class ACLInterceptor extends CMSInterceptor
+{
+ /**
+ *
+ */
+ private AuthorizationProvider authorizationProvider = null;
+
+ /**
+ * default security policy that the cms service should be booted with
+ */
+ private String defaultPolicy = null;
+
+ /**
+ *
+ */
+ private RoleModule roleModule = null;
+
+ /**
+ *
+ */
+ private String jndiName = null;
+
+ /**
+ *
+ * @return
+ */
+ public String getAuthorizationProviderClass()
+ {
+ String authorizationProviderStr = null;
+ if(this.authorizationProvider!=null)
+ {
+ authorizationProviderStr = authorizationProvider.getClass().getName();
+ }
+ return authorizationProviderStr;
+ }
+
+ /**
+ *
+ * @param authorizationProviderStr
+ */
+ public void setAuthorizationProviderClass(String authorizationProviderStr)
+ {
+ try
+ {
+ this.authorizationProvider = (AuthorizationProvider)Thread.currentThread().
+ getContextClassLoader().loadClass(authorizationProviderStr).newInstance();
+ }
+ catch(Exception e)
+ {
+ this.authorizationProvider = null;
+ this.stop();
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getDefaultPolicy()
+ {
+ return this.defaultPolicy;
+ }
+
+ /**
+ *
+ * @param defaultPolicy
+ */
+ public void setDefaultPolicy(String defaultPolicy)
+ {
+ this.defaultPolicy = defaultPolicy;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public RoleModule getRoleModule()
+ {
+ return this.roleModule;
+ }
+
+ /**
+ *
+ * @param roleModule
+ */
+ public void setRoleModule(RoleModule roleModule)
+ {
+ this.roleModule = roleModule;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getJNDIName()
+ {
+ return this.jndiName;
+ }
+
+ /**
+ *
+ * @param jndiName
+ */
+ public void setJNDIName(String jndiName)
+ {
+ this.jndiName = jndiName;
+ }
+
+ /**
+ *
+ */
+ protected Object invoke(JCRCommand invocation) throws Exception, InvocationException
+ {
+ Session session = Tools.getOpenSession();
+ Transaction tx = session.beginTransaction();
+
+ //make the acl check before this command is executed
+ User user = (User)JCRCMS.getUserInfo().get();
+
+
+ //setup the security context with enough information for the authorization
provider
+ //to be able to make an enforcement decision
+ PortalSecurityContext securityContext = new PortalSecurityContext(user);
+ securityContext.setAttribute("command",invocation);
+
+
+ //perform access check
+ boolean allowAccess = this.authorizationProvider.hasAccess(securityContext);
+ tx.commit();
+ Tools.closeSession(session);
+
+ if(allowAccess)
+ {
+ Object response = invocation.invokeNext();
+
+ //also filter lists of files and folders based on access allowed on these
resources
+ response = this.applyFilter(response,securityContext);
+
+ return response;
+ }
+ else
+ {
+ throw new CMSException("Access to this resource is denied");
+ }
+ }
+
+ /**
+ * Filters any files/folders based on the user's access. The filter is applied to
folders/files
+ * returned by invoking a CMS command
+ *
+ * @param response
+ * @return
+ */
+ private Object applyFilter(Object response,PortalSecurityContext securityContext)
+ {
+ Session session = Tools.getOpenSession();
+ Transaction tx = session.beginTransaction();
+ Object filteredResponse = response;
+
+ try
+ {
+
+
+ if(filteredResponse instanceof Folder)
+ {
+ Folder folder = (Folder)filteredResponse;
+ List filteredFolders = new ArrayList();
+ List filteredFiles = new ArrayList();
+ securityContext.removeAttribute("command");
+ for(Iterator itr=folder.getFolders().iterator();itr.hasNext();)
+ {
+ Folder cour = (Folder)itr.next();
+ securityContext.setAttribute("applyFilter",cour.getBasePath());
+ boolean allow = this.authorizationProvider.hasAccess(securityContext);
+ if(allow)
+ {
+ filteredFolders.add(cour);
+ }
+ }
+ for(Iterator itr=folder.getFiles().iterator();itr.hasNext();)
+ {
+ File cour = (File)itr.next();
+
securityContext.setAttribute("applyFilter",cour.getBasePath());
+ boolean allow = this.authorizationProvider.hasAccess(securityContext);
+ if(allow)
+ {
+ filteredFiles.add(cour);
+ }
+ }
+ folder.setFolders(filteredFolders);
+ folder.setFiles(filteredFiles);
+ }
+ }
+ catch(Exception e)
+ {
+ tx.rollback();
+ }
+ finally
+ {
+ tx.commit();
+ Tools.closeSession(session);
+ }
+
+ return filteredResponse;
+ }
+
+ /**
+ *
+ */
+ public void startService() throws Exception
+ {
+ super.startService();
+
+ Tools.init(this.jndiName);
+
+
+ //check and see if cms permissions exist...if not, boot it with the default
policy
+ //specified in the configuration
+ if(!this.isBootRequired())
+ {
+ return;
+ }
+
+ //go ahead and boot the cms access policy with default policy specified in the
configuration
+ InputStream is = null;
+ try
+ {
+ //process the specified defaultPolicy
+ is = new ByteArrayInputStream(this.defaultPolicy.getBytes());
+ Document document =
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
+
+ NodeList criteria = document.getElementsByTagName("criteria");
+ if(criteria!=null)
+ {
+ for(int i=0;i<criteria.getLength();i++)
+ {
+ Element criteriaElem = (Element)criteria.item(i);
+ String name = criteriaElem.getAttribute("name");
+ String value = criteriaElem.getAttribute("value");
+
+ //permission setup
+ NodeList permissions =
criteriaElem.getElementsByTagName("permission");
+ if(permissions!=null)
+ {
+ Session session = null;
+ Transaction tx = null;
+ Collection parsedPermissions =
this.parseDefaultPermissions(permissions);
+ try
+ {
+ session = Tools.getOpenSession();
+ tx = session.beginTransaction();
+ for(Iterator
itr=parsedPermissions.iterator();itr.hasNext();)
+ {
+ Permission permission = (Permission)itr.next();
+ permission.addCriteria(new Criteria(name,value));
+ PermissionManager.getInstance().store(permission);
+ }
+ tx.commit();
+ }
+ catch(Exception e)
+ {
+ tx.rollback();
+ }
+ finally
+ {
+ Tools.closeSession(session);
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ if(is!=null)
+ {
+ is.close();
+ }
+ }
+ }
+
+ /**
+ * Parses and produces Permission objects for the default policy
+ *
+ * @param permissions
+ * @return
+ */
+ private Collection parseDefaultPermissions(NodeList permissions) throws Exception
+ {
+ Collection parsedPermissions = new ArrayList();
+ for(int i=0;i<permissions.getLength();i++)
+ {
+ Element permissionElement = (Element)permissions.item(i);
+ String name = permissionElement.getAttribute("name");
+ String action = permissionElement.getAttribute("action");
+ Permission permission = new Permission(name,action);
+
+ //parse the roles listed under this permission element
+ NodeList roles = permissionElement.getElementsByTagName("role");
+ for(int j=0;j<roles.getLength();j++)
+ {
+ Element roleElement = (Element)roles.item(j);
+ String roleName = roleElement.getAttribute("name");
+ Role role = this.getRole(roleName);
+ PermRoleAssoc roleAssoc = new PermRoleAssoc();
+ if(role.getId()!=null)
+ {
+ //makes sure this is not Anonymous
+ roleAssoc.setRoleId(((Long)role.getId()).longValue());
+ }
+ permission.addRoleAssoc(roleAssoc);
+ }
+
+ parsedPermissions.add(permission);
+ }
+ return parsedPermissions;
+ }
+
+ /**
+ * Returns the Role object specified in the default policy
+ *
+ * @param name
+ * @return
+ */
+ private Role getRole(String name) throws Exception
+ {
+ Role role = null;
+
+ //since this is at app start up and not on user thread...need to create a
transaction context.
+ InitialContext context = new InitialContext();
+ SessionFactory sessionFactory =
(SessionFactory)context.lookup("java:/portal/UserSessionFactory");
+ Session session = sessionFactory.openSession();
+ Transaction tx = session.beginTransaction();
+ try
+ {
+ role = this.roleModule.findRoleByName(name);
+ }
+ catch(Exception e)
+ {
+ role = new RoleImpl();
+ }
+ finally
+ {
+ if(tx!=null)
+ {
+ tx.rollback();
+ }
+ if(session!=null)
+ {
+ session.close();
+ }
+ }
+
+ return role;
+ }
+
+ /**
+ * Returns if cms permissions need to be booted with the default policy from
configuration
+ *
+ * @return
+ */
+ private boolean isBootRequired()
+ {
+ boolean bootRequired = false;
+
+ String hsqlQuery = "select count(permission) from
org.jboss.portal.cms.security.Permission as permission";
+ Session session = Tools.getOpenSession();
+ Transaction tx = session.beginTransaction();
+ try
+ {
+ Query query = session.createQuery(hsqlQuery);
+ long count = ((Long)query.list().get(0)).longValue();
+ if(count<=0)
+ {
+ bootRequired = true;
+ }
+ }
+ finally
+ {
+ if(tx!=null)
+ {
+ tx.rollback();
+ }
+ Tools.closeSession(session);
+ }
+
+ return bootRequired;
+ }
+}
Modified: trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/JCRCMS.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/JCRCMS.java 2006-12-12 01:24:50 UTC
(rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/JCRCMS.java 2006-12-12 04:59:21 UTC
(rev 5806)
@@ -46,6 +46,8 @@
import org.jboss.portal.common.net.URLVisitor;
import org.jboss.portal.common.util.Tools;
import org.jboss.portal.common.util.XML;
+import org.jboss.portal.identity.User;
+import org.jboss.portal.identity.UserModule;
import org.jboss.portal.jems.as.system.AbstractJBossService;
import org.jboss.util.StopWatch;
import org.w3c.dom.DOMImplementation;
@@ -65,6 +67,7 @@
import java.util.LinkedList;
import java.util.Locale;
+
/**
* @author <a href="mailto:roy@jboss.org">Roy Russo</a>
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
@@ -89,6 +92,8 @@
private InterceptorStackFactory stackFactory;
private Element config;
+
+ private UserModule userModule = null;
private InvocationHandler handler = new InvocationHandler()
@@ -99,6 +104,15 @@
return cmd.execute();
}
};
+
+ /**
+ * Used for storing the logged in user information
+ */
+ protected static ThreadLocal userInfo = new ThreadLocal();
+ public static ThreadLocal getUserInfo()
+ {
+ return JCRCMS.userInfo;
+ }
public JCRCMS()
{
@@ -169,6 +183,24 @@
{
this.doChecking = doChecking;
}
+
+ /**
+ *
+ * @return
+ */
+ public UserModule getUserModule()
+ {
+ return this.userModule;
+ }
+
+ /**
+ *
+ * @param userModule
+ */
+ public void setUserModule(UserModule userModule)
+ {
+ this.userModule = userModule;
+ }
/** CMS Start */
public void startService() throws Exception
@@ -262,12 +294,22 @@
// /**
/** Loads content from sar and adds it to the repo. */
- public void createContent() throws IOException
+ public void createContent() throws Exception
{
log.info("Creating default CMS content.");
+
// Get the content
URL root =
Thread.currentThread().getContextClassLoader().getResource(defaultContentLocation);
+
+ //make the user executing these to create the default content, an 'Admin'
user
+ //without this, the fine grained security won't allow the creation
+ org.hibernate.Session session =
org.jboss.portal.cms.hibernate.state.Tools.getOpenSession();
+ org.hibernate.Transaction tx = session.beginTransaction();
+ User user = this.userModule.findUserByUserName("admin");
+ this.getUserInfo().set(user);
+ tx.rollback();
+ org.jboss.portal.cms.hibernate.state.Tools.closeSession(session);
// Iterate over the content
URLVisitor visitor = new URLVisitor()
Added: trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ACLEnforcer.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ACLEnforcer.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ACLEnforcer.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,621 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.impl.jcr.command;
+
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.StringTokenizer;
+
+import org.jboss.portal.cms.impl.jcr.command.*;
+import org.jboss.portal.cms.impl.jcr.composite.*;
+import org.jboss.portal.cms.impl.jcr.*;
+import org.jboss.portal.cms.security.AuthorizationProvider;
+import org.jboss.portal.cms.security.PortalSecurityContext;
+import org.jboss.portal.cms.security.SecurityContext;
+import org.jboss.portal.cms.security.Permission;
+import org.jboss.portal.cms.security.PermissionManager;
+import org.jboss.portal.cms.security.Criteria;
+import org.jboss.portal.identity.User;
+
+/**
+ * ACLEnforcer checks proper access privileges for actions before
+ * the Command objects are allowed to execute and do their job on the CMS
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 28, 2006
+ *
+ */
+public class ACLEnforcer implements AuthorizationProvider
+{
+ private Collection readCommands = new ArrayList(); //a list of commands that perform
read action on the cms
+ private Collection writeCommands = new ArrayList();//a list of commands that perform
write action on the cms
+ private Collection manageCommands = new ArrayList();//a list of commands that perform
manage action on the cms
+
+ private static final int read = 0;
+ private static final int write = 1;
+ private static final int manage = 2;
+
+
+ /**
+ *
+ *
+ */
+ public ACLEnforcer()
+ {
+ super();
+
+ String packageName = "org.jboss.portal.cms.impl.jcr.command.";
+
+ //load the read related commands
+ readCommands.add(packageName+"FolderGetListCommand");
+ readCommands.add(packageName+"FolderGetCommand");
+ readCommands.add(packageName+"FileGetListCommand");
+ readCommands.add(packageName+"FileGetCommand");
+
+ //load the write related commands
+ writeCommands.add(packageName+"ContentCreateCommand");
+ writeCommands.add(packageName+"FileCreateCommand");
+ writeCommands.add(packageName+"FolderCreateCommand");
+ writeCommands.add(packageName+"FileUpdateCommand");
+ writeCommands.add(packageName+"StoreArchiveCommand");
+ writeCommands.add(packageName+"ContentCreateNewVersionCommand");
+
writeCommands.add("org.jboss.portal.cms.impl.jcr.composite.NewFileCommand");
+
writeCommands.add("org.jboss.portal.cms.impl.jcr.composite.UpdateFileCommand");
+
+
+ //load the manage related commands
+ manageCommands.add(packageName+"CopyCommand");
+ manageCommands.add(packageName+"DeleteCommand");
+ manageCommands.add(packageName+"MoveCommand");
+ manageCommands.add(packageName+"RenameCommand");
+ }
+
+
+ /**
+ *
+ * @param securityContext
+ * @return
+ */
+ public boolean hasAccess(SecurityContext context)
+ {
+ boolean hasAccess = true;
+ PortalSecurityContext portalSecurityContext = (PortalSecurityContext)context;
+ User loggedInUser = (User)portalSecurityContext.getIdentity();
+ JCRCommand command =
(JCRCommand)portalSecurityContext.getAttribute("command");
+
+ int actionCode = -1;
+ if(command != null)
+ {
+ actionCode = this.getActionCode(command);
+ }
+ switch(actionCode)
+ {
+ case read:
+ hasAccess = this.hasReadAccess(loggedInUser,command);
+ break;
+
+ case write:
+ hasAccess = this.hasWriteAccess(loggedInUser,command);
+ break;
+
+ case manage:
+ hasAccess = this.hasManageAccess(loggedInUser,command);
+ break;
+
+ default:
+ //check if a filter needs to be applied here......
+ //only show resources that the user has write or more access to
+ if(context.getAttribute("applyFilter")!=null)
+ {
+ String path = (String)context.getAttribute("applyFilter");
+ hasAccess = this.computeToolAccess(loggedInUser,path);
+ }
+ break;
+ }
+
+ return hasAccess;
+ }
+
+ /**
+ *
+ * @param command
+ * @return
+ */
+ private int getActionCode(JCRCommand command)
+ {
+ int actionCode = -1;
+
+ if(this.readCommands.contains(command.getClass().getName()))
+ {
+ actionCode = read;
+ }
+ else if(this.writeCommands.contains(command.getClass().getName()))
+ {
+ actionCode = write;
+ }
+ else if(this.manageCommands.contains(command.getClass().getName()))
+ {
+ actionCode = manage;
+ }
+ return actionCode;
+ }
+
//---------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ * @param user
+ * @param command
+ * @return
+ */
+ private boolean hasReadAccess(User user,JCRCommand command)
+ {
+ boolean hasReadAccess = false;
+
+ String path = null;
+ if(command instanceof FolderGetListCommand)
+ {
+ path = ((FolderGetListCommand)command).sFolderPath;
+ }
+ else if(command instanceof FolderGetCommand)
+ {
+ path = ((FolderGetCommand)command).msPath;
+ }
+ else if(command instanceof FileGetCommand)
+ {
+ path = ((FileGetCommand)command).path;
+ }
+ else if(command instanceof FileGetListCommand)
+ {
+ path = ((FileGetListCommand)command).sFilePath;
+ }
+
+ hasReadAccess = this.computeAccess(user,path,"read");
+ if(!hasReadAccess)
+ {
+ //make sure implied write is not available
+ hasReadAccess = this.computeAccess(user,path,"write");
+ if(!hasReadAccess)
+ {
+ //make sure implied manage is not available
+ hasReadAccess = this.computeAccess(user,path,"manage");
+ }
+ }
+
+ return hasReadAccess;
+ }
+
//-------------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ * @param user
+ * @param command
+ * @return
+ */
+ private boolean hasWriteAccess(User user,JCRCommand command)
+ {
+ boolean hasWriteAccess = false;
+
+ String path = null;
+ if(command instanceof ContentCreateCommand)
+ {
+ path = ((ContentCreateCommand)command).mFile.getBasePath();
+ }
+ else if(command instanceof FileCreateCommand)
+ {
+ path = ((FileCreateCommand)command).mFile.getBasePath();
+ }
+ else if(command instanceof FolderCreateCommand)
+ {
+ path = ((FolderCreateCommand)command).mFolder.getBasePath();
+ }
+ else if(command instanceof FileUpdateCommand)
+ {
+ path = ((FileUpdateCommand)command).mFile.getBasePath();
+ }
+ else if(command instanceof StoreArchiveCommand)
+ {
+ path = ((StoreArchiveCommand)command).msRootPath;
+ }
+ else if(command instanceof NewFileCommand)
+ {
+ path = ((NewFileCommand)command).getPath();
+ }
+ else if(command instanceof UpdateFileCommand)
+ {
+ path = ((UpdateFileCommand)command).getPath();
+ }
+
+ hasWriteAccess = this.computeAccess(user,path,"write");
+ if(!hasWriteAccess)
+ {
+ //make sure implied manage is not available
+ hasWriteAccess = this.computeAccess(user,path,"manage");
+ }
+
+ return hasWriteAccess;
+ }
+
//-----------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ * @param user
+ * @param command
+ * @return
+ */
+ private boolean hasManageAccess(User user,JCRCommand command)
+ {
+ boolean hasManageAccess = false;
+
+ String path = null;
+ if(command instanceof CopyCommand)
+ {
+ path = ((CopyCommand)command).msFromPath;
+ }
+ else if(command instanceof DeleteCommand)
+ {
+ path = ((DeleteCommand)command).msPath;
+ }
+ else if(command instanceof MoveCommand)
+ {
+ path = ((MoveCommand)command).msFromPath;
+ }
+ else if(command instanceof RenameCommand)
+ {
+ path = ((RenameCommand)command).msPath;
+ }
+
+ hasManageAccess = this.computeAccess(user,path,"manage");
+
+ return hasManageAccess;
+ }
+
//-----------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ */
+ private boolean computeAccess(User user,String path,String action)
+ {
+ boolean hasAccess = false;
+
+ //to prevent any administration issues, if the user is the 'admin'
+ //treat him like a super user with access to everything in the cms
+ if(user!= null && user.getUserName()!=null &&
user.getUserName().equals("admin"))
+ {
+ return true;
+ }
+
+
+ //get the permissions available for the user in question
+ Collection userPermissions = this.getPermissions(user);
+
+ //check against permissions that are explicitly specified on this node (file or
folder)
+ Collection specificPermissions = this.getPermissions(path);
+ for(Iterator itr=specificPermissions.iterator();itr.hasNext();)
+ {
+ Permission specificPermission = (Permission)itr.next();
+ if(specificPermission.getService().equals("cms") &&
specificPermission.getAction().equals(action))
+ {
+ for(Iterator itr2=userPermissions.iterator();itr2.hasNext();)
+ {
+ Permission userPermission = (Permission)itr2.next();
+ if(userPermission.getService().equals("cms") &&
userPermission.getAction().equals(action))
+ {
+ String pathCriteria =
userPermission.findCriteriaValue("path");
+ if(pathCriteria.equals(path))
+ {
+ //this means this user has read access to this path
+ hasAccess = true;
+ }
+ }
+ }
+ }
+ }
+
+ if(specificPermissions!=null && !specificPermissions.isEmpty())
+ {
+ //explicit permissions on this node have been specified....
+ //which override any permissions that could be inherited via the path
hierarchy
+ return hasAccess;
+ }
+
+
+ //check against the full path of this resource and make sure,
+ //there aren't any specific node permissions specified on any node along the
path
+ //that excludes this user from having access for this action
+ StringTokenizer st = new StringTokenizer(path,"/");
+ StringBuffer buffer = new StringBuffer("/");
+ boolean explicitPermissionsFound = false;
+ while(st.hasMoreTokens())
+ {
+ buffer.append(st.nextToken());
+ String currentNode = buffer.toString();
+ Collection permissions = this.getPermissions(currentNode);
+
+ //this is for forming the path using the next token
+ if(st.hasMoreTokens())
+ {
+ buffer.append("/");
+ }
+ else
+ {
+ continue;
+ }
+
+
+ //perform processing for permissions explicitly set on this node
+ //in the path hierarchy
+ if(permissions!=null && !permissions.isEmpty())
+ {
+ explicitPermissionsFound = true;
+
+ //specific node permissions found on one of the nodes in the path...
+ //make sure the current user is listed to have access to this.
+ boolean accessFound = false;
+ for(Iterator itr=permissions.iterator();itr.hasNext();)
+ {
+ Permission nodePermission = (Permission)itr.next();
+ if(nodePermission.getService().equals("cms") &&
nodePermission.getAction().equals(action))
+ {
+ for(Iterator itr2=userPermissions.iterator();itr2.hasNext();)
+ {
+ Permission userPermission = (Permission)itr2.next();
+ if(userPermission.getService().equals("cms")
&& userPermission.getAction().equals(action))
+ {
+ String pathCriteria =
userPermission.findCriteriaValue("path");
+ if(pathCriteria.equals(currentNode))
+ {
+ //this means this user has read access to this path
+ accessFound = true;
+ }
+ }
+ }
+ }
+ if(accessFound)
+ {
+ break;
+ }
+ }
+ if(!accessFound)
+ {
+ //the user does not have access through the path hierarchy
+ return false;
+ }
+ }
+ }
+
+ //if i am here the user has access to this node via path hierarchy inheritance
+ if(explicitPermissionsFound)
+ {
+ //and without the hierarchy access *not being overriden* by any *explicit
permissions*
+ //on nodes in the hierarchy
+ hasAccess = true;
+ }
+ else
+ {
+ //there were no permissions found anywhere throughout the resource's path
hierarchy
+ hasAccess = false;
+ }
+
+ return hasAccess;
+ }
+
+ /**
+ * This is used to filter out cms resources in the CMS Admin tool, so that the user
+ * can see only the resources that he has write/manage access to
+ *
+ * @param user
+ * @param path
+ * @return
+ */
+ private boolean computeToolAccess(User user,String path)
+ {
+ boolean toolAccess = false;
+
+ //to prevent any administration issues, if the user is the 'admin'
+ //treat him like a super user with access to everything in the cms
+ if(user!= null && user.getUserName()!=null &&
user.getUserName().equals("admin"))
+ {
+ return true;
+ }
+
+ //get the permissions available for the user in question
+ Collection userPermissions = this.getPermissions(user);
+
+ //check against permissions that are explicitly specified on this node (file or
folder)
+ Collection specificPermissions = this.getPermissions(path);
+ for(Iterator itr=specificPermissions.iterator();itr.hasNext();)
+ {
+ Permission specificPermission = (Permission)itr.next();
+ if( (specificPermission.getService().equals("cms")) &&
+ (specificPermission.getAction().equals("write") ||
specificPermission.getAction().equals("manage"))
+ )
+ {
+ for(Iterator itr2=userPermissions.iterator();itr2.hasNext();)
+ {
+ Permission userPermission = (Permission)itr2.next();
+ if( (userPermission.getService().equals("cms")) &&
+ (userPermission.getAction().equals("write") ||
userPermission.getAction().equals("manage"))
+ )
+ {
+ String pathCriteria =
userPermission.findCriteriaValue("path");
+ if(pathCriteria.equals(path))
+ {
+ //this means this user has read access to this path
+ toolAccess = true;
+ }
+ }
+ }
+ }
+ }
+
+ if(specificPermissions!=null && !specificPermissions.isEmpty())
+ {
+ //explicit permissions on this node have been specified....
+ //which override any permissions that could be inherited via the path
hierarchy
+ return toolAccess;
+ }
+
+ //if i am here...calculate based on permissions inherited via path hierarchy
+ Collection writeOrMoreCriteria = this.getWriteOrMore(userPermissions);
+ for(Iterator itr=writeOrMoreCriteria.iterator();itr.hasNext();)
+ {
+ Criteria cour = (Criteria)itr.next();
+ if(this.doesPathMatchPattern(path,cour.getValue()))
+ {
+
+ toolAccess = true;
+ break;
+ }
+ }
+
+ return toolAccess;
+ }
+
//----------------------------------------------------------------------------------------------------------------------------------------------
+ /**
+ *
+ * @param user
+ * @return
+ */
+ private Collection getPermissions(User user)
+ {
+ Collection permissions = null;
+ long userId = 0;
+ if(user!=null)
+ {
+ //this is not an anonymous access
+ userId = ((Long)user.getId()).longValue();
+ permissions = PermissionManager.getInstance().findPermissionsByUser(userId);
+ }
+ else
+ {
+ //this is an anonymous access
+ permissions = PermissionManager.getInstance().findPermissionsByRole(0);
+ }
+ return permissions;
+ }
+
+ /**
+ *
+ * @param user
+ * @return
+ */
+ private Collection getPermissions(String path)
+ {
+ Criteria criteria = new Criteria("path",path);
+ return PermissionManager.getInstance().findPermissionsByCriteria(criteria);
+ }
+
+ /**
+ *
+ * @param allPermissions
+ * @return
+ */
+ private Collection getWriteOrMore(Collection allPermissions)
+ {
+ Collection writeOrMore = new HashSet();
+
+ if(allPermissions!=null)
+ {
+ for(Iterator itr=allPermissions.iterator();itr.hasNext();)
+ {
+ Permission cour = (Permission)itr.next();
+ if( (cour.getService().equals("cms")) &&
+ ( cour.getAction().equals("write") ||
cour.getAction().equals("manage") )
+ )
+ {
+ writeOrMore.addAll(cour.getCriteria());
+ }
+ }
+ }
+
+ return writeOrMore;
+ }
+
+ /**
+ * @param path
+ * @param pattern
+ * @return
+ */
+ private boolean doesPathMatchPattern(String path,String pattern)
+ {
+ boolean match = true;
+
+ //format the path first before starting to match it with the specified pattern
+ if(!path.startsWith("/"))
+ {
+ path = "/" + path;
+ }
+ if(!path.endsWith("/"))
+ {
+ path = path + "/";
+ }
+
+ StringTokenizer patternTokenizer = new StringTokenizer(pattern,"/");
+ StringTokenizer pathTokenizer = new StringTokenizer(path,"/");
+ StringBuffer pathMatched = new StringBuffer("/");
+ StringBuffer patternMatched = new StringBuffer();
+ if(pattern.startsWith("/"))
+ {
+ patternMatched.append("/");
+ }
+ while(
+ patternTokenizer.hasMoreTokens() &&
+ pathTokenizer.hasMoreTokens()
+ )
+ {
+ String patternToken = patternTokenizer.nextToken();
+ String pathToken = pathTokenizer.nextToken();
+
+ //setup token tracking
+ pathMatched.append(pathToken+"/");
+ if(patternTokenizer.hasMoreTokens())
+ {
+ patternMatched.append(patternToken+"/");
+ }
+ else
+ {
+ patternMatched.append(patternToken);
+ }
+
+ //perform token matching
+ if(!match){continue;}
+ int wildCardIndex = patternToken.indexOf('*');
+ //if wildCard is not relevant
+ if(wildCardIndex<=0)
+ {
+ //if wildCardIndex == 0 then this token matches...
+ if(wildCardIndex!=0 && !pathToken.equals(patternToken))
+ {
+ match = false;
+ }
+ }
+ else
+ {
+ String wildPath = pathToken.substring(0,wildCardIndex);
+ String wildPattern = patternToken.substring(0,wildCardIndex);
+ if(!wildPath.equals(wildPattern))
+ {
+ match = false;
+ }
+ }
+ }
+
+ return match;
+ }
+}
Modified: trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/composite/NewFileCommand.java
===================================================================
---
trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/composite/NewFileCommand.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/composite/NewFileCommand.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -30,17 +30,33 @@
import org.jboss.portal.cms.model.Content;
import org.jboss.portal.cms.model.File;
-/** @author <a href="mailto:theute@jboss.org">Thomas Heute</a> */
+/** @author <a href="mailto:theute@jboss.org">Thomas Heute</a>
+ * @author <a href="mailto:sohil.shah@jboss.com">Sohil Shah</a> -
Nov 28, 2006
+ **/
public class NewFileCommand extends JCRCompositeCommand
{
/** The serialVersionUID */
private static final long serialVersionUID = -6134173065175936408L;
+
+ //
+ private String path = null;
+
+ /**
+ *
+ * @return
+ */
+ public String getPath()
+ {
+ return this.path;
+ }
public NewFileCommand(File file, Content content)
{
// setAttribute("file", file);
// setAttribute("content", content);
+ this.path = file.getBasePath();
+
Command saveFileCMD = new FileCreateCommand(file);
commands.add(saveFileCMD);
Command saveContentCMD = new ContentCreateCommand(file);
Added: trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProvider.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProvider.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProvider.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,39 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.security;
+
+/**
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 27, 2006
+ *
+ */
+public interface AuthorizationProvider
+{
+ /**
+ * Checks if the currently logged in user has the necessary privileges to access the
resources
+ * encapsulated within the securityContext
+ *
+ * @param context security context containing the information used to enforce access
control
+ * @return true - access should be granted, false - access should not be granted
+ */
+ public boolean hasAccess(SecurityContext context);
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/security/Criteria.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/Criteria.java 2006-12-12 01:24:50 UTC
(rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/Criteria.java 2006-12-12 04:59:21 UTC
(rev 5806)
@@ -0,0 +1,127 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.security;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 29, 2006
+ *
+ */
+public class Criteria implements Serializable
+{
+ /**
+ *
+ */
+ private long id = 0;
+ private String name = null;
+ private String value = null;
+
+ /**
+ *
+ *
+ */
+ public Criteria()
+ {
+
+ }
+
+ /**
+ *
+ *
+ */
+ public Criteria(String name,String value)
+ {
+ this();
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public long getId()
+ {
+ return this.id;
+ }
+
+ /**
+ *
+ * @param key
+ */
+ public void setId(long id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * @return Returns the context.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * @param context The context to set.
+ */
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+
+ /**
+ * @return Returns the value.
+ */
+ public String getValue()
+ {
+ return value;
+ }
+
+ /**
+ * @param value The value to set.
+ */
+ public void setValue(String value)
+ {
+ this.value = value;
+ }
+
+ /**
+ *
+ */
+ public boolean equals(Object obj)
+ {
+ boolean equals = false;
+ if(obj instanceof Criteria)
+ {
+ Criteria input = (Criteria)obj;
+ if(input.name.equals(this.name) && input.value.equals(this.value))
+ {
+ equals = true;
+ }
+ }
+ return equals;
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/security/PermRoleAssoc.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/PermRoleAssoc.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/PermRoleAssoc.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,95 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.security;
+
+/**
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Dec 7, 2006
+ *
+ */
+public class PermRoleAssoc
+{
+ private long id = 0;
+ private long roleId = 0;
+
+ /**
+ *
+ *
+ */
+ public PermRoleAssoc()
+ {
+ super();
+ }
+
+ /**
+ *
+ * @return
+ */
+ public long getId()
+ {
+ return id;
+ }
+
+ /**
+ *
+ * @param id
+ */
+ public void setId(long id)
+ {
+ this.id = id;
+ }
+
+
+ /**
+ *
+ * @return
+ */
+ public long getRoleId()
+ {
+ return roleId;
+ }
+
+ /**
+ *
+ * @param roleId
+ */
+ public void setRoleId(long roleId)
+ {
+ this.roleId = roleId;
+ }
+
+ public boolean equals(Object obj)
+ {
+ boolean equals = false;
+
+ if(obj instanceof PermRoleAssoc)
+ {
+ PermRoleAssoc input = (PermRoleAssoc)obj;
+ if(input.roleId == this.roleId)
+ {
+ equals = true;
+ }
+ }
+
+ return equals;
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/security/PermUserAssoc.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/PermUserAssoc.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/PermUserAssoc.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,95 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.security;
+
+/**
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Dec 7, 2006
+ *
+ */
+public class PermUserAssoc
+{
+ private long id = 0;
+ private long userId = 0;
+
+ /**
+ *
+ *
+ */
+ public PermUserAssoc()
+ {
+ super();
+ }
+
+ /**
+ *
+ * @return
+ */
+ public long getId()
+ {
+ return id;
+ }
+
+ /**
+ *
+ * @param id
+ */
+ public void setId(long id)
+ {
+ this.id = id;
+ }
+
+
+ /**
+ *
+ * @return
+ */
+ public long getUserId()
+ {
+ return userId;
+ }
+
+ /**
+ *
+ * @param roleId
+ */
+ public void setUserId(long userId)
+ {
+ this.userId = userId;
+ }
+
+ public boolean equals(Object obj)
+ {
+ boolean equals = false;
+
+ if(obj instanceof PermUserAssoc)
+ {
+ PermUserAssoc input = (PermUserAssoc)obj;
+ if(input.userId == this.userId)
+ {
+ equals = true;
+ }
+ }
+
+ return equals;
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/security/Permission.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/Permission.java 2006-12-12 01:24:50
UTC (rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/Permission.java 2006-12-12 04:59:21
UTC (rev 5806)
@@ -0,0 +1,376 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.security;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.security.BasicPermission;
+
+/**
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 28, 2006
+ *
+ */
+public class Permission extends BasicPermission
+{
+ /**
+ *
+ */
+ private long id = 0; //unique id for this permission object in the storage (typically
database)
+ private String service = null;
+ private String action = null;
+ private boolean isNegated = false;
+
+ /**
+ *
+ */
+ private Set criteria = null;
+ private Set roleAssoc = null;
+ private Set userAssoc = null;
+
+ /**
+ *
+ *
+ */
+ public Permission()
+ {
+ this("null");
+ }
+
+
+ /**
+ *
+ * @param name
+ */
+ public Permission(String service)
+ {
+ super(service);
+ this.service = service;
+ }
+
+ /**
+ *
+ * @param name
+ * @param actions
+ */
+ public Permission(String service,String actions)
+ {
+ super(service,actions);
+ this.service = service;
+ this.action = actions;
+ }
+
+
+ /**
+ *
+ * @return
+ */
+ public long getId()
+ {
+ return this.id;
+ }
+
+ /**
+ *
+ * @param id
+ */
+ public void setId(long id)
+ {
+ this.id = id;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public Set getCriteria()
+ {
+ return this.criteria;
+ }
+
+ /**
+ *
+ * @param criteria
+ */
+ public void setCriteria(Set criteria)
+ {
+ this.criteria = criteria;
+ }
+
+ /**
+ *
+ * @param criteria
+ */
+ public void addCriteria(Criteria criteria)
+ {
+ if(this.criteria == null)
+ {
+ this.criteria = new HashSet();
+ }
+ this.criteria.add(criteria);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getService()
+ {
+ return this.service;
+ }
+
+
+ /**
+ *
+ * @param name
+ */
+ public void setService(String service)
+ {
+ this.service = service;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getAction()
+ {
+ return this.action;
+ }
+
+ /**
+ *
+ * @param action
+ */
+ public void setAction(String action)
+ {
+ this.action = action;
+ }
+
+
+ /**
+ * Finds the specified criteria value for the criteriaId
+ *
+ * @param criteriaId
+ * @return value of the criteria
+ */
+ public String findCriteriaValue(String criteriaId)
+ {
+ String value = null;
+ if(this.criteria!=null)
+ {
+ for(Iterator itr=this.criteria.iterator();itr.hasNext();)
+ {
+ Criteria cour = (Criteria)itr.next();
+ if(criteriaId.equals(cour.getName()))
+ {
+ value = cour.getValue();
+ }
+ }
+ }
+ return value;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public boolean isNegated()
+ {
+ return isNegated;
+ }
+
+ /**
+ *
+ * @param isNegated
+ */
+ public void setNegated(boolean isNegated)
+ {
+ this.isNegated = isNegated;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public Set getRoleAssoc()
+ {
+ return roleAssoc;
+ }
+
+ /**
+ *
+ * @param roleAssoc
+ */
+ public void setRoleAssoc(Set roleAssoc)
+ {
+ this.roleAssoc = roleAssoc;
+ }
+
+ /**
+ *
+ * @param roleAssoc
+ */
+ public void addRoleAssoc(PermRoleAssoc roleAssoc)
+ {
+ if(this.roleAssoc == null)
+ {
+ this.roleAssoc = new HashSet();
+ }
+ this.roleAssoc.add(roleAssoc);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public Set getRoleAssocIds()
+ {
+ Set ids = new HashSet();
+ if(this.roleAssoc!=null)
+ {
+ for(Iterator itr=this.roleAssoc.iterator();itr.hasNext();)
+ {
+ PermRoleAssoc cour = (PermRoleAssoc)itr.next();
+ ids.add(new Long(cour.getRoleId()));
+ }
+ }
+ return ids;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public Set getUserAssoc()
+ {
+ return userAssoc;
+ }
+
+ /**
+ *
+ * @param userAssoc
+ */
+ public void setUserAssoc(Set userAssoc)
+ {
+ this.userAssoc = userAssoc;
+ }
+
+ /**
+ *
+ * @param userAssoc
+ */
+ public void addUserAssoc(PermUserAssoc userAssoc)
+ {
+ if(this.userAssoc == null)
+ {
+ this.userAssoc = new HashSet();
+ }
+ this.userAssoc.add(userAssoc);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public Set getUserAssocIds()
+ {
+ Set ids = new HashSet();
+ if(this.userAssoc!=null)
+ {
+ for(Iterator itr=this.userAssoc.iterator();itr.hasNext();)
+ {
+ PermUserAssoc cour = (PermUserAssoc)itr.next();
+ ids.add(new Long(cour.getUserId()));
+ }
+ }
+ return ids;
+ }
+
+
+ /**
+ *
+ */
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("-----------------------------\n");
+ buffer.append("ID="+this.id+"\n");
+ buffer.append("Service="+this.service+"\n");
+ buffer.append("Action="+this.action+"\n");
+ buffer.append("Negated="+this.isNegated+"\n");
+
+ //print role association
+ if(this.roleAssoc!=null)
+ {
+ for(Iterator itr=this.roleAssoc.iterator();itr.hasNext();)
+ {
+ PermRoleAssoc cour = (PermRoleAssoc)itr.next();
+ buffer.append("Role ="+cour.getRoleId()+"\n");
+ }
+ }
+
+ //print user association
+ if(this.userAssoc!=null)
+ {
+ for(Iterator itr=this.userAssoc.iterator();itr.hasNext();)
+ {
+ PermUserAssoc cour = (PermUserAssoc)itr.next();
+ buffer.append("User ="+cour.getUserId()+"\n");
+ }
+ }
+
+ //print criteria
+ if(this.criteria!=null)
+ {
+ for(Iterator itr=this.criteria.iterator();itr.hasNext();)
+ {
+ Criteria cour = (Criteria)itr.next();
+ buffer.append("Criteria
="+cour.getName()+","+cour.getValue()+"\n");
+ }
+ }
+
+ buffer.append("-----------------------------\n");
+
+ return buffer.toString();
+ }
+
+
+ /**
+ *
+ */
+ public boolean equals(Object obj)
+ {
+ boolean equals = false;
+ if(obj instanceof Permission)
+ {
+ Permission input = (Permission)obj;
+ if(input.id == this.id)
+ {
+ equals = true;
+ }
+ }
+ return equals;
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/security/PermissionManager.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/PermissionManager.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/PermissionManager.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,240 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.security;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+
+import org.hibernate.Query;
+import org.hibernate.Session;
+
+
+import org.jboss.portal.cms.hibernate.state.Tools;
+import org.jboss.portal.identity.User;
+import org.jboss.portal.identity.Role;
+
+/**
+ * PermissionManager is used to manage (create,read,update,delete) permissions stored in
the database
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Dec 1, 2006
+ *
+ */
+public class PermissionManager
+{
+ /**
+ * the singleton instance. This is a stateless component
+ */
+ private static PermissionManager singleton = null;
+
+ /**
+ *
+ *
+ */
+ private PermissionManager()
+ {
+ super();
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static PermissionManager getInstance()
+ {
+ if(PermissionManager.singleton==null)
+ {
+ PermissionManager.singleton = new PermissionManager();
+ }
+ return PermissionManager.singleton;
+ }
+
+
+ //PermissionManager
API--------------------------------------------------------------------------------------------------------------
+ /**
+ * Stores a permission and its associations into peristent storage
+ *
+ * @param permission - Permission to be persisted
+ * @param roles - Roles associated with this permission
+ * @param users - Individual users associated with this permission
+ */
+ public void store(Permission permission,Collection roles,Collection users)
+ {
+ //setup the role association
+ if(roles != null)
+ {
+ Set roleAssoc = new HashSet();
+ for(Iterator itr=roles.iterator();itr.hasNext();)
+ {
+ Role role = (Role)itr.next();
+ PermRoleAssoc cour = new PermRoleAssoc();
+ if(role.getId()!=null)
+ {
+ cour.setRoleId(((Long)role.getId()).longValue());
+ }
+ roleAssoc.add(cour);
+ }
+ permission.setRoleAssoc(roleAssoc);
+ }
+ else
+ {
+ permission.setRoleAssoc(null);
+ }
+
+
+ //setup the user association
+ if(users != null)
+ {
+ Set userAssoc = new HashSet();
+ for(Iterator itr=users.iterator();itr.hasNext();)
+ {
+ User user = (User)itr.next();
+ PermUserAssoc cour = new PermUserAssoc();
+ cour.setUserId(((Long)user.getId()).longValue());
+ userAssoc.add(cour);
+ }
+ permission.setUserAssoc(userAssoc);
+ }
+ else
+ {
+ permission.setUserAssoc(null);
+ }
+
+ //persist this into the database
+ this.store(permission);
+ }
+
+ /**
+ * Stores a permission and its associations into peristent storage
+ *
+ * @param permission - Permission to be persisted
+ */
+ public void store(Permission permission)
+ {
+ //persist this into the database
+ Session session = Tools.getCurrentSession();
+ session.saveOrUpdate(permission);
+ }
+
+ /**
+ * Deletes the specified permissions from the database
+ *
+ * @param permissions
+ */
+ public void remove(Collection permissions)
+ {
+ Session session = Tools.getCurrentSession();
+ if(permissions!=null)
+ {
+ for(Iterator itr=permissions.iterator();itr.hasNext();)
+ {
+ Permission permission = (Permission)itr.next();
+ session.delete(permission);
+ }
+ }
+ }
+
+
+ /**
+ * Returns all permissions associated with the specified user
+ *
+ * @param user
+ * @return
+ */
+ public Collection findPermissionsByUser(long userId)
+ {
+ Collection permissions = new HashSet();
+
+ String lookupByUser = "SELECT permission from Permission permission JOIN
permission.userAssoc user WHERE user.userId=?";
+ String lookupByRole = "SELECT * from jbp_cms_perm p,jbp_cms_perm_role
r,jbp_role_membership m WHERE " +
+ "p.id=r.cms_perm_id AND " +
+ "r.role_id=m.jbp_rid AND " +
+ "m.jbp_uid=?";
+
+ Session session = Tools.getCurrentSession();
+
+ //perform lookup by explicitly specified users
+ Query userQuery = session.createQuery(lookupByUser);
+ userQuery.setLong(0,userId);
+ userQuery.setCacheable(true);
+ permissions.addAll(userQuery.list());
+
+
+ //perform lookup based on role membership
+ Query roleQuery =
session.createSQLQuery(lookupByRole).addEntity(Permission.class);
+ roleQuery.setLong(0,userId);
+ roleQuery.setCacheable(true);
+ permissions.addAll(roleQuery.list());
+
+ return permissions;
+ }
+
+ /**
+ * Returns all permissions associated with the specified role
+ *
+ * @param role
+ * @return
+ */
+ public Collection findPermissionsByRole(long roleId)
+ {
+ Collection permissions = new HashSet();
+
+ String lookupByRole = "SELECT permission from Permission permission JOIN
permission.roleAssoc role WHERE role.roleId=?";
+
+ Session session = Tools.getCurrentSession();
+
+ //perform lookup by explicitly specified users
+ Query roleQuery = session.createQuery(lookupByRole);
+ roleQuery.setLong(0,roleId);
+ roleQuery.setCacheable(true);
+ permissions.addAll(roleQuery.list());
+
+
+ return permissions;
+ }
+
+ /**
+ * Return all permissions that match the specified criteria
+ *
+ * @param criteria
+ * @return
+ */
+ public Collection findPermissionsByCriteria(Criteria criteria)
+ {
+ Collection permissions = new HashSet();
+
+ String lookupByCriteria = "SELECT permission from Permission permission JOIN
permission.criteria criteria WHERE criteria.name=? AND criteria.value=?";
+
+ Session session = Tools.getCurrentSession();
+
+ //perform lookup by explicitly specified users
+ Query criteriaQuery = session.createQuery(lookupByCriteria);
+ criteriaQuery.setString(0,criteria.getName());
+ criteriaQuery.setString(1,criteria.getValue());
+ criteriaQuery.setCacheable(true);
+ permissions.addAll(criteriaQuery.list());
+
+
+ return permissions;
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/security/PortalSecurityContext.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/PortalSecurityContext.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/PortalSecurityContext.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,108 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.security;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.portal.identity.User;
+
+/**
+ * An implementation of SecurityContext for the core Portal Engine
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 27, 2006
+ *
+ */
+public class PortalSecurityContext implements SecurityContext
+{
+ private Map contextMap = null;
+
+ /**
+ * signifies the user currently logged in to the system
+ */
+ private User portalUser = null;
+
+
+ /**
+ *
+ *
+ */
+ public PortalSecurityContext(User portalUser)
+ {
+ super();
+ this.portalUser = portalUser;
+ this.contextMap = new HashMap();
+ }
+
+ /**
+ * This method returns the Identity of the user logged into the portal. The return
value is of type
+ * org.jboss.portal.identity.User
+ *
+ * @return Identity related information associated with the user logged into the
portal
+ */
+ public Object getIdentity()
+ {
+ return this.portalUser;
+ }
+
+ /**
+ * Returns value corresponding to the specified attribute name
+ *
+ * @param name
+ * @return
+ */
+ public Object getAttribute(String name)
+ {
+ return this.contextMap.get(name);
+ }
+
+ /**
+ * Sets a specified value corresponding to the specified name in the context
+ *
+ * @param name
+ * @param value
+ */
+ public void setAttribute(String name,Object value)
+ {
+ this.contextMap.put(name,value);
+ }
+
+ /**
+ * Removes the specified attribute
+ *
+ * @param name
+ */
+ public void removeAttribute(String name)
+ {
+ this.contextMap.remove(name);
+ }
+
+ /**
+ * Returns an array of Strings consisting of all keys/names stored in the context
+ *
+ * @return
+ */
+ public String[] getAttributeNames()
+ {
+ return (String[])this.contextMap.keySet().toArray();
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/cms/security/SecurityContext.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/SecurityContext.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/SecurityContext.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,69 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.cms.security;
+
+/**
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 27, 2006
+ *
+ */
+public interface SecurityContext
+{
+ /**
+ * This method returns the Identity of the user logged into the portal.
+ *
+ * @return Identity related information associated with the user logged into the
portal
+ */
+ public Object getIdentity();
+
+ /**
+ * Returns value corresponding to the specified attribute name
+ *
+ * @param name
+ * @return
+ */
+ public Object getAttribute(String name);
+
+
+ /**
+ * Sets a specified value corresponding to the specified name in the context
+ *
+ * @param name
+ * @param value
+ */
+ public void setAttribute(String name,Object value);
+
+ /**
+ * Removes the specified attribute
+ *
+ * @param name
+ */
+ public void removeAttribute(String name);
+
+
+ /**
+ * Returns an array of Strings consisting of all keys/names stored in the context
+ *
+ * @return
+ */
+ public String[] getAttributeNames();
+}
Added:
trunk/cms/src/main/org/jboss/portal/test/cms/commands/CMSInterceptorStackFactory.java
===================================================================
---
trunk/cms/src/main/org/jboss/portal/test/cms/commands/CMSInterceptorStackFactory.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/cms/src/main/org/jboss/portal/test/cms/commands/CMSInterceptorStackFactory.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,40 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.test.cms.commands;
+
+import org.jboss.portal.server.impl.invocation.JBossInterceptorStackFactory;
+import org.jboss.portal.common.invocation.InterceptorStack;
+
+public class CMSInterceptorStackFactory extends JBossInterceptorStackFactory
+{
+
+ public CMSInterceptorStackFactory()
+ {
+ super();
+ }
+
+ public void setInterceptorStack(InterceptorStack stack)
+ {
+ this.stack = stack;
+ }
+
+}
Added: trunk/cms/src/main/org/jboss/portal/test/cms/commands/SecureCommandTestCase.java
===================================================================
---
trunk/cms/src/main/org/jboss/portal/test/cms/commands/SecureCommandTestCase.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/cms/src/main/org/jboss/portal/test/cms/commands/SecureCommandTestCase.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,62 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+package org.jboss.portal.test.cms.commands;
+
+import org.jboss.portal.cms.impl.interceptors.ACLInterceptor;
+import org.jboss.portal.common.invocation.Interceptor;
+import org.jboss.portal.server.impl.invocation.JBossInterceptorStack;
+
+/**
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 30, 2006
+ *
+ */
+public class SecureCommandTestCase extends AbstractCommandTestCase
+{
+ /**
+ *
+ *
+ */
+ public SecureCommandTestCase()
+ {
+ super();
+ }
+
+ /**
+ *
+ */
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ //setup the interceptor stack
+ CMSInterceptorStackFactory stackFactory = new CMSInterceptorStackFactory();
+ ACLInterceptor aclInterceptor = new ACLInterceptor();
+
aclInterceptor.setAuthorizationProviderClass("org.jboss.portal.cms.impl.jcr.command.ACLEnforcer");
+ Interceptor[] interceptors = new Interceptor[1];
+ interceptors[0] = aclInterceptor;
+ JBossInterceptorStack stack = new JBossInterceptorStack(interceptors);
+ stackFactory.setInterceptorStack(stack);
+
+ service.setStackFactory(stackFactory);
+ }
+}
Added: trunk/cms/src/main/org/jboss/portal/test/cms/commands/TestSecureFileGet.java
===================================================================
---
trunk/cms/src/main/org/jboss/portal/test/cms/commands/TestSecureFileGet.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/cms/src/main/org/jboss/portal/test/cms/commands/TestSecureFileGet.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,104 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.test.cms.commands;
+
+import junit.framework.TestSuite;
+import org.jboss.portal.cms.CMSException;
+import org.jboss.portal.cms.Command;
+import org.jboss.portal.cms.impl.ContentImpl;
+import org.jboss.portal.cms.impl.FileImpl;
+import org.jboss.portal.cms.model.Content;
+import org.jboss.portal.cms.model.File;
+
+import java.util.Locale;
+import java.util.Map;
+
+
+/**
+ *
+ * @author Sohil Shah - sohil.shah(a)jboss.com - Nov 30, 2006
+ *
+ */
+public class TestSecureFileGet extends SecureCommandTestCase
+{
+ String rejectPath = "/default/private/license.html";
+ String allowedPath = "/default/images/check.gif";
+
+
+ /**
+ *
+ *
+ */
+ public TestSecureFileGet()
+ {
+ }
+
+ /**
+ *
+ *
+ */
+ public static TestSuite suite() throws Exception
+ {
+ return createTestSuite(TestSecureFileGet.class);
+ }
+
+ /** Tests retrieval of the version labeled LIVE. */
+ public void testFileGet() throws CMSException
+ {
+ //first run against non-access scenario
+ try
+ {
+ Command getCMD =
service.getCommandFactory().createFileGetCommand(rejectPath,Locale.ENGLISH);
+ File newfile = (File)service.execute(getCMD);
+ }
+ catch(CMSException cme)
+ {
+ //assert and make sure access was not granted
+ String cmeMessage = cme.toString();
+ boolean accessGranted = true;
+ if(cmeMessage.indexOf("Access to this resource is denied")!=-1)
+ {
+ accessGranted = false;
+ }
+ this.assertEquals(false,accessGranted);
+ }
+
+ //now run against scenario where access should be granted
+ try
+ {
+ Command getCMD =
service.getCommandFactory().createFileGetCommand(allowedPath,Locale.ENGLISH);
+ File newfile = (File)service.execute(getCMD);
+ }
+ catch(CMSException cme)
+ {
+ //assert and make sure access was granted
+ String cmeMessage = cme.toString();
+ boolean accessGranted = true;
+ if(cmeMessage.indexOf("Access to this resource is denied")!=-1)
+ {
+ accessGranted = false;
+ }
+ this.assertEquals(true,accessGranted);
+ }
+ }
+}
Modified: trunk/cms/src/resources/hibernate/domain.hbm.xml
===================================================================
--- trunk/cms/src/resources/hibernate/domain.hbm.xml 2006-12-12 01:24:50 UTC (rev 5805)
+++ trunk/cms/src/resources/hibernate/domain.hbm.xml 2006-12-12 04:59:21 UTC (rev 5806)
@@ -274,5 +274,96 @@
type="long"
not-null="true"/>
</class>
+
+ <!-- mapping to persist CMS Fine Grained Security related objects -->
+ <class name="org.jboss.portal.cms.security.PermRoleAssoc"
table="jbp_cms_perm_role">
+ <id
+ name="id"
+ column="ID"
+ type="java.lang.Long">
+ <generator class="native"/>
+ </id>
+ <property
+ name="roleId"
+ column="ROLE_ID"
+ type="long"
+ not-null="true"
+ />
+ </class>
+ <class name="org.jboss.portal.cms.security.PermUserAssoc"
table="jbp_cms_perm_user">
+ <id
+ name="id"
+ column="ID"
+ type="java.lang.Long">
+ <generator class="native"/>
+ </id>
+ <property
+ name="userId"
+ column="USER_ID"
+ type="long"
+ not-null="true"
+ />
+ </class>
+ <class name="org.jboss.portal.cms.security.Permission"
table="jbp_cms_perm">
+ <id
+ name="id"
+ column="ID"
+ type="java.lang.Long">
+ <generator class="native"/>
+ </id>
+ <!-- one-to-many association with the criteria object -->
+ <set name="criteria" lazy="true"
table="jbp_cms_perm_criteria" cascade="all">
+ <key column="CMS_PERM_ID"/>
+ <one-to-many class="org.jboss.portal.cms.security.Criteria"/>
+ </set>
+ <!-- many-to-many association with the role object -->
+ <set name="roleAssoc" lazy="true"
cascade="all">
+ <key column="CMS_PERM_ID"/>
+ <one-to-many
class="org.jboss.portal.cms.security.PermRoleAssoc"/>
+ </set>
+ <!-- many-to-many association with the user object -->
+ <set name="userAssoc" lazy="true"
cascade="all">
+ <key column="CMS_PERM_ID"/>
+ <one-to-many
class="org.jboss.portal.cms.security.PermUserAssoc"/>
+ </set>
+ <property
+ name="name"
+ column="NAME"
+ type="string"
+ not-null="true"
+ />
+ <property
+ name="action"
+ column="ACTION"
+ type="string"
+ not-null="true"
+ />
+ <property
+ name="negated"
+ column="NEGATED"
+ type="boolean"
+ not-null="true"
+ />
+ </class>
+ <class name="org.jboss.portal.cms.security.Criteria"
table="jbp_cms_perm_criteria">
+ <id
+ name="id"
+ column="ID"
+ type="java.lang.Long">
+ <generator class="native"/>
+ </id>
+ <property
+ name="name"
+ column="NAME"
+ type="string"
+ not-null="true"
+ />
+ <property
+ name="value"
+ column="VALUE"
+ type="string"
+ not-null="true"
+ />
+ </class>
</hibernate-mapping>
Added: trunk/cms/src/resources/portal-cms-sar/default-content/default/images/back.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/back.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/cms/src/resources/portal-cms-sar/default-content/default/images/check.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/check.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_cornerelement.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_cornerelement.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_jbosslogo.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_jbosslogo.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_main.jpg
===================================================================
(Binary files differ)
Property changes on:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/homeimg_main.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/cms/src/resources/portal-cms-sar/default-content/default/images/logo.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/cms/src/resources/portal-cms-sar/default-content/default/images/logo.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/cms/src/resources/portal-cms-sar/default-content/default/index.html
===================================================================
--- trunk/cms/src/resources/portal-cms-sar/default-content/default/index.html 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/resources/portal-cms-sar/default-content/default/index.html 2006-12-12
04:59:21 UTC (rev 5806)
@@ -1 +1,102 @@
-This is the default index.html page for JBoss Portal JCR CMS.
\ No newline at end of file
+<style type="text/css">
+ #welcomelogo {
+ float: left;
+ margin: 30px 0px 30px 15px;
+ }
+
+ #welcometext {
+ margin: 30px 50px 30px 225px;
+ }
+
+ #welcomegreybox {
+ background-color: #f4f4f4;
+ padding: 15px;
+ margin-bottom: 30px;
+ }
+
+ #welcomegreyboxTD {
+ border-left: 1px solid #d5d5d5;
+ padding-left: 15px;
+ }
+
+ #welcomegreybox h3 {
+ color: #5078aa;
+ font: bold 13px Helvetica, Arial, sans-serif;
+ }
+</style>
+
+<table width="100%" border="0" cellpadding="0"
cellspacing="0">
+ <tr>
+ <td width="560"><img
src="default/images/homeimg_main.jpg" width="560"
height="160"/></td>
+ <td align="right" valign="top"
bgcolor="#7AB5E0"><img
src="default/images/homeimg_cornerelement.gif" width="2"
+
height="2"/></td>
+ </tr>
+</table>
+<div id="welcomelogo"><img
src="default/images/homeimg_jbosslogo.gif" width="143"
height="64"/></div>
+<p id="welcometext">JBoss Portal provides an open source platform for
hosting and serving a portal Web interface,
+ publishing and managing its content, and customizing its experience. While most
packaged Portal frameworks help
+ enterprises launch Portals more quickly, only JBoss Portal delivers the benefits of a
zero-cost open source license
+ combined with a flexible and scalable underling platform.</p>
+
+<div id="welcomegreybox">
+ <table width="100%">
+ <tr>
+ <td valign="top"><h3>Support Services</h3>
+
+ <p>JBoss Inc. offers various support services tailored to fit your
needs. <a href="default/support.html">Explore</a>
+ support and service options for JBoss Portal.</p></td>
+ <td valign="top"
id="welcomegreyboxTD"><h3>PortletSwap</h3>
+
+ <p><a href="http://www.portletswap.com"
target="_blank">Portletswap.com</a> is an open community sponsored
+ by JBoss, Inc. to facilitate the exchange of portlets and layouts for use
in JBoss Portal.</p></td>
+ <td valign="top"
id="welcomegreyboxTD"><h3>Project Information</h3>
+
+ <p>Learn more about the <a
href="default/project.html">JBoss Portal project</a>, on-going
development, open
+ issues, and our
+ user and developer communities.</p></td>
+ </tr>
+ </table>
+
+</div>
+<p>Thank you for downloading and deploying JBoss Portal. We hope your enjoy working
with it as much as we enjoy
+ developing it!</p>
+<p>Baci e abbracci,<br/>
+ The JBoss Portal Team.</p>
+
+<!--
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td valign="top" align="left"
class="portlet-section-body"><font class="portlet-font">JBoss
Portal provides an open source platform for hosting and serving a portal's Web
interface, publishing and managing its content, and customizing its experience. While most
packaged Portal frameworks help enterprises launch Portals more quickly, only JBoss Portal
delivers the benefits of a zero-cost open source license combined with a flexible and
scalable underlying platform.</font></td>
+<td valign="top" align="right"><img
src="default/images/jboss_logo.gif"></td>
+<tr>
+<td colspan="2"><table width="100%"
border="0">
+<tr>
+<td align="left" valign="top" width="64"
class="portlet-section-alternate"><a
href="default/support.html"><img
src="default/images/support.gif" border="0"></a></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font"><b>Support Services</b><br/>
+JBoss Inc. offers various support services tailored to fit your needs. <a
href="default/support.html">Click here</a> to explore support and
service options related to JBoss Portal.
+</font></td>
+</tr>
+<tr>
+<td align="left" valign="top" width="64"
class="portlet-section-alternate"><a
href="http://www.portletswap.com" target="_blank"><img
src="default/images/plugin.gif" border="0"></a></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font"><b>PortletSwap</b><br/>
+<a href="http://www.portletswap.com"
target="_blank">PortletSwap.com</a> is a open community sponsored by
JBoss, Inc. to facilitate the exchange of portlets and layouts for use in JBoss Portal.
<a href="http://www.portletswap.com" target="_blank">Click
here</a> to visit
PortletSwap.com.
+</font></td>
+</tr>
+<tr>
+<td align="left" valign="top" width="64"
class="portlet-section-alternate"><a
href="default/project.html"><img
src="default/images/project.gif" border="0"></a></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font"><b>Project Information</b><br/>
+<a href="default/project.html">Click here</a> to learn more about
the JBoss Portal project, on-going development, open issues, and our vibrant user and
developer communities.
+</font></td>
+</tr>
+</table>
+</tr>
+<tr>
+<td colspan="2" align="left"
class="portlet-section-body"><font class="portlet-font">
+Thank you for downloading and deploying JBoss Portal. We hope you enjoy working with it
as much as we enjoy developing it!
+<br/><br/>
+Bacci e Abracci,<br/>
+The JBoss Portal Team.
+</font></td>
+</tr>
+</table>
+-->
Added:
trunk/cms/src/resources/portal-cms-sar/default-content/default/private/license.html
===================================================================
---
trunk/cms/src/resources/portal-cms-sar/default-content/default/private/license.html 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/cms/src/resources/portal-cms-sar/default-content/default/private/license.html 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,38 @@
+<!-- begin: portlet content -->
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td valign="top" align="left"
class="portlet-section-body"><font class="portlet-font">JBoss
Inc. delivers the Professional Support, Consulting, and Training that you need whether you
are testing a proof of concept, deploying a mission-critical application, or rolling out
JEMS across your enterprise. </font></td>
+<td valign="top" align="right"><img
src="default/images/jboss_logo.gif"></td>
+</tr>
+<tr>
+<td colspan="2">
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/profsupport"
target="_blank">Professional Support</a>
+<br/>
+The JBoss Subscription is a set of services and tools that assist you during every stage
of the application lifecycle - from design and development, thru testing and deployment,
to on-going management and monitoring of your enterprise application deployments. JBoss
Subscriptions allow you to reduce business, legal, and technical risks while enabling you
to more effectively utilize your team's resources. A JBoss Subscription will ensure
that you achieve a much greater success rate for all of your JEMS-based projects.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/consulting"
target="_blank">Consulting Services</a>
+<br/>
+JBoss offers short-term on-site JEMS consulting engagements that provide you expert
assistance at various stages of the application lifecycle. All engagements are delivered
by certified JEMS consultants.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/training"
target="_blank">Training and Certification</a>
+<br/>
+A Certified JBoss Web Developer is capable of implementing presentation tier components
for J2EE applications. They have the base knowledge on Servlet and JSP technology, Portlet
specification, Tomcat Servlet container and JBoss Portal. A Certified JBoss Developer for
web tier is able to implement and deploy presentation components (Web Archives) on Tomcat
server and Portlet components on JBoss Portal implementation.
+</font></td>
+</tr>
+</table>
+</table>
+<br/>
+<a href="default/index.html"><img
src="default/images/back.gif" border="0"
alt="back"></a>
+<!-- end: portlet content -->
\ No newline at end of file
Added: trunk/cms/src/resources/portal-cms-sar/default-content/default/project.html
===================================================================
--- trunk/cms/src/resources/portal-cms-sar/default-content/default/project.html 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/resources/portal-cms-sar/default-content/default/project.html 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,69 @@
+<!-- begin: portlet content -->
+<table width="100%" border="0" cellpadding="2">
+ <tr>
+ <td valign="top" align="left"
class="portlet-section-body"><font class="portlet-font">JBoss
Inc. delivers the
+ Professional Support, Consulting, and Training that you need whether you are
testing a proof of concept,
+ deploying a mission-critical application, or rolling out JEMS across your
enterprise. </font></td>
+ <td valign="top" align="right"><img
src="default/images/jboss_logo.gif"></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <table width="100%" border="0"
cellpadding="2">
+ <tr>
+ <td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
+ src="default/images/check.gif"></td>
+ <td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+ <a
href="http://labs.jboss.com/portal/jbossportal/index.html"
target="_blank">JBoss Portal Home</a>
+ <br/>
+ The Epicenter of everything JBoss Portal.</font></td>
+ </tr>
+ <tr>
+ <td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
+ src="default/images/check.gif"></td>
+ <td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+ <a
href="http://labs.jboss.com/portal/jbossportal/docs/index.html"
target="_blank">Documentation</a>
+ <br/>
+ Here you will find user documentation, reference documentation, tutorials,
and javadoc.</font></td>
+ </tr>
+ <tr>
+ <td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
+ src="default/images/check.gif"></td>
+ <td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+ <a
href="http://www.jboss.com/index.html?module=bb&op=viewforum&...
target="_blank">Forums</a>
+ <br/>
+ Our forums are the main channel of communication between all community
+ members. If you have any questions or concerns, please use
+ our <a
href="http://www.jboss.org/index.html?module=bb&op=viewforum...
target="_blank">User
+ Forums</a>, <a
href="/index.html?module=bb&op=viewforum&f=205"
target="_blank">Developer
+ Forums</a>, or <a
href="http://jboss.org/index.html?module=bb&op=viewforum&f=2...
target="_blank">WSRP Forums</a> to voice them. Project developers and
community members are always there to help.
+ </font></td>
+ </tr>
+ <tr>
+ <td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
+ src="default/images/check.gif"></td>
+ <td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+ <a
href="http://www.jboss.com/wiki/Wiki.jsp?page=JBossPortal"
target="_blank">Wiki</a>
+ <br/>
+ Our wiki knowledge base is a user and developer contributed collection of
important resources regarding
+ JBoss Portal.</font></td>
+ </tr>
+ <tr>
+ <td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
+ src="default/images/check.gif"></td>
+ <td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+ <a
href="http://jira.jboss.com/jira/secure/BrowseProject.jspa?id=10050&...
target="_blank">Jira</a>
+ <br/>
+ JBoss Portal uses the JIRA tracking and project management system to
organize and prioritize tasks.<br>
+ <a
href="http://jira.jboss.com/jira/secure/BrowseProject.jspa?id=10050&...
target="_blank">JBoss Portal</a>
+ | <a
+
href="http://jira.jboss.com/jira/browse/JBPORTAL?report=com.atlassia...
+ target="_blank">Open Issues</a>
+ | <a
+
href="http://jira.jboss.com/jira/browse/JBPORTAL?report=com.atlassia...
+ target="_blank">Roadmap</a></font></td>
+ </tr>
+ </table>
+</table>
+<br/>
+<a href="default/index.html"><img
src="default/images/back.gif" border="0"
alt="back"></a>
+<!-- end: portlet content -->
Added: trunk/cms/src/resources/portal-cms-sar/default-content/default/support.html
===================================================================
--- trunk/cms/src/resources/portal-cms-sar/default-content/default/support.html 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/cms/src/resources/portal-cms-sar/default-content/default/support.html 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,38 @@
+<!-- begin: portlet content -->
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td valign="top" align="left"
class="portlet-section-body"><font class="portlet-font">JBoss
Inc. delivers the Professional Support, Consulting, and Training that you need whether you
are testing a proof of concept, deploying a mission-critical application, or rolling out
JEMS across your enterprise. </font></td>
+<td valign="top" align="right"><img
src="default/images/jboss_logo.gif"></td>
+</tr>
+<tr>
+<td colspan="2">
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/profsupport"
target="_blank">Professional Support</a>
+<br/>
+The JBoss Subscription is a set of services and tools that assist you during every stage
of the application lifecycle - from design and development, thru testing and deployment,
to on-going management and monitoring of your enterprise application deployments. JBoss
Subscriptions allow you to reduce business, legal, and technical risks while enabling you
to more effectively utilize your team's resources. A JBoss Subscription will ensure
that you achieve a much greater success rate for all of your JEMS-based projects.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/consulting"
target="_blank">Consulting Services</a>
+<br/>
+JBoss offers short-term on-site JEMS consulting engagements that provide you expert
assistance at various stages of the application lifecycle. All engagements are delivered
by certified JEMS consultants.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/training"
target="_blank">Training and Certification</a>
+<br/>
+A Certified JBoss Web Developer is capable of implementing presentation tier components
for J2EE applications. They have the base knowledge on Servlet and JSP technology, Portlet
specification, Tomcat Servlet container and JBoss Portal. A Certified JBoss Developer for
web tier is able to implement and deploy presentation components (Web Archives) on Tomcat
server and Portlet components on JBoss Portal implementation.
+</font></td>
+</tr>
+</table>
+</table>
+<br/>
+<a href="default/index.html"><img
src="default/images/back.gif" border="0"
alt="back"></a>
+<!-- end: portlet content -->
\ No newline at end of file
Added:
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/code.html
===================================================================
---
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/code.html 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/code.html 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,38 @@
+<!-- begin: portlet content -->
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td valign="top" align="left"
class="portlet-section-body"><font
class="portlet-font"><b>Document2: This is a protected document. This
is used to test the fine grained access control</b></font></td>
+<td valign="top" align="right"><img
src="default/images/jboss_logo.gif"></td>
+</tr>
+<tr>
+<td colspan="2">
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/profsupport"
target="_blank">Professional Support</a>
+<br/>
+The JBoss Subscription is a set of services and tools that assist you during every stage
of the application lifecycle - from design and development, thru testing and deployment,
to on-going management and monitoring of your enterprise application deployments. JBoss
Subscriptions allow you to reduce business, legal, and technical risks while enabling you
to more effectively utilize your team's resources. A JBoss Subscription will ensure
that you achieve a much greater success rate for all of your JEMS-based projects.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/consulting"
target="_blank">Consulting Services</a>
+<br/>
+JBoss offers short-term on-site JEMS consulting engagements that provide you expert
assistance at various stages of the application lifecycle. All engagements are delivered
by certified JEMS consultants.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/training"
target="_blank">Training and Certification</a>
+<br/>
+A Certified JBoss Web Developer is capable of implementing presentation tier components
for J2EE applications. They have the base knowledge on Servlet and JSP technology, Portlet
specification, Tomcat Servlet container and JBoss Portal. A Certified JBoss Developer for
web tier is able to implement and deploy presentation components (Web Archives) on Tomcat
server and Portlet components on JBoss Portal implementation.
+</font></td>
+</tr>
+</table>
+</table>
+<br/>
+<a href="default/index.html"><img
src="default/images/back.gif" border="0"
alt="back"></a>
+<!-- end: portlet content -->
\ No newline at end of file
Added:
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/confidential/license.html
===================================================================
---
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/confidential/license.html 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/confidential/license.html 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,38 @@
+<!-- begin: portlet content -->
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td valign="top" align="left"
class="portlet-section-body"><font
class="portlet-font"><b>Document3: This is a protected document. This
is used to test the fine grained access control</b></font></td>
+<td valign="top" align="right"><img
src="default/images/jboss_logo.gif"></td>
+</tr>
+<tr>
+<td colspan="2">
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/profsupport"
target="_blank">Professional Support</a>
+<br/>
+The JBoss Subscription is a set of services and tools that assist you during every stage
of the application lifecycle - from design and development, thru testing and deployment,
to on-going management and monitoring of your enterprise application deployments. JBoss
Subscriptions allow you to reduce business, legal, and technical risks while enabling you
to more effectively utilize your team's resources. A JBoss Subscription will ensure
that you achieve a much greater success rate for all of your JEMS-based projects.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/consulting"
target="_blank">Consulting Services</a>
+<br/>
+JBoss offers short-term on-site JEMS consulting engagements that provide you expert
assistance at various stages of the application lifecycle. All engagements are delivered
by certified JEMS consultants.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/training"
target="_blank">Training and Certification</a>
+<br/>
+A Certified JBoss Web Developer is capable of implementing presentation tier components
for J2EE applications. They have the base knowledge on Servlet and JSP technology, Portlet
specification, Tomcat Servlet container and JBoss Portal. A Certified JBoss Developer for
web tier is able to implement and deploy presentation components (Web Archives) on Tomcat
server and Portlet components on JBoss Portal implementation.
+</font></td>
+</tr>
+</table>
+</table>
+<br/>
+<a href="default/index.html"><img
src="default/images/back.gif" border="0"
alt="back"></a>
+<!-- end: portlet content -->
\ No newline at end of file
Added:
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/license.html
===================================================================
---
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/license.html 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/core/src/bin/portal-cms-sar/portal/cms/conf/default-content/default/private/license.html 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,38 @@
+<!-- begin: portlet content -->
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td valign="top" align="left"
class="portlet-section-body"><font
class="portlet-font"><b>Document1: This is a protected document. This
is used to test the fine grained access control</b></font></td>
+<td valign="top" align="right"><img
src="default/images/jboss_logo.gif"></td>
+</tr>
+<tr>
+<td colspan="2">
+<table width="100%" border="0" cellpadding="2">
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/profsupport"
target="_blank">Professional Support</a>
+<br/>
+The JBoss Subscription is a set of services and tools that assist you during every stage
of the application lifecycle - from design and development, thru testing and deployment,
to on-going management and monitoring of your enterprise application deployments. JBoss
Subscriptions allow you to reduce business, legal, and technical risks while enabling you
to more effectively utilize your team's resources. A JBoss Subscription will ensure
that you achieve a much greater success rate for all of your JEMS-based projects.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/consulting"
target="_blank">Consulting Services</a>
+<br/>
+JBoss offers short-term on-site JEMS consulting engagements that provide you expert
assistance at various stages of the application lifecycle. All engagements are delivered
by certified JEMS consultants.
+</font></td>
+</tr>
+<tr>
+<td class="portlet-section-alternate" width="16"
valign="top" align="left"><img
src="default/images/check.gif"></td>
+<td align="left" valign="top"
class="portlet-section-alternate"><font
class="portlet-font">
+<a
href="http://www.jboss.com/services/training"
target="_blank">Training and Certification</a>
+<br/>
+A Certified JBoss Web Developer is capable of implementing presentation tier components
for J2EE applications. They have the base knowledge on Servlet and JSP technology, Portlet
specification, Tomcat Servlet container and JBoss Portal. A Certified JBoss Developer for
web tier is able to implement and deploy presentation components (Web Archives) on Tomcat
server and Portlet components on JBoss Portal implementation.
+</font></td>
+</tr>
+</table>
+</table>
+<br/>
+<a href="default/index.html"><img
src="default/images/back.gif" border="0"
alt="back"></a>
+<!-- end: portlet content -->
\ No newline at end of file
Modified:
trunk/core/src/main/org/jboss/portal/core/aspects/controller/PageCustomizerInterceptor.java
===================================================================
---
trunk/core/src/main/org/jboss/portal/core/aspects/controller/PageCustomizerInterceptor.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/core/src/main/org/jboss/portal/core/aspects/controller/PageCustomizerInterceptor.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -253,6 +253,15 @@
}
sb.append(" | ");
+
+ //inject CMS Admin link
+ if(user != null && showadminURL == null)
+ {
+ sb.append("<a
href=\"").append("/portal/portal/cms").append("\">CMS
Admin Tool</a>");
+ }
+
+ sb.append(" | ");
+
sb.append("<a
href=\"").append(logoutURL).append("\">Logout</a>");
}
return sb;
Modified: trunk/core/src/main/org/jboss/portal/core/aspects/server/UserInterceptor.java
===================================================================
---
trunk/core/src/main/org/jboss/portal/core/aspects/server/UserInterceptor.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/core/src/main/org/jboss/portal/core/aspects/server/UserInterceptor.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -23,6 +23,7 @@
package org.jboss.portal.core.aspects.server;
import org.jboss.logging.Logger;
+import org.jboss.portal.cms.impl.jcr.JCRCMS;
import org.jboss.portal.common.invocation.InvocationException;
import org.jboss.portal.core.CoreConstants;
import org.jboss.portal.identity.NoSuchUserException;
@@ -170,6 +171,10 @@
{
// Attach the request user to the invocation
invocation.getRequest().setUser(user);
+
+ //setup the portal user information to be used by the CMS Business Layer
+ //for fine grained access control enforcement
+ JCRCMS.getUserInfo().set(user);
// Continue the invocation
invocation.invokeNext();
Modified: trunk/core/src/main/org/jboss/portal/core/cms/CMSObjectCommandFactory.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/cms/CMSObjectCommandFactory.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/core/src/main/org/jboss/portal/core/cms/CMSObjectCommandFactory.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -148,7 +148,16 @@
}
catch (CMSException e)
{
- log.error("CMS error", e);
+ if(e.toString().indexOf("Access to this resource is denied")!=-1)
+ {
+ ParametersStateString parameters = new ParametersStateString();
+ parameters.setValue("path", portalRequestPath);
+ return new InvokePortletWindowRenderCommand(targetWindowId, Mode.VIEW,
null, parameters);
+ }
+ else
+ {
+ log.error("CMS error", e);
+ }
}
return null; // TODO: 404?
}
Modified: trunk/core/src/main/org/jboss/portal/core/portlet/cms/CMSPortlet.java
===================================================================
--- trunk/core/src/main/org/jboss/portal/core/portlet/cms/CMSPortlet.java 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/core/src/main/org/jboss/portal/core/portlet/cms/CMSPortlet.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -140,11 +140,12 @@
public void doView(RenderRequest req, RenderResponse resp) throws PortletException,
PortletSecurityException, IOException
{
+ String path = null;
try
{
// String linkMode = req.getPreferences().getValue("linkMode",
LINK_MODE_PORTLET);
// boolean useCMSLink = LINK_MODE_CMS.equals(linkMode);
- String path = req.getParameter("path");
+ path = req.getParameter("path");
if (path == null)
{
PortletPreferences prefs = req.getPreferences();
@@ -245,7 +246,26 @@
}
catch (CMSException e)
{
- log.error("CMS error", e);
+ if(e.toString().indexOf("Access to this resource is denied")!=-1)
+ {
+ resp.setContentType("text/html");
+ PrintWriter writer = resp.getWriter();
+ String sHTML = "";
+ if(path==null || path.trim().length()==0)
+ {
+ sHTML = "<h2>Access Denied</h2>You are not allowed to
access the following resource";
+ }
+ else
+ {
+ sHTML = "<h2>Access Denied</h2>You are not allowed to
access the following resource - "+path;
+ }
+ writer.write(sHTML);
+ writer.close();
+ }
+ else
+ {
+ log.error("CMS error", e);
+ }
}
}
Modified:
trunk/core/src/main/org/jboss/portal/core/portlet/cms/admin/CMSAdminPortlet.java
===================================================================
---
trunk/core/src/main/org/jboss/portal/core/portlet/cms/admin/CMSAdminPortlet.java 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/core/src/main/org/jboss/portal/core/portlet/cms/admin/CMSAdminPortlet.java 2006-12-12
04:59:21 UTC (rev 5806)
@@ -22,6 +22,8 @@
******************************************************************************/
package org.jboss.portal.core.portlet.cms.admin;
+import javax.portlet.PortletRequest;
+
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.portlet.PortletFileUpload;
@@ -37,6 +39,10 @@
import org.jboss.portal.cms.model.Folder;
import org.jboss.portal.cms.util.FileUtil;
import org.jboss.portal.cms.util.NodeUtil;
+import org.jboss.portal.cms.security.PermissionManager;
+import org.jboss.portal.cms.security.Permission;
+import org.jboss.portal.cms.security.Criteria;
+
import org.jboss.portal.core.cms.StreamContentCommand;
import org.jboss.portal.core.controller.ControllerContext;
import org.jboss.portal.identity.IdentityException;
@@ -50,22 +56,31 @@
import org.jboss.portlet.JBossRenderRequest;
import org.jboss.portlet.JBossRenderResponse;
+import org.jboss.portal.identity.User;
+import org.jboss.portal.identity.Role;
+import org.jboss.portal.identity.db.RoleImpl;
+
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletSession;
import javax.portlet.UnavailableException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.PrintWriter;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.Vector;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.HashSet;
/**
* @author <a href="mailto:roy@jboss.org">Roy Russo</a>
* @author <a href="mailto:theute@jboss.org">Thomas Heute</a>
+ * @author <a href="mailto:sohil.shah@jboss.com">Sohil Shah</a>
*/
public class CMSAdminPortlet extends JBossPortlet
{
@@ -96,13 +111,52 @@
protected void doView(final JBossRenderRequest rReq, final JBossRenderResponse rRes)
throws PortletException, IOException, UnavailableException
{
+ //check and make sure the CMSAdminPortlet is accessible to the current user
+ if(!this.isPortletAccessible(rReq))
+ {
+ rRes.setContentType("text/html");
+ PrintWriter writer = rRes.getWriter();
+ String sHTML = "<h2>Access Denied</h2>";
+ writer.write(sHTML);
+ writer.close();
+ return;
+ }
+
+
+ //now if the security console is being launched...make sure proper access is
fulfilled
+ String op = rReq.getParameter("op");
+ if(op!=null && CMSAdminConstants.OP_CONFIRMSECURE.equals(op))
+ {
+ if(!this.isSecurityConsoleAccessible(rReq))
+ {
+ rRes.setContentType("text/html");
+ PrintWriter writer = rRes.getWriter();
+ String sHTML = "<h2>Access Denied</h2>";
+ writer.write(sHTML);
+ writer.close();
+ return;
+ }
+ }
+
+
try
{
- internalDoView(rReq, rRes);
+ if(rReq.getParameter("accessDenied")!=null)
+ {
+ throw new PortletException("Access to this resource is denied");
+ }
+ internalDoView(rReq, rRes);
}
catch (CMSException e)
{
- throw new PortletException(e);
+ if(e.toString().indexOf("Access to this resource is denied")!=-1)
+ {
+ throw new PortletException("Access to this resource is denied");
+ }
+ else
+ {
+ throw new PortletException(e);
+ }
}
}
@@ -380,15 +434,33 @@
{
String sPath = rReq.getParameter("path");
String sConfirm = rReq.getParameter("confirm");
+ String returnOp = rReq.getParameter("returnOp");
Set roleSet;
Set userSet;
+ Set readRoleSet;
+ Set readUserSet;
+ Set writeRoleSet;
+ Set writeUserSet;
+ Set manageRoleSet;
+ Set manageUserSet;
try
{
roleSet = roleModule.findRoles();
userSet = userModule.findUsers(0, 1000);
- // TODO: get roles/users from DB and mark certain ones selected.
+ Collection permissions = PermissionManager.getInstance().
+ findPermissionsByCriteria(new Criteria("path",sPath));
+
+ readRoleSet = this.processRolePermissions(permissions,"read");
+ readUserSet = this.processUserPermissions(permissions,"read");
+
+ writeRoleSet = this.processRolePermissions(permissions,"write");
+ writeUserSet = this.processUserPermissions(permissions,"write");
+
+ manageRoleSet = this.processRolePermissions(permissions,"manage");
+ manageUserSet = this.processUserPermissions(permissions,"manage");
+
}
catch (IdentityException ie)
{
@@ -400,6 +472,15 @@
rReq.setAttribute("roles", roleSet);
rReq.setAttribute("users", userSet);
+ rReq.setAttribute("readRoleSet",readRoleSet);
+ rReq.setAttribute("readUserSet",readUserSet);
+ rReq.setAttribute("writeRoleSet",writeRoleSet);
+ rReq.setAttribute("writeUserSet",writeUserSet);
+ rReq.setAttribute("manageRoleSet",manageRoleSet);
+ rReq.setAttribute("manageUserSet",manageUserSet);
+
+ //operation to return from the security console
+ rReq.setAttribute("returnOp",returnOp);
if (sConfirm != null)
{
@@ -412,13 +493,33 @@
public void processAction(final JBossActionRequest aReq, final JBossActionResponse
aRes) throws PortletException
{
+ //now if the security console is being launched...make sure proper access is
fulfilled
+ String op = aReq.getParameter("op");
+ if(op!=null && CMSAdminConstants.OP_SECURE.equals(op))
+ {
+ if(!this.isSecurityConsoleAccessible(aReq))
+ {
+ aRes.setRenderParameter("op",
CMSAdminConstants.OP_CONFIRMSECURE);
+ aRes.setRenderParameter("path",
aReq.getParameter("path"));
+ aRes.setRenderParameter("confirm", "Access to the Security
Console was Denied");
+ return;
+ }
+ }
+
try
{
internalProcessAction(aReq, aRes);
}
catch (CMSException e)
{
- throw new PortletException(e);
+ if(e.toString().indexOf("Access to this resource is denied")!=-1)
+ {
+ aRes.setRenderParameter("accessDenied","true");
+ }
+ else
+ {
+ throw new PortletException(e);
+ }
}
}
@@ -901,14 +1002,26 @@
}
else if (CMSAdminConstants.OP_SECURE.equals(op))
{
- String[] selectedRoles = aReq.getParameterValues("secureroles");
- String[] selectedUsers = aReq.getParameterValues("secureusers");
-
- // TODO: assign roles/users to node
-
- aRes.setRenderParameter("op", CMSAdminConstants.OP_CONFIRMSECURE);
- aRes.setRenderParameter("path",
aReq.getParameter("path"));
- aRes.setRenderParameter("confirm", "Security settings updated
successfully.");
+ boolean success = false;
+ try
+ {
+ this.storePermissions(aReq);
+ success = true;
+ }
+ catch(Exception e)
+ {
+ aRes.setRenderParameter("confirm", "An error occurred
while setting the permissions.("+e.toString()+")");
+ success = false;
+ }
+
+ if(success)
+ {
+ aRes.setRenderParameter("confirm", "Security settings
updated successfully.");
+ }
+
+ aRes.setRenderParameter("op",
CMSAdminConstants.OP_CONFIRMSECURE);
+ aRes.setRenderParameter("path",
aReq.getParameter("path"));
+ aRes.setRenderParameter("returnOp",
aReq.getParameter("returnOp"));
}
}
else
@@ -947,8 +1060,225 @@
ControllerContext cc = req.getControllerContext();
return cc.renderURL(cmd, NON_SECURE_NON_AUTH_URL_CONTEXT,
RELATIVE_SERVLET_ENCODED_URL_FORMAT);
}
-
+
static final URLContext NON_SECURE_NON_AUTH_URL_CONTEXT =
URLContext.newInstance(false, false);
static final URLFormat RELATIVE_SERVLET_ENCODED_URL_FORMAT =
URLFormat.newInstance(true, true);
+
+ //fine-grained access related ui control
logic-------------------------------------------------------------------------------------------------
+ /**
+ *
+ * @param aReq
+ */
+ private void storePermissions(JBossActionRequest aReq) throws Exception
+ {
+ String path = aReq.getParameter("path");
+ String[] readRoles = aReq.getParameterValues("secureroles:read");
+ String[] readUsers = aReq.getParameterValues("secureusers:read");
+ String[] writeRoles = aReq.getParameterValues("secureroles:write");
+ String[] writeUsers = aReq.getParameterValues("secureusers:write");
+ String[] manageRoles = aReq.getParameterValues("secureroles:manage");
+ String[] manageUsers = aReq.getParameterValues("secureusers:manage");
+
+
+ if(
+ (readRoles==null || readRoles.length==0) &&
+ (readUsers==null || readUsers.length==0) &&
+ (writeRoles==null || writeRoles.length==0) &&
+ (writeUsers==null || writeUsers.length==0) &&
+ (manageRoles==null || manageRoles.length==0) &&
+ (manageUsers==null || manageUsers.length==0)
+ )
+ {
+ //remove all direct permissions on this node
+ Collection oldPermissions =
PermissionManager.getInstance().findPermissionsByCriteria(new
Criteria("path",path));
+ PermissionManager.getInstance().remove(oldPermissions);
+ return;
+ }
+
+ //cleanup the old permissions on this node, before new ones are created
+ Collection oldPermissions =
PermissionManager.getInstance().findPermissionsByCriteria(new
Criteria("path",path));
+ PermissionManager.getInstance().remove(oldPermissions);
+
+ //setup the read permission on this node
+ this.storePermission("read",path,readRoles,readUsers);
+
+ //setup the write permission on this node
+ this.storePermission("write",path,writeRoles,writeUsers);
+
+ //setup the manage permission on this node
+ this.storePermission("manage",path,manageRoles,manageUsers);
+ }
+
+ /**
+ *
+ * @param permission
+ * @param action
+ * @param criteria
+ * @param roles
+ * @param users
+ */
+ private void storePermission(String action,String path,String[] roles,String[] users)
throws Exception
+ {
+ Permission permission = new Permission("cms",action);
+ permission.addCriteria(new Criteria("path",path));
+
+ Set rolesSet = null;
+ if(roles!=null && roles.length>0)
+ {
+ rolesSet = new HashSet();
+ for(int i=0;i<roles.length;i++)
+ {
+ int roleId = Integer.parseInt(roles[i]);
+ Role role = null;
+ if(roleId>0)
+ {
+ role = this.roleModule.findRoleById(roles[i]);
+ }
+ else
+ {
+ role = new RoleImpl();
+ }
+ rolesSet.add(role);
+ }
+ }
+
+ Set usersSet = null;
+ if(users!=null && users.length>0)
+ {
+ usersSet = new HashSet();
+ for(int i=0;i<users.length;i++)
+ {
+ User user = this.userModule.findUserById(users[i]);
+ usersSet.add(user);
+ }
+ }
+
+ PermissionManager.getInstance().store(permission,rolesSet,usersSet);
+ }
+
+ /**
+ *
+ * @param permissions
+ * @param action
+ * @return
+ */
+ private Set processRolePermissions(Collection permissions,String action)
+ {
+ Set rolePermissions = new HashSet();
+
+ if(permissions!=null)
+ {
+ for(Iterator itr=permissions.iterator();itr.hasNext();)
+ {
+ Permission permission = (Permission)itr.next();
+ if(permission.getService().equals("cms") &&
permission.getAction().equals(action))
+ {
+ rolePermissions.addAll(permission.getRoleAssocIds());
+ }
+ }
+ }
+
+ return rolePermissions;
+ }
+
+ /**
+ *
+ * @param permissions
+ * @param action
+ * @return
+ */
+ private Set processUserPermissions(Collection permissions,String action)
+ {
+ Set userPermissions = new HashSet();
+
+ if(permissions!=null)
+ {
+ for(Iterator itr=permissions.iterator();itr.hasNext();)
+ {
+ Permission permission = (Permission)itr.next();
+ if(permission.getService().equals("cms") &&
permission.getAction().equals(action))
+ {
+ userPermissions.addAll(permission.getUserAssocIds());
+ }
+ }
+ }
+
+ return userPermissions;
+ }
+
+ /**
+ *
+ * @param aReq
+ * @return
+ */
+ private boolean isPortletAccessible(PortletRequest portletRequest)
+ {
+ try
+ {
+ boolean isPortletAccessible = false;
+
+ if(portletRequest.getUserPrincipal()!=null)
+ {
+ User user =
this.userModule.findUserByUserName(portletRequest.getUserPrincipal().getName());
+ Collection permissions =
PermissionManager.getInstance().findPermissionsByUser(((Long)user.getId()).longValue());
+ if(permissions != null)
+ {
+ for(Iterator itr=permissions.iterator();itr.hasNext();)
+ {
+ Permission permission = (Permission)itr.next();
+ if( (permission.getService().equals("cms")) &&
+ (permission.getAction().equals("write") ||
permission.getAction().equals("manage"))
+ )
+ {
+ isPortletAccessible = true;
+ }
+ }
+ }
+ }
+
+ return isPortletAccessible;
+ }
+ catch(Exception e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ *
+ * @param aReq
+ * @return
+ */
+ private boolean isSecurityConsoleAccessible(PortletRequest portletRequest)
+ {
+ try
+ {
+ boolean isAccessible = false;
+
+ if(portletRequest.getUserPrincipal()!=null)
+ {
+ User user =
this.userModule.findUserByUserName(portletRequest.getUserPrincipal().getName());
+ Set roles = this.roleModule.getRoles(user);
+ if(roles!=null)
+ {
+ for(Iterator itr=roles.iterator();itr.hasNext();)
+ {
+ Role role = (Role)itr.next();
+ if(role.getName().equalsIgnoreCase("admin"))
+ {
+ isAccessible = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return isAccessible;
+ }
+ catch(Exception e)
+ {
+ return false;
+ }
+ }
}
\ No newline at end of file
Modified: trunk/core/src/resources/portal-cms-sar/META-INF/jboss-service.xml
===================================================================
--- trunk/core/src/resources/portal-cms-sar/META-INF/jboss-service.xml 2006-12-12 01:24:50
UTC (rev 5805)
+++ trunk/core/src/resources/portal-cms-sar/META-INF/jboss-service.xml 2006-12-12 04:59:21
UTC (rev 5806)
@@ -57,15 +57,13 @@
<depends>jboss.jca:service=DataSourceBinding,name=@portal.datasource.name@</depends>
<depends>portal:service=JAASLoginModule</depends>
<depends>portal:service=Hibernate,type=CMS</depends>
- <!--
- //this is not needed anymore. this cache is redundant because of JBossCache PM
- <depends optional-attribute-name="StackFactory"
proxy-type="attribute">portal:service=InterceptorStackFactory,type=Cms</depends>
- -->
+ <depends optional-attribute-name="StackFactory"
proxy-type="attribute">portal:service=InterceptorStackFactory,type=Cms</depends>
+ <depends optional-attribute-name="UserModule"
proxy-type="attribute">portal:service=Module,type=User</depends>
<attribute name="DoChecking">true</attribute>
<attribute
name="DefaultContentLocation">portal/cms/conf/default-content/default/</attribute>
<attribute name="DefaultLocale">en</attribute>
<attribute
name="RepositoryName">PortalRepository</attribute>
- <attribute
name="HomeDir">${jboss.server.data.dir}${/}portal${/}cms${/}conf</attribute>
+ <attribute
name="HomeDir">${jboss.server.data.dir}${/}portal${/}cms${/}conf</attribute>
<attribute name="Config">
<Repository>
<!--
@@ -108,7 +106,7 @@
<!--
persistence manager of the workspace.
- Use XMLPersistenceManager for LocalFileSystem Store and
HibernatePersistentManager .
+ Use XMLPersistenceManager for LocalFileSystem Store and
JBossCachePersistenceManager .
-->
<!-- HibernatePersistentManager: uses RDBMS + Hibernate for storage
-->
@@ -155,7 +153,7 @@
<!--
Configures the persistence manager to be used for persisting version
state.
- Use XMLPersistenceManager for LocalFileSystem Store and
HibernatePersistentManager for HibernateStore.
+ Use XMLPersistenceManager for LocalFileSystem Store and
JBossCachePersistenceManager for HibernateStore.
-->
<!-- HibernatePersistentManager: uses RDBMS + Hibernate for storage
-->
@@ -422,6 +420,108 @@
<attribute name="CacheLoaderAsynchronous">false</attribute-->
</mbean>
+
+ <!-- interceptor factory where all cms interceptors are registered -->
+ <mbean
+
code="org.jboss.portal.server.impl.invocation.JBossInterceptorStackFactory"
+ name="portal:service=InterceptorStackFactory,type=Cms"
+ xmbean-dd=""
+ xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
+ <xmbean/>
+ <depends-list optional-attribute-name="InterceptorNames">
+
<depends-list-element>portal:service=Interceptor,type=Cms,name=ACL</depends-list-element>
+ </depends-list>
+ </mbean>
+
+ <!-- ACL Security Interceptor -->
+ <mbean
+ code="org.jboss.portal.cms.impl.interceptors.ACLInterceptor"
+ name="portal:service=Interceptor,type=Cms,name=ACL"
+ xmbean-dd=""
+ xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
+ <xmbean/>
+ <attribute
name="JNDIName">java:portal/cms/CMSSessionFactory</attribute>
+ <attribute
name="AuthorizationProviderClass">org.jboss.portal.cms.impl.jcr.command.ACLEnforcer</attribute>
+ <attribute name="DefaultPolicy">
+ <![CDATA[
+ <policy>
+ <!-- permissions on the root cms node -->
+ <criteria name="path" value="/">
+ <permission name="cms" action="read">
+ <role name="Anonymous"/>
+ </permission>
+ <permission name="cms" action="write">
+ <role name="User"/>
+ </permission>
+ <permission name="cms" action="manage">
+ <role name="Admin"/>
+ </permission>
+ </criteria>
+ <!-- permissions on the default cms node -->
+ <criteria name="path" value="/default">
+ <permission name="cms" action="read">
+ <role name="Anonymous"/>
+ </permission>
+ <permission name="cms" action="write">
+ <role name="User"/>
+ </permission>
+ <permission name="cms" action="manage">
+ <role name="Admin"/>
+ </permission>
+ </criteria>
+ <!-- permissions on the private/protected node -->
+ <criteria name="path" value="/default/private">
+ <permission name="cms" action="manage">
+ <role name="Admin"/>
+ </permission>
+ </criteria>
+ </policy>
+ ]]>
+ </attribute>
+ <depends optional-attribute-name="RoleModule"
proxy-type="attribute">
+ portal:service=Module,type=Role
+ </depends>
+ </mbean>
+
+ <!-- logging interceptor -->
+ <!--mbean
+ code="org.jboss.portal.cms.impl.interceptors.LogInterceptor"
+ name="portal:service=Interceptor,type=Cms,name=Log"
+ xmbean-dd=""
+ xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
+ <xmbean/>
+ </mbean-->
+
+ <!--
+ <mbean
+ code="org.jboss.portal.cms.impl.interceptors.CacheInterceptor"
+ name="portal:service=Interceptor,type=Cms,name=Cache"
+ xmbean-dd=""
+ xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
+ <xmbean/>
+ <depends>portal:service=CMSTreeCacheService</depends>
+ </mbean>
+ //this is not needed anymore. this cache is redundant since there is a JBossCache PM
+ <mbean
+ code="org.jboss.portal.cms.impl.cache.CMSTreeCacheServiceImpl"
+ name="portal:service=CMSTreeCacheService"
+ xmbean-dd=""
+ xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
+ <xmbean/>
+ <depends optional-attribute-name="Cache"
proxy-type="attribute">
+ <mbean
+ code="org.jboss.cache.TreeCache"
+ name="portal:service=CMSTreeCache">
+ <depends>jboss:service=Naming</depends>
+ <depends>jboss:service=TransactionManager</depends>
+ <attribute
name="TransactionManagerLookupClass">org.jboss.cache.JBossTransactionManagerLookup</attribute>
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+ <attribute name="IsolationLevel">NONE</attribute>
+ </mbean>
+ </depends>
+ <attribute
name="JNDIName">java:/portal/cms/CMSTreeCache</attribute>
+ </mbean>
+ -->
<!--
| Uncomment in clustered mode : TreeCache configuration for the clustered
JackRabbit in-memory cache...
| This helps with node synching, but there are other aspects of JackRabbit like
versioning subsystem
@@ -498,55 +598,4 @@
<attribute
name="UseRegionBasedMarshalling">false</attribute>
</mbean-->
-
-
- <!--mbean
- code="org.jboss.portal.cms.impl.interceptors.LogInterceptor"
- name="portal:service=Interceptor,type=Cms,name=Log"
- xmbean-dd=""
- xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
- <xmbean/>
- </mbean-->
-
- <!--
- //this is not needed anymore. this cache is redundant since there is a JBossCache
PM
- <mbean
- code="org.jboss.portal.cms.impl.cache.CMSTreeCacheServiceImpl"
- name="portal:service=CMSTreeCacheService"
- xmbean-dd=""
- xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
- <xmbean/>
- <depends optional-attribute-name="Cache"
proxy-type="attribute">
- <mbean
- code="org.jboss.cache.TreeCache"
- name="portal:service=CMSTreeCache">
- <depends>jboss:service=Naming</depends>
- <depends>jboss:service=TransactionManager</depends>
- <attribute
name="TransactionManagerLookupClass">org.jboss.cache.JBossTransactionManagerLookup</attribute>
- <attribute name="CacheMode">REPL_ASYNC</attribute>
- <attribute name="IsolationLevel">NONE</attribute>
- </mbean>
- </depends>
- <attribute
name="JNDIName">java:/portal/cms/CMSTreeCache</attribute>
- </mbean>
-
- <mbean
- code="org.jboss.portal.cms.impl.interceptors.CacheInterceptor"
- name="portal:service=Interceptor,type=Cms,name=Cache"
- xmbean-dd=""
- xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
- <xmbean/>
- <depends>portal:service=CMSTreeCacheService</depends>
- </mbean>
- <mbean
-
code="org.jboss.portal.server.impl.invocation.JBossInterceptorStackFactory"
- name="portal:service=InterceptorStackFactory,type=Cms"
- xmbean-dd=""
- xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
- <xmbean/>
- <depends-list optional-attribute-name="InterceptorNames">
-
<depends-list-element>portal:service=Interceptor,type=Cms,name=Cache</depends-list-element>
- </depends-list>
- </mbean>
- -->
</server>
Modified: trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/domain.hbm.xml
===================================================================
--- trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/domain.hbm.xml 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/domain.hbm.xml 2006-12-12
04:59:21 UTC (rev 5806)
@@ -274,5 +274,103 @@
type="long"
not-null="true"/>
</class>
+
+ <!-- mapping to persist CMS Fine Grained Security related objects -->
+ <class name="org.jboss.portal.cms.security.PermRoleAssoc"
table="jbp_cms_perm_role">
+ <cache usage="read-write"/>
+ <id
+ name="id"
+ column="ID"
+ type="java.lang.Long">
+ <generator class="native"/>
+ </id>
+ <property
+ name="roleId"
+ column="ROLE_ID"
+ type="long"
+ not-null="true"
+ />
+ </class>
+ <class name="org.jboss.portal.cms.security.PermUserAssoc"
table="jbp_cms_perm_user">
+ <cache usage="read-write"/>
+ <id
+ name="id"
+ column="ID"
+ type="java.lang.Long">
+ <generator class="native"/>
+ </id>
+ <property
+ name="userId"
+ column="USER_ID"
+ type="long"
+ not-null="true"
+ />
+ </class>
+ <class name="org.jboss.portal.cms.security.Criteria"
table="jbp_cms_perm_criteria">
+ <cache usage="read-write"/>
+ <id
+ name="id"
+ column="ID"
+ type="java.lang.Long">
+ <generator class="native"/>
+ </id>
+ <property
+ name="name"
+ column="NAME"
+ type="string"
+ not-null="true"
+ />
+ <property
+ name="value"
+ column="VALUE"
+ type="string"
+ not-null="true"
+ />
+ </class>
+ <class name="org.jboss.portal.cms.security.Permission"
table="jbp_cms_perm">
+ <cache usage="read-write"/>
+ <id
+ name="id"
+ column="ID"
+ type="java.lang.Long">
+ <generator class="native"/>
+ </id>
+ <!-- one-to-many association with the criteria object -->
+ <set name="criteria" lazy="false"
table="jbp_cms_perm_criteria" cascade="all-delete-orphan">
+ <cache usage="read-write"/>
+ <key column="CMS_PERM_ID"/>
+ <one-to-many class="org.jboss.portal.cms.security.Criteria"/>
+ </set>
+ <!-- many-to-many association with the role object -->
+ <set name="roleAssoc" lazy="false"
cascade="all-delete-orphan">
+ <cache usage="read-write"/>
+ <key column="CMS_PERM_ID"/>
+ <one-to-many
class="org.jboss.portal.cms.security.PermRoleAssoc"/>
+ </set>
+ <!-- many-to-many association with the user object -->
+ <set name="userAssoc" lazy="false"
cascade="all-delete-orphan">
+ <cache usage="read-write"/>
+ <key column="CMS_PERM_ID"/>
+ <one-to-many
class="org.jboss.portal.cms.security.PermUserAssoc"/>
+ </set>
+ <property
+ name="service"
+ column="NAME"
+ type="string"
+ not-null="true"
+ />
+ <property
+ name="action"
+ column="ACTION"
+ type="string"
+ not-null="true"
+ />
+ <property
+ name="negated"
+ column="NEGATED"
+ type="boolean"
+ not-null="true"
+ />
+ </class>
</hibernate-mapping>
Added: trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/ehcache.xml
===================================================================
--- trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/ehcache.xml 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/ehcache.xml 2006-12-12
04:59:21 UTC (rev 5806)
@@ -0,0 +1,61 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ JBoss, a division of Red Hat ~
+ ~ Copyright 2006, Red Hat Middleware, LLC, and individual ~
+ ~ contributors as indicated by the @authors tag. See the ~
+ ~ copyright.txt in the distribution for a full listing of ~
+ ~ individual contributors. ~
+ ~ ~
+ ~ This is free software; you can redistribute it and/or modify it ~
+ ~ under the terms of the GNU Lesser General Public License as ~
+ ~ published by the Free Software Foundation; either version 2.1 of ~
+ ~ the License, or (at your option) any later version. ~
+ ~ ~
+ ~ This software is distributed in the hope that it will be useful, ~
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of ~
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ~
+ ~ Lesser General Public License for more details. ~
+ ~ ~
+ ~ You should have received a copy of the GNU Lesser General Public ~
+ ~ License along with this software; if not, write to the Free ~
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ~
+ ~ 02110-1301 USA, or see the FSF site:
http://www.fsf.org. ~
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+
+<ehcache>
+
+ <!-- Sets the path to the directory where cache .data files are created.
+
+ If the path is a Java System Property it is replaced by
+ its value in the running VM.
+
+ The following properties are translated:
+ user.home - User's home directory
+ user.dir - User's current working directory
+ java.io.tmpdir - Default temp file path -->
+ <diskStore path="java.io.tmpdir/cms"/>
+
+
+ <!--Default Cache configuration. These will applied to caches programmatically
created through
+ the CacheManager.
+
+ The following attributes are required for defaultCache:
+
+ maxInMemory - Sets the maximum number of objects that will be created in memory
+ eternal - Sets whether elements are eternal. If eternal, timeouts are
ignored and the element
+ is never expired.
+ timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only
used
+ if the element is not eternal. Idle time is now - last accessed
time
+ timeToLiveSeconds - Sets the time to live for an element before it expires. Is only
used
+ if the element is not eternal. TTL is now - creation time
+ overflowToDisk - Sets whether elements can overflow to disk when the in-memory
cache
+ has reached the maxInMemory limit.
+
+ -->
+ <defaultCache
+ maxElementsInMemory="10000"
+ eternal="false"
+ timeToIdleSeconds="120"
+ timeToLiveSeconds="120"
+ overflowToDisk="false"
+ />
+</ehcache>
Modified: trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/hibernate.cfg.xml
===================================================================
---
trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/hibernate.cfg.xml 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/core/src/resources/portal-cms-sar/conf/hibernate/cms/hibernate.cfg.xml 2006-12-12
04:59:21 UTC (rev 5806)
@@ -28,18 +28,21 @@
<hibernate-configuration>
<session-factory>
<property
name="connection.datasource">java:@portal.datasource.name@</property>
- <property name="show_sql">@portal.sql.show(a)</property>
- <property
name="cache.use_second_level_cache">false</property>
- <property name="cache.use_query_cache">false</property>
+ <property name="show_sql">@portal.sql.show(a)</property>
+
+ <!-- caching properties -->
+ <property
name="cache.use_second_level_cache">true</property>
+ <property name="cache.use_query_cache">true</property>
+ <property
name="cache.provider_configuration_file_resource_path">conf/hibernate/cms/ehcache.xml</property>
+ <property
name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- managed environment transaction configuration -->
<property
name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<property
name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<!-- Force the dialect instead of using autodetection -->
- <!--
- <property
name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
- -->
+ <!--property
name="dialect">org.hibernate.dialect.PostgreSQLDialect</property-->
+ <!--property
name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property-->
<!-- Mapping files -->
<mapping resource="conf/hibernate/cms/domain.hbm.xml"/>
Modified: trunk/core/src/resources/portal-core-sar/conf/data/default-object.xml
===================================================================
--- trunk/core/src/resources/portal-core-sar/conf/data/default-object.xml 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/core/src/resources/portal-core-sar/conf/data/default-object.xml 2006-12-12
04:59:21 UTC (rev 5806)
@@ -406,7 +406,85 @@
<role-name>Admin</role-name>
<action-name>viewrecursive</action-name>
</policy-permission>
- </security-constraint>
+ </security-constraint>
</portal>
</deployment>
+
+
+ <!-- cms administration tool page with the fine grained access control integrated
-->
+ <deployment>
+ <parent-ref/>
+ <if-exists>keep</if-exists>
+ <portal>
+ <portal-name>cms</portal-name>
+ <properties>
+ <!--
+ | Set the layout for the default portal, see also portal-layouts.xml.
+ -->
+ <property>
+ <name>layout.id</name>
+ <value>generic</value>
+ </property>
+ <!--
+ | Set the theme for the default portal, see also portal-themes.xml.
+ -->
+ <property>
+ <name>theme.id</name>
+ <value>renaissance</value>
+ </property>
+ <!--
+ | Set the default render set name (used by the render tag in layouts), see
also portal-renderSet.xml
+ -->
+ <property>
+ <name>theme.renderSetId</name>
+ <value>divRenderer</value>
+ </property>
+ <!--
+ | Set the default strategy name (used by the strategy interceptor), see also
portal-strategies.xml
+ -->
+ <property>
+ <name>layout.strategyId</name>
+ <value>maximizedRegion</value>
+ </property>
+ <!--
+ | The default page name, if the property is not explicited then the default
page name is "default"
+ -->
+ <property>
+ <name>portal.defaultObjectName</name>
+ <value>default</value>
+ </property>
+ </properties>
+ <supported-modes>
+ <mode>view</mode>
+ <mode>edit</mode>
+ <mode>help</mode>
+ </supported-modes>
+ <supported-window-states>
+ <window-state>normal</window-state>
+ <window-state>minimized</window-state>
+ <window-state>maximized</window-state>
+ </supported-window-states>
+ <page>
+ <page-name>default</page-name>
+ <window>
+ <window-name>CMSAdminPortletWindow</window-name>
+ <instance-ref>CMSAdminPortletInstance</instance-ref>
+ <region>center</region>
+ <height>0</height>
+ </window>
+ <window>
+ <window-name>JSPPortletWindow</window-name>
+ <instance-ref>JSPPortletInstance</instance-ref>
+ <region>left</region>
+ <height>0</height>
+ </window>
+ <window>
+ <window-name>UserPortletWindow</window-name>
+ <instance-ref>UserPortletInstance</instance-ref>
+ <region>left</region>
+ <height>1</height>
+ </window>
+ </page>
+ </portal>
+ </deployment>
</deployments>
Modified: trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/main.jsp
===================================================================
--- trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/main.jsp 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/main.jsp 2006-12-12
04:59:21 UTC (rev 5806)
@@ -92,6 +92,7 @@
<li><a href="<portlet:renderURL>
<portlet:param name="op" value="<%=
CMSAdminConstants.OP_CONFIRMSECURE %>"/>
<portlet:param name="path" value="<%= sCurrPath %>"/>
+ <portlet:param name="returnOp" value="<%=
CMSAdminConstants.OP_MAIN %>"/>
</portlet:renderURL>">${n:i18n("CMS_SECURE")}</a></li>
<%
if (!"/".equals(sCurrPath))
Modified: trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/securenode.jsp
===================================================================
---
trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/securenode.jsp 2006-12-12
01:24:50 UTC (rev 5805)
+++
trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/securenode.jsp 2006-12-12
04:59:21 UTC (rev 5806)
@@ -15,11 +15,20 @@
Set roleSet = (Set)request.getAttribute("roles");
Set userSet = (Set)request.getAttribute("users");
String sConfirm = (String)request.getAttribute("confirm");
+ String returnOp = (String)request.getAttribute("returnOp");
+
+ Set readRoleSet = (Set)request.getAttribute("readRoleSet");
+ Set readUserSet = (Set)request.getAttribute("readUserSet");
+ Set writeRoleSet = (Set)request.getAttribute("writeRoleSet");
+ Set writeUserSet = (Set)request.getAttribute("writeUserSet");
+ Set manageRoleSet = (Set)request.getAttribute("manageRoleSet");
+ Set manageUserSet = (Set)request.getAttribute("manageUserSet");
%>
<form action="<portlet:actionURL>
<portlet:param name="op" value="<%= CMSAdminConstants.OP_SECURE
%>"/>
<portlet:param name="path" value="<%= sCurrPath %>"/>
+ <portlet:param name="returnOp" value="<%= returnOp
%>"/>
</portlet:actionURL>" method="post">
<table width="100%">
<th colspan="2" align="center"
class="portlet-section-header">${n:i18n("TITLE_SECURECONFIRM")}</th>
@@ -53,15 +62,18 @@
</tr>
<tr>
<td>
- <select name="secureroles" multiple="multiple">
- <option value="Anonymous">Anonymous</option>
+ <select name="secureroles:read"
multiple="multiple">
+ <option value="0" <%if(readRoleSet.contains(new
Long(0))){%>selected<%}%>>
+ Anonymous
+ </option>
<%
Iterator iterator = roleSet.iterator();
while (iterator.hasNext())
{
Role role = (Role)iterator.next();
%>
- <option value="<%= role.getId() %>"><%=
role.getDisplayName() %>
+ <option value="<%= role.getId() %>"
<%if(readRoleSet.contains(role.getId())){%>selected<%}%>>
+ <%= role.getDisplayName() %>
</option>
<%
}
@@ -77,14 +89,15 @@
</tr>
<tr>
<td>
- <select name="secureusers" multiple="multiple">
+ <select name="secureusers:read"
multiple="multiple">
<%
Iterator iteratorUser = userSet.iterator();
while (iteratorUser.hasNext())
{
User user = (User)iteratorUser.next();
%>
- <option value="<%= user.getId() %>"><%=
user.getUserName() %>
+ <option value="<%= user.getId() %>"
<%if(readUserSet.contains(user.getId())){%>selected<%}%>>
+ <%= user.getUserName() %>
</option>
<%
}
@@ -109,15 +122,18 @@
</tr>
<tr>
<td>
- <select name="secureroles" multiple="multiple">
- <option value="Anonymous">Anonymous</option>
+ <select name="secureroles:write"
multiple="multiple">
+ <option value="0" <%if(writeRoleSet.contains(new
Long(0))){%>selected<%}%>>
+ Anonymous
+ </option>
<%
iterator = roleSet.iterator();
while (iterator.hasNext())
{
Role role = (Role)iterator.next();
%>
- <option value="<%= role.getId() %>"><%=
role.getDisplayName() %>
+ <option value="<%= role.getId() %>"
<%if(writeRoleSet.contains(role.getId())){%>selected<%}%>>
+ <%= role.getDisplayName() %>
</option>
<%
}
@@ -133,14 +149,15 @@
</tr>
<tr>
<td>
- <select name="secureusers" multiple="multiple">
+ <select name="secureusers:write"
multiple="multiple">
<%
iteratorUser = userSet.iterator();
while (iteratorUser.hasNext())
{
User user = (User)iteratorUser.next();
%>
- <option value="<%= user.getId() %>"><%=
user.getUserName() %>
+ <option value="<%= user.getId() %>"
<%if(writeUserSet.contains(user.getId())){%>selected<%}%>>
+ <%= user.getUserName() %>
</option>
<%
}
@@ -165,15 +182,18 @@
</tr>
<tr>
<td>
- <select name="secureroles" multiple="multiple">
- <option value="Anonymous">Anonymous</option>
+ <select name="secureroles:manage"
multiple="multiple">
+ <option value="0" <%if(manageRoleSet.contains(new
Long(0))){%>selected<%}%>>
+ Anonymous
+ </option>
<%
iterator = roleSet.iterator();
while (iterator.hasNext())
{
Role role = (Role)iterator.next();
%>
- <option value="<%= role.getId() %>"><%=
role.getDisplayName() %>
+ <option value="<%= role.getId() %>"
<%if(manageRoleSet.contains(role.getId())){%>selected<%}%>>
+ <%= role.getDisplayName() %>
</option>
<%
}
@@ -189,14 +209,15 @@
</tr>
<tr>
<td>
- <select name="secureusers" multiple="multiple">
+ <select name="secureusers:manage"
multiple="multiple">
<%
iteratorUser = userSet.iterator();
while (iteratorUser.hasNext())
{
User user = (User)iteratorUser.next();
%>
- <option value="<%= user.getId() %>"><%=
user.getUserName() %>
+ <option value="<%= user.getId() %>"
<%if(manageUserSet.contains(user.getId())){%>selected<%}%>>
+ <%= user.getUserName() %>
</option>
<%
}
@@ -221,7 +242,7 @@
</form>
<a href="<portlet:renderURL>
- <portlet:param name="op" value="<%=
CMSAdminConstants.OP_MAIN %>"/>
+ <portlet:param name="op" value="<%= returnOp
%>"/>
<portlet:param name="path"
value="<%= sCurrPath %>"/>
</portlet:renderURL>">
Modified: trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/viewfile.jsp
===================================================================
--- trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/viewfile.jsp 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/core/src/resources/portal-core-war/WEB-INF/jsp/cms/admin/viewfile.jsp 2006-12-12
04:59:21 UTC (rev 5806)
@@ -118,6 +118,7 @@
<li><a href="<portlet:renderURL>
<portlet:param name="op" value="<%=
CMSAdminConstants.OP_CONFIRMSECURE %>"/>
<portlet:param name="path" value="<%= sCurrPath %>"/>
+ <portlet:param name="returnOp" value="<%=
CMSAdminConstants.OP_VIEWFILE %>"/>
</portlet:renderURL>">${n:i18n("CMS_SECURE")}</a></li>
</ul>
</li>
Modified: trunk/core/src/resources/portal-core-war/WEB-INF/portlet-instances.xml
===================================================================
--- trunk/core/src/resources/portal-core-war/WEB-INF/portlet-instances.xml 2006-12-12
01:24:50 UTC (rev 5805)
+++ trunk/core/src/resources/portal-core-war/WEB-INF/portlet-instances.xml 2006-12-12
04:59:21 UTC (rev 5806)
@@ -51,12 +51,14 @@
<instance>
<instance-id>CMSAdminPortletInstance</instance-id>
<portlet-ref>CMSAdminPortlet</portlet-ref>
- <security-constraint>
+
+ <!--security-constraint>
<policy-permission>
<role-name>Admin</role-name>
<action-name>view</action-name>
</policy-permission>
- </security-constraint>
+ </security-constraint-->
+
</instance>
</deployment>
<deployment>