You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by ta...@apache.org on 2006/06/20 09:09:39 UTC

svn commit: r415531 - in /portals/jetspeed-2/trunk: applications/j2-admin/src/java/org/apache/jetspeed/portlets/security/permissions/ components/portal/src/java/org/apache/jetspeed/layout/ajax-xml/ components/portal/src/java/org/apache/jetspeed/layout/...

Author: taylor
Date: Tue Jun 20 00:09:37 2006
New Revision: 415531

URL: http://svn.apache.org/viewvc?rev=415531&view=rev
Log:
* new PermissionManager API for updating a set of new granted/revoked roles
  useful for less chatter on UI updates

* unit tests for PermissionManager new API 

* "permissions" AJAX API implemented

* updated AJAX API docs with latest APIs 

Added:
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/ajax-xml/permissions.vm
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/RolesSecurityBehavior.java
    portals/jetspeed-2/trunk/docs/release/JETSPEED-2.1-TODO.txt
Modified:
    portals/jetspeed-2/trunk/applications/j2-admin/src/java/org/apache/jetspeed/portlets/security/permissions/SecurityPermissionsPortlet.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/ChangePortletAction.java
    portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/SecurityPermissionAction.java
    portals/jetspeed-2/trunk/components/security/maven.xml
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java
    portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestPermissionManager.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/PermissionManager.java
    portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/ajax-layout.xml
    portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-managers.xml
    portals/jetspeed-2/trunk/xdocs/guides/guide-ajax-api.xml

Modified: portals/jetspeed-2/trunk/applications/j2-admin/src/java/org/apache/jetspeed/portlets/security/permissions/SecurityPermissionsPortlet.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/applications/j2-admin/src/java/org/apache/jetspeed/portlets/security/permissions/SecurityPermissionsPortlet.java?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/applications/j2-admin/src/java/org/apache/jetspeed/portlets/security/permissions/SecurityPermissionsPortlet.java (original)
+++ portals/jetspeed-2/trunk/applications/j2-admin/src/java/org/apache/jetspeed/portlets/security/permissions/SecurityPermissionsPortlet.java Tue Jun 20 00:09:37 2006
@@ -16,10 +16,10 @@
 package org.apache.jetspeed.portlets.security.permissions;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.ArrayList;
 
 import javax.portlet.ActionRequest;
 import javax.portlet.ActionResponse;
@@ -117,7 +117,7 @@
             List folders = new LinkedList();
             List pages = new LinkedList();
             List portlets = new LinkedList();
-            Iterator all = pm.getPermissions();
+            Iterator all = pm.getPermissions().iterator();
             while (all.hasNext())
             {
                 InternalPermission permission = (InternalPermission)all.next();                

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/ajax-xml/permissions.vm
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/ajax-xml/permissions.vm?rev=415531&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/ajax-xml/permissions.vm (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/ajax-xml/permissions.vm Tue Jun 20 00:09:37 2006
@@ -0,0 +1,8 @@
+<js>
+    <status>$status</status>
+    <action>$action</action>
+    <resource>$resource</resource> 
+    <type>$type</type> 
+    <actions>$actions</actions>
+    <actions>$roles</actions>    
+</js>
\ No newline at end of file

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/ChangePortletAction.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/ChangePortletAction.java?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/ChangePortletAction.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/ChangePortletAction.java Tue Jun 20 00:09:37 2006
@@ -32,18 +32,14 @@
 import org.apache.jetspeed.request.RequestContext;
 
 /**
- * Move Portlet portlet placement action
+ * Changes the window state or portlet mode for a given portlet window
  *
  * AJAX Parameters: 
  *    id = the fragment id of the portlet to move
  *    page = (implied in the URL)
- * Additional Absolute Parameters:  
- *    row = the new row to move to
- *    col = the new column to move to
- * Additional Relative Parameters: (move left, right, up, down)
- *    none
+ *    state = the new window state
+ *    mode = the new portlet mode
  *    
- * @author <a>David Gurney</a>
  * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
  * @version $Id: $
  */

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/RolesSecurityBehavior.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/RolesSecurityBehavior.java?rev=415531&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/RolesSecurityBehavior.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/RolesSecurityBehavior.java Tue Jun 20 00:09:37 2006
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.layout.impl;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.layout.PortletActionSecurityBehavior;
+import org.apache.jetspeed.request.RequestContext;
+
+/**
+ * Abstracted behavior of security checks for portlet actions
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: $
+ */
+public class RolesSecurityBehavior implements PortletActionSecurityBehavior
+{
+    protected Log log = LogFactory.getLog(PortletActionSecurityPathBehavior.class);    
+    protected List roles;
+    
+    public RolesSecurityBehavior(List roles)
+    {
+        this.roles = roles;
+    }
+
+    public boolean checkAccess(RequestContext context, String action)
+    {
+        Iterator iterator = roles.iterator();
+        while (iterator.hasNext())
+        {
+            String role = (String)iterator.next();
+            if (context.getRequest().isUserInRole(role))
+                return true;
+        }        
+        return false;
+    }
+
+    public boolean createNewPageOnEdit(RequestContext context)
+    {
+        return false;
+    }
+}

Modified: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/SecurityPermissionAction.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/SecurityPermissionAction.java?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/SecurityPermissionAction.java (original)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/layout/impl/SecurityPermissionAction.java Tue Jun 20 00:09:37 2006
@@ -15,7 +15,13 @@
  */
 package org.apache.jetspeed.layout.impl;
 
+import java.lang.reflect.Constructor;
+import java.security.Permission;
+import java.security.Principal;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
+import java.util.StringTokenizer;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -23,26 +29,23 @@
 import org.apache.jetspeed.ajax.AJAXException;
 import org.apache.jetspeed.ajax.AjaxAction;
 import org.apache.jetspeed.ajax.AjaxBuilder;
-import org.apache.jetspeed.layout.Coordinate;
 import org.apache.jetspeed.layout.PortletActionSecurityBehavior;
-import org.apache.jetspeed.layout.PortletPlacementContext;
-import org.apache.jetspeed.om.page.Fragment;
-import org.apache.jetspeed.om.page.Page;
 import org.apache.jetspeed.request.RequestContext;
 import org.apache.jetspeed.security.PermissionManager;
+import org.apache.jetspeed.security.SecurityException;
+import org.apache.jetspeed.security.impl.RolePrincipalImpl;
 
 /**
  * Security Permission action
  * 
  * AJAX Parameters: 
  *    action = permission
- *    sub = add | remove | grant | revoke 
- *    page = (implied in the URL)
+ *    method = add | update | delete 
  *    resource = name of the resource to modify
- *    actions = comma-separated actions
  *    type = portlet | page | folder
- * Parameters for grant | revoke:  
- *    role = name of  role to grant or revoke
+ *    roles = comma separated list of roles
+ *    actions = comma separated list of actions
+ *    oldactions = comma separated list of old actions
  *    
  * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
  * @version $Id: $
@@ -53,14 +56,17 @@
 {
     protected Log log = LogFactory.getLog(SecurityPermissionAction.class);
     protected PermissionManager pm = null;
+    protected Map permissionMap = null;
 
     public SecurityPermissionAction(String template, 
                             String errorTemplate, 
                             PermissionManager pm,
-                            PortletActionSecurityBehavior securityBehavior)
+                            PortletActionSecurityBehavior securityBehavior,
+                            Map permissionMap)
     {
         super(template, errorTemplate, securityBehavior); 
         this.pm = pm;
+        this.permissionMap = permissionMap;
     }
     
     public boolean run(RequestContext requestContext, Map resultMap)
@@ -72,35 +78,195 @@
         {
             resultMap.put(ACTION, "permissions");
             // Get the necessary parameters off of the request
-            String sub = requestContext.getRequestParameter("sub");
-            if (sub == null) 
+            String method = requestContext.getRequestParameter("method");
+            if (method == null) 
             { 
-                throw new RuntimeException("Sub Action not provided"); 
+                throw new RuntimeException("Method not provided"); 
             }            
-            resultMap.put("sub", sub);
+            resultMap.put("method", method);
             if (false == checkAccess(requestContext, JetspeedActions.EDIT))
             {
-                if (!createNewPageOnEdit(requestContext))
-                {
-                    success = false;
-                    resultMap.put(REASON, "Insufficient access to edit page");                
-                    return success;
-                }
-                status = "refresh";
+                success = false;
+                resultMap.put(REASON, "Insufficient access to administer portal permissions");                
+                return success;
             }           
+            int count = 0;
+            if (method.equals("add"))
+            {
+                count = addPermission(requestContext, resultMap);
+            }
+            else if (method.equals("update"))
+            {
+                count = updatePermission(requestContext, resultMap);
+            }            
+            else if (method.equals("remove"))
+            {
+                count = removePermission(requestContext, resultMap);
+            }
+            else
+            {
+                success = false;
+                resultMap.put(REASON, "Unsupported portal permissions method: " + method);                
+                return success;                
+            }
+            resultMap.put("count", Integer.toString(count));
+            resultMap.put("resource", requestContext.getRequestParameter("resource"));
+            resultMap.put("type", requestContext.getRequestParameter("type"));
+            resultMap.put("actions", requestContext.getRequestParameter("actions"));
+            resultMap.put("roles", requestContext.getRequestParameter("roles"));
             resultMap.put(STATUS, status);
         } 
         catch (Exception e)
         {
-            // Log the exception
-            log.error("exception while adding a portlet", e);
+            log.error("exception administering portal permissions", e);
             resultMap.put(REASON, e.toString());
-
-            // Return a failure indicator
             success = false;
         }
-
         return success;
+    }
+    
+    protected int addPermission(RequestContext requestContext, Map resultMap)
+    throws AJAXException
+    {
+        try
+        {
+            String type = requestContext.getRequestParameter("type");
+            if (type == null)
+                throw new AJAXException("Missing 'type' parameter");
+            String resource = requestContext.getRequestParameter("resource");
+            if (resource == null)
+                throw new AJAXException("Missing 'resource' parameter");
+            String actions = requestContext.getRequestParameter("actions");
+            if (actions == null)
+                throw new AJAXException("Missing 'actions' parameter");
+            
+            Permission permission = createPermissionFromClass(type, resource, actions);            
+            if (pm.permissionExists(permission))
+            {
+                throw new AJAXException("Permission " + resource + " already exists");
+            }   
+            
+            pm.addPermission(permission);            
+            String roleNames = requestContext.getRequestParameter("roles");
+            return updateRoles(permission, roleNames);
+        }
+        catch (SecurityException e)
+        {
+            throw new AJAXException(e.toString(), e);
+        }        
+    }
+
+    protected int updatePermission(RequestContext requestContext, Map resultMap)
+    throws AJAXException
+    {
+        try
+        {
+            String type = requestContext.getRequestParameter("type");
+            if (type == null)
+                throw new AJAXException("Missing 'type' parameter");
+            String resource = requestContext.getRequestParameter("resource");
+            if (resource == null)
+                throw new AJAXException("Missing 'resource' parameter");
+            String actions = requestContext.getRequestParameter("actions");
+            if (actions == null)
+                throw new AJAXException("Missing 'actions' parameter");
+            String oldActions = requestContext.getRequestParameter("oldactions");
+            if (oldActions == null)
+            {
+                // assume no change
+                oldActions = actions;
+            }
+            Permission permission = null;
+            if (!oldActions.equals(actions))
+            {
+                permission = createPermissionFromClass(type, resource, oldActions);
+                pm.removePermission(permission);
+                permission = createPermissionFromClass(type, resource, actions);
+                pm.addPermission(permission);
+            }   
+            else
+            {
+                permission = createPermissionFromClass(type, resource, actions);
+            }
+            String roleNames = requestContext.getRequestParameter("roles");
+            return updateRoles(permission, roleNames);
+        }
+        catch (SecurityException e)
+        {
+            throw new AJAXException(e.toString(), e);
+        }        
+    }
+    
+    protected int updateRoles(Permission permission, String roleNames)
+    throws SecurityException
+    {
+        List principals = new LinkedList();
+        if (roleNames != null)
+        {
+            StringTokenizer toke = new StringTokenizer(roleNames, ",");
+            while (toke.hasMoreTokens())
+            {
+                String roleName = (String)toke.nextToken();
+                Principal role = new RolePrincipalImpl(roleName);
+                principals.add(role);
+            }                
+        }
+        return pm.updatePermission(permission, principals);                    
+    }
+
+    protected int removePermission(RequestContext requestContext, Map resultMap)
+    throws AJAXException
+    {
+        try
+        {
+            String type = requestContext.getRequestParameter("type");
+            if (type == null)
+                throw new AJAXException("Missing 'type' parameter");
+            String resource = requestContext.getRequestParameter("resource");
+            if (resource == null)
+                throw new AJAXException("Missing 'resource' parameter");
+            String actions = requestContext.getRequestParameter("actions");
+            if (actions == null)
+                throw new AJAXException("Missing 'actions' parameter");            
+            Permission permission = createPermissionFromClass(type, resource, actions);            
+            if (pm.permissionExists(permission))
+            {
+                pm.removePermission(permission);
+                return 1;
+            }
+            return 0;
+        }
+        catch (SecurityException e)
+        {
+            throw new AJAXException(e.toString(), e);
+        }
+    }
+    
+    protected String mapTypeToClassname(String type)
+    throws AJAXException
+    {
+        String classname = (String)this.permissionMap.get(type);
+        if (classname != null)
+            return classname;
+        throw new AJAXException("Bad resource 'type' parameter: " + type);            
+    }
+    
+    protected Permission createPermissionFromClass(String type, String resource, String actions)
+    throws AJAXException
+    {        
+        String classname = this.mapTypeToClassname(type);
+        try
+        {
+            Class permissionClass = Class.forName(classname);
+            Class[] parameterTypes = { String.class, String.class };
+            Constructor permissionConstructor = permissionClass.getConstructor(parameterTypes);
+            Object[] initArgs = { resource, actions };
+            return (Permission)permissionConstructor.newInstance(initArgs);
+        }
+        catch (Exception e)
+        {
+            throw new AJAXException("Failed to create permission: " + type, e);
+        }
     }
     
 }

Modified: portals/jetspeed-2/trunk/components/security/maven.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/maven.xml?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/maven.xml (original)
+++ portals/jetspeed-2/trunk/components/security/maven.xml Tue Jun 20 00:09:37 2006
@@ -17,6 +17,7 @@
 <project default="java:jar" xmlns:j="jelly:core" xmlns:define="jelly:define" xmlns:maven="jelly:maven">
 
     <!-- Target of maven test:single test -->
-    <property name="testcase" value="org.apache.jetspeed.security.spi.ldap.TestLdapUserSecurityHandler" />
-    
+<!--    <property name="testcase" value="org.apache.jetspeed.security.spi.ldap.TestLdapUserSecurityHandler" /> -->
+       <property name="testcase" value="org.apache.jetspeed.security.TestPermissionManager" />    
+
 </project>

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java Tue Jun 20 00:09:37 2006
@@ -262,4 +262,26 @@
             log.debug("No permissions to add...");
         }
     }
+    
+    public static Principal createPrincipalFromFullPath(String fullPath)
+    {
+        Principal principal = null;
+        if (fullPath.startsWith(BasePrincipal.PREFS_ROLE_ROOT))
+        {
+            String name = RolePrincipalImpl.getPrincipalNameFromFullPath(fullPath);            
+            principal = new RolePrincipalImpl(name);
+        }
+        else if (fullPath.startsWith(BasePrincipal.PREFS_USER_ROOT))
+        {
+            String name = UserPrincipalImpl.getPrincipalNameFromFullPath(fullPath);
+            principal = new UserPrincipalImpl(name);
+        }
+        else if (fullPath.startsWith(BasePrincipal.PREFS_GROUP_ROOT))
+        {
+            String name = GroupPrincipalImpl.getPrincipalNameFromFullPath(fullPath);            
+            principal = new GroupPrincipalImpl(name);
+            
+        }
+        return principal;
+    }
 }

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java Tue Jun 20 00:09:37 2006
@@ -26,6 +26,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedList;
 
 import javax.security.auth.Subject;
 
@@ -520,21 +521,93 @@
         return true;         
     }
     
-    public Iterator getPermissions()
+    public Collection getPermissions()
     {
         QueryByCriteria query = QueryFactory.newQuery(InternalPermissionImpl.class, new Criteria());
         query.addOrderByAscending("classname");
         query.addOrderByAscending("name");
-        return getPersistenceBrokerTemplate().getCollectionByQuery(query).iterator();        
+        Collection internalPermissions = getPersistenceBrokerTemplate().getCollectionByQuery(query);
+        return internalPermissions;
     }
-
-    public Iterator getPermissions(String classname, String resource)
+    
+    public Permissions getPermissions(String classname, String resource)
     {
         Criteria filter = new Criteria();
         filter.addEqualTo("classname", classname);
         filter.addEqualTo("name", resource);
         Query query = QueryFactory.newQuery(InternalPermissionImpl.class, filter);
-        return getPersistenceBrokerTemplate().getCollectionByQuery(query).iterator();                
+        Collection internalPermissions = getPersistenceBrokerTemplate().getCollectionByQuery(query);        
+        Permissions permissions = new Permissions();
+        Iterator iter = internalPermissions.iterator();
+        try
+        {
+            while (iter.hasNext())
+            {
+                InternalPermission internalPermission = (InternalPermission)iter.next();
+                Class permissionClass = Class.forName(internalPermission.getClassname());
+                Class[] parameterTypes = { String.class, String.class };
+                Constructor permissionConstructor = permissionClass.getConstructor(parameterTypes);
+                Object[] initArgs = { internalPermission.getName(), internalPermission.getActions() };
+                Permission permission = (Permission) permissionConstructor.newInstance(initArgs);            
+                permissions.add(permission);
+            }
+        }
+        catch (Exception e)
+        {
+            logger.error("Failed to retrieve permissions", e);            
+        }
+        return permissions;        
     }    
+    
+    public int updatePermission(Permission permission, Collection principals)
+    throws SecurityException
+    {
+        int count = 0;
+        InternalPermission internal = getInternalPermission(permission);
+        Iterator iter = principals.iterator();
+        Collection newPrincipals = new LinkedList();
+        while (iter.hasNext())
+        {
+            Principal principal = (Principal)iter.next();
+            String fullPath = SecurityHelper.getPreferencesFullPath(principal);
+            InternalPrincipal internalPrincipal = getInternalPrincipal(fullPath);
+            newPrincipals.add(internalPrincipal);            
+        }
+        internal.setPrincipals(newPrincipals);
+        internal.setModifiedDate(new Timestamp(System.currentTimeMillis()));
+        try
+        {            
+            getPersistenceBrokerTemplate().store(internal);            
+        }
+        catch (Exception e)
+        {
+            KeyedMessage msg = SecurityException.UNEXPECTED.create("PermissionManager.updatePermission",
+                                                                   "store", e.getMessage());
+            logger.error(msg, e);            
+            throw new SecurityException(msg, e);
+        }
+
+        return count;
+    }
+    
+    public Collection getPrincipals(Permission permission)
+    {
+        Collection result = new LinkedList();        
+        InternalPermission internalPermission = this.getInternalPermission(permission);
+        if (internalPermission == null)
+        {
+            return result;
+        }
+        Iterator principals = internalPermission.getPrincipals().iterator();
+        while (principals.hasNext())
+        {
+            InternalPrincipal internalPrincipal = (InternalPrincipal)principals.next();            
+            Principal principal = 
+                SecurityHelper.createPrincipalFromFullPath(internalPrincipal.getFullPath());
+            result.add(principal);
+        }
+        return  result;
+    }
+    
     
 }

Modified: portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestPermissionManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestPermissionManager.java?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestPermissionManager.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestPermissionManager.java Tue Jun 20 00:09:37 2006
@@ -17,11 +17,14 @@
 import java.security.AccessControlException;
 import java.security.Permission;
 import java.security.Permissions;
+import java.security.Principal;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.Vector;
 
 import javax.security.auth.Subject;
 
@@ -739,4 +742,80 @@
             assertTrue("could not remove permissions. exception caught: " + sex, false);
         }
     }
+    
+    public void testUpdatePermission()
+    {
+        // Init test.
+        RolePrincipal role1 = new RolePrincipalImpl("role1");
+        RolePrincipal role2 = new RolePrincipalImpl("role2");
+        RolePrincipal role3 = new RolePrincipalImpl("role3");
+        RolePrincipal role4 = new RolePrincipalImpl("role4");
+        PortletPermission perm1 = new PortletPermission("testportlet", "view");
+        try
+        {
+            rms.addRole(role1.getName());
+            rms.addRole(role2.getName());
+            rms.addRole(role3.getName());
+            rms.addRole(role4.getName());            
+            pms.addPermission(perm1);
+        }
+        catch (SecurityException sex)
+        {
+            assertTrue("failed to init testUpdatePermission(), " + sex, false);
+        }
+
+        // Grant 1 and 2      
+        try
+        {
+            pms.grantPermission(role1, perm1);
+            pms.grantPermission(role2, perm1);
+        }
+        catch (SecurityException sex)
+        {
+            assertTrue("failed to grant on testUpdatePermission. caught exception, " + sex, false);
+        }
+
+        Collection principals = pms.getPrincipals(perm1);        
+        assertTrue("principal count should be 2 ", principals.size() == 2);        
+        Object [] array = (Object[])principals.toArray();
+        assertTrue("element is Principal ", array[0] instanceof Principal);
+        assertTrue("first element not found ", ((Principal)array[0]).getName().equals("role1"));
+        assertTrue("second element not found ", ((Principal)array[1]).getName().equals("role2"));
+        
+        
+        // Try to update collection
+        try
+        {
+            Collection roles = new Vector();
+            roles.add(role1);
+            roles.add(role3);
+            roles.add(role4);
+            pms.updatePermission(perm1, roles);
+        }
+        catch (SecurityException sex)
+        {
+            assertTrue("principal does not exist. caught exception, " + sex, false);
+        }
+        principals = pms.getPrincipals(perm1);
+        assertTrue("principal count should be 3 ", principals.size() == 3);
+        array = (Object[])principals.toArray();
+        assertTrue("first element not found ", ((Principal)array[0]).getName().equals("role1"));
+        assertTrue("second element not found ", ((Principal)array[1]).getName().equals("role3"));
+        assertTrue("third element not found ", ((Principal)array[2]).getName().equals("role4"));
+        
+        // Cleanup test.
+        try
+        {
+            rms.removeRole(role1.getName());
+            rms.removeRole(role2.getName());
+            rms.removeRole(role3.getName());
+            rms.removeRole(role4.getName());
+            pms.removePermission(perm1);
+        }
+        catch (SecurityException sex)
+        {
+            assertTrue("could not remove user and permission. exception caught: " + sex, false);
+        }
+    }
+    
 }

Added: portals/jetspeed-2/trunk/docs/release/JETSPEED-2.1-TODO.txt
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/docs/release/JETSPEED-2.1-TODO.txt?rev=415531&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/docs/release/JETSPEED-2.1-TODO.txt (added)
+++ portals/jetspeed-2/trunk/docs/release/JETSPEED-2.1-TODO.txt Tue Jun 20 00:09:37 2006
@@ -0,0 +1,73 @@
+
+ 0. Jetspeed Desktop                                                      
+      a. Portlet Selector                             
+      b. Windows States                               
+
+ 1. XML Serialization                                 
+      a. Replace SQL seed scripts with XML            
+
+ 2. Cluster Support                                                       
+       a. Registry
+       b. PSML
+
+ 3. Customizer - Redesign
+       a. DOJO based, build into desktop
+       b. access DOJO customizer from non-desktop  
+       c. Security Permissions Editor
+       d. Security Constraints Editor
+       e. integrate site manager with new customizer
+
+ 4. Improve Admin with DOJO or JSF...
+      a. Site Manager                        
+      b. Profiler (write docs)               
+      c. Roles, Groups               
+
+ 5. Major Bug/Featurs
+      a. JS2-499 Prefs per User     
+         Refactor Prefs, fix PrefsPreferenes mess                                  
+      b. JS2-517 Secure XML AJAX Requests       
+      c. Redeploy Failing on Tomcat      
+
+ 6. Graffito Integration
+
+ 7. Performance
+      a. Portlet Selector
+      b. Roles, Groups
+      c. Permission Checks
+
+ 8. App Server Support
+      a. Jetty Support
+      b. WAS
+      c. WAS CE
+
+ 9. Jetspeed Lite
+      a. replace OJB with Serialized
+      b. minimal security
+      c. internal portlet app, single WAR deployment
+      d. simpler security model
+  
+10. Build and Configurations
+      a. move to Maven-2, drop M1
+      b. various configurations, lite
+
+11. Demo Sites
+      a. improve JSF and Facelets support
+      b. Spring MVC Examples
+      c. redo demo site
+      d. google map portlet 
+
+12. Better Examples, get rid of old ones
+      * Google Map Portlet (JP)
+
+13. Eclipse Plugin
+
+14. Security 
+      * new schema
+      
+15. JPT
+$jetspeed.RenderEntity(entityId)
+
+or
+
+$jetspeed.RenderPortletEntity(entityId, portletId)
+      
\ No newline at end of file

Modified: portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/PermissionManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/PermissionManager.java?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/PermissionManager.java (original)
+++ portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/security/PermissionManager.java Tue Jun 20 00:09:37 2006
@@ -143,18 +143,40 @@
     boolean checkPermission(Subject subject, Permission permission);
     
     /**
-     * Retrieve a list of all Permissions in the system ordered by Permission Type, resource
+     * Retrieve a collection of all Permissions in the system ordered by Permission Type, resource
+     * Note that we return a collection of <code>InternalPrincipal</code>
      * 
-     * @return A list of type InternalPermission
+     * @return A Java Security collection of <code>InternalPrincipal</code>
      */
-    Iterator getPermissions();    
+    Collection getPermissions();    
     
     /**
      * Retrieve a list of all Permissions in the system for a given resource
      * The resource can be a prefix, for example "j2-admin" will retrieve all 
      * portlet permissions starting with j2-admin
      * 
-     * @return A list of type InternalPermission
+     * @return A Java Security collection of Permissions
      */
-    Iterator getPermissions(String classname, String resource);    
+    Permissions getPermissions(String classname, String resource);
+
+    /**
+     * Update the collection of principals on the given principal, 
+     * appropriately granting or revoking principals to the given permission.
+     * 
+     * @param permission Permission to be updated
+     * @param principals The new collection of principals based on BasePrincipal 
+     *        to be associated with this permission 
+     * @return
+     * @throws SecurityException
+     */
+    int updatePermission(Permission permission, Collection principals)
+    throws SecurityException;
+    
+    /**
+     * Given a permission, return all principals granted to that permission
+     * 
+     * @param permission 
+     * @return A collection of Java Security Permission objects
+     */
+    public Collection getPrincipals(Permission permission);
 }

Modified: portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/ajax-layout.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/ajax-layout.xml?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/ajax-layout.xml (original)
+++ portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/ajax-layout.xml Tue Jun 20 00:09:37 2006
@@ -18,6 +18,18 @@
     </constructor-arg>    	
 </bean>	
 
+<bean id="RolesSecurityBehavior"
+	  class="org.apache.jetspeed.layout.impl.RolesSecurityBehavior">
+       <!-- List of required roles (comma-separated) 
+            Only need to match one of the listed  roles to pass security requirements
+           -->
+        <constructor-arg>
+            <list>
+                <value>admin</value>
+            </list>
+        </constructor-arg>
+</bean>	
+    
 <bean id="AjaxMove"
     class="org.apache.jetspeed.layout.impl.MovePortletAction">
     <constructor-arg index="0">
@@ -269,6 +281,35 @@
     </constructor-arg>    	
 </bean>
 
+<bean id="AjaxSecurityPermissions"
+    class="org.apache.jetspeed.layout.impl.SecurityPermissionAction">
+    <constructor-arg index="0">
+        <value>org/apache/jetspeed/layout/ajax-xml/permissions.vm</value>
+    </constructor-arg>
+    <constructor-arg index="1">
+        <value>org/apache/jetspeed/layout/ajax-xml/error.vm</value>
+    </constructor-arg>
+    <constructor-arg index='2'>    
+        <ref bean="org.apache.jetspeed.security.PermissionManager"/>        
+    </constructor-arg>    
+    <constructor-arg index='3'>
+        <ref bean="RolesSecurityBehavior"/>        
+    </constructor-arg>    	
+    <constructor-arg index='4'>    
+        <map>
+            <entry key="portlet">
+                <value>org.apache.jetspeed.security.PortletPermission</value>
+            </entry>                        
+            <entry key="page">
+                <value>org.apache.jetspeed.security.PagePermission</value>
+            </entry>                                    
+            <entry key="folder">
+                <value>org.apache.jetspeed.security.FolderPermission</value>
+            </entry>                                    
+        </map>
+    </constructor-arg>
+</bean>
+    
 <bean id="AjaxRequestService" class="org.apache.jetspeed.ajax.AjaxRequestServiceImpl">
     <constructor-arg index="0">
         <map>
@@ -314,6 +355,9 @@
             <entry key="getmenu">
                 <ref bean="AjaxGetMenu"/>
             </entry>			            
+            <entry key="permissions">
+                <ref bean="AjaxSecurityPermissions"/>
+            </entry>			                        
         </map>
     </constructor-arg>
     <constructor-arg index="1">

Modified: portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-managers.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-managers.xml?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-managers.xml (original)
+++ portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-managers.xml Tue Jun 20 00:09:37 2006
@@ -57,6 +57,7 @@
 				<prop key="revoke*">PROPAGATION_REQUIRED</prop>
 				<prop key="grant*">PROPAGATION_REQUIRED</prop>
 				<prop key="add*">PROPAGATION_REQUIRED</prop>
+				<prop key="update*">PROPAGATION_REQUIRED</prop>
 				<prop key="*">PROPAGATION_SUPPORTS</prop>
 			</props>
 		</property>

Modified: portals/jetspeed-2/trunk/xdocs/guides/guide-ajax-api.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/xdocs/guides/guide-ajax-api.xml?rev=415531&r1=415530&r2=415531&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/xdocs/guides/guide-ajax-api.xml (original)
+++ portals/jetspeed-2/trunk/xdocs/guides/guide-ajax-api.xml Tue Jun 20 00:09:37 2006
@@ -571,6 +571,281 @@
 	</tr>				
 </table>        
 </subsection>	
+    
+<subsection name='Permissions'>
+<table>		
+
+    <tr>
+        <td>API:</td>
+        <td>permissions</td>
+    </tr>
+    <tr>
+        <td>Component:</td>
+        <td>AjaxSecurityPermissions</td>
+    </tr>
+    <tr>
+        <td>Description:</td>
+        <td>Security Permissions Maintenance to add, update, and remove permissions from the Jetspeed security policy</td>
+    </tr>
+    <tr>
+        <td>Parameters:</td>
+        <table>
+			<tr>
+				<td>action</td>
+				<td>permissions</td>				
+			</tr>			            
+			<tr>
+				<td>method</td>
+				<td>the method to execute: must be of value: add | update | delete</td>				
+			</tr>
+			<tr>
+				<td>type</td>
+				<td>the type of permission being manipulated: portlet | folder | page</td>				
+			</tr>			
+			<tr>
+				<td>resource</td>
+				<td>the name of the portal resource being manipulated</td>				
+			</tr>			            
+			<tr>
+				<td>roles</td>
+				<td>comma-separated list of roles, only valid for methods: add, update</td>				
+			</tr>			                        
+			<tr>
+				<td>actions</td>
+				<td>comma-separated list of actions, only valid for methods: add, update</td>				
+			</tr>			                        
+			<tr>
+				<td>oldactions</td>
+				<td>comma-separated list of previous actions, only valid for methods: update</td>				
+			</tr>			                                    
+		</table>
+    </tr>
+    <tr>
+        <td>API example:</td>
+		<td>
+<source><![CDATA[			
+http://localhost:8080/jetspeed/ajaxapi?action=permissions&method=add&type=portlet&resource=demo::*&roles=role1,role2,role3&actions=view,edit
+]]></source>			
+		</td>    
+	</tr>
+    <tr>
+        <td>XML Response:</td>
+		<td>
+<source><![CDATA[
+<js>
+    <status>success</status>
+    <action>permissions</action>
+    <resource>demo::*</resource> 
+    <type>portlet</type> 
+    <actions>view,edit</actions>
+    <actions>role1,role2,role3</actions>    
+</js>
+]]></source>		
+		</td>    
+	</tr>
+</table>
+</subsection>
+
+<subsection name='getmenus'>
+<table>		
+
+    <tr>
+        <td>API:</td>
+        <td>getmenus</td>
+    </tr>
+    <tr>
+        <td>Component:</td>
+        <td>AjaxGetMenus</td>
+    </tr>
+    <tr>
+        <td>Description:</td>
+        <td>Retrieves all menus for the current page (implied in URL)</td>
+    </tr>
+    <tr>
+        <td>Parameters:</td>
+        <table>
+			<tr>
+				<td>action</td>
+				<td>getmenus</td>				
+			</tr>			            
+			<tr>
+				<td>page</td>
+				<td>(implied in URL)</td>				
+			</tr>
+		</table>
+    </tr>
+    <tr>
+        <td>API example:</td>
+		<td>
+<source><![CDATA[			
+http://localhost:8080/jetspeed/ajaxapi/default-page.psml?action=getmenus
+]]></source>			
+		</td>    
+	</tr>
+    <tr>
+        <td>XML Response:</td>
+		<td>
+<source><![CDATA[
+<js>
+    <status>success</status>
+    <action>getmenus</action>    
+    <menus>
+        <menu type="standard">navigations</menu>
+        <menu type="standard">back</menu>
+        <menu type="standard">pages</menu>
+        <menu type="standard">breadcrumbs</menu>
+        <menu type="custom">site-navigations</menu>
+        <menu type="custom">additional-links</menu>
+        <menu type="custom">page-navigations</menu>
+    </menus>
+</js>
+]]></source>		
+		</td>    
+	</tr>
+</table>
+</subsection>
+
+<subsection name='getmenu'>
+<table>		
+
+    <tr>
+        <td>API:</td>
+        <td>getmenu</td>
+    </tr>
+    <tr>
+        <td>Component:</td>
+        <td>AjaxGetMenu</td>
+    </tr>
+    <tr>
+        <td>Description:</td>
+        <td>Retrieves the menu definition for a given menu</td>
+    </tr>
+    <tr>
+        <td>Parameters:</td>
+        <table>
+			<tr>
+				<td>action</td>
+				<td>getmenu</td>				
+			</tr>			            
+			<tr>
+				<td>menu</td>
+				<td>name of the menu to retrieve (menu definition may change per page)</td>				
+			</tr>
+		</table>
+    </tr>
+    <tr>
+        <td>API example:</td>
+		<td>
+<source><![CDATA[			
+http://localhost:8080/jetspeed/ajaxapi?action=getmenu&name=breadcrumbs
+]]></source>			
+		</td>    
+	</tr>
+    <tr>
+        <td>XML Response:</td>
+		<td>
+<source><![CDATA[
+<js>
+<status>success</status>
+<action>getmenu</action>
+<menu>
+  <name>breadcrumbs</name>
+  <title>You are here:</title>
+  <short-title>You are here:</short-title>
+  <skin>breadcrumbs</skin>
+  <url>/default-page.psml</url>
+  <hidden>false</hidden>
+  <selected>true</selected>
+  <option>
+    <type>folder</type>
+    <title>Root Folder</title>
+    <short-title>Root Folder</short-title>
+    <skin>breadcrumbs</skin>
+    <url>/</url>
+    <hidden>false</hidden>
+    <selected>true</selected>
+  </option>
+  <option>
+    <type>page</type>
+    <title>Welcome to Jetspeed 2</title>
+    <short-title>Welcome to Jetspeed 2</short-title>
+    <skin>blue</skin>
+    <url>/default-page.psml</url>
+    <hidden>false</hidden>
+    <selected>true</selected>
+  </option>
+</menu>
+</js>
+]]></source>		
+		</td>    
+	</tr>
+</table>
+</subsection>
+
+<subsection name='window'>
+<table>		
+
+    <tr>
+        <td>API:</td>
+        <td>getmenus</td>
+    </tr>
+    <tr>
+        <td>Component:</td>
+        <td>AjaxChangeWindow</td>
+    </tr>
+    <tr>
+        <td>Description:</td>
+        <td>Changes a portlet window's Window State or Portlet Mode</td>
+    </tr>
+    <tr>
+        <td>Parameters:</td>
+        <table>
+			<tr>
+				<td>action</td>
+				<td>window</td>				
+			</tr>			            
+			<tr>
+				<td>id</td>
+				<td>window id of the portlet to be modified</td>				
+			</tr>
+			<tr>
+				<td>state</td>
+				<td>A portlet api valid window state or extended window state (normal | maximized | minimized)</td>				
+			</tr>            
+			<tr>
+				<td>mode</td>
+				<td>A portlet api valid portlet mode or extended portlet mode (view | edit | help | print)</td>				
+			</tr>                        
+			<tr>
+				<td>page</td>
+				<td>Implied in URL</td>				
+			</tr>                                    
+		</table>
+    </tr>
+    <tr>
+        <td>API example:</td>
+		<td>
+<source><![CDATA[			
+http://localhost:8080/jetspeed/ajaxapi?action=window&state=maximized&mode=edit&id=um-2
+]]></source>			
+		</td>    
+	</tr>
+    <tr>
+        <td>XML Response:</td>
+		<td>
+<source><![CDATA[
+<js>
+  <status>success</status>
+  <action>window</action>
+  <id>um-2</id>  
+  <state>maximized</state>
+  <mode>edit</mode>
+</js>
+]]></source>		
+		</td>    
+	</tr>
+</table>
+</subsection>        
 </section>
 
 <section name='Spring Assembly'>
@@ -583,6 +858,9 @@
 <bean id="AjaxRequestService" class="org.apache.jetspeed.ajax.AjaxRequestServiceImpl">
     <constructor-arg index="0">
         <map>
+            <entry key="move">
+                <ref bean="AjaxMove"/>
+            </entry>            
             <entry key="moveabs">
                 <ref bean="AjaxMovePortletAbsolute"/>
             </entry>
@@ -610,6 +888,21 @@
             <entry key="getpage">
                 <ref bean="AjaxGetPage"/>
             </entry>
+            <entry key="getpages">
+                <ref bean="AjaxGetPages"/>
+            </entry>			
+            <entry key="window">
+                <ref bean="AjaxChangeWindow"/>
+            </entry>			            
+            <entry key="getmenus">
+                <ref bean="AjaxGetMenus"/>
+            </entry>			            
+            <entry key="getmenu">
+                <ref bean="AjaxGetMenu"/>
+            </entry>			            
+            <entry key="permissions">
+                <ref bean="AjaxSecurityPermissions"/>
+            </entry>			                        
         </map>
     </constructor-arg>
     <constructor-arg index="1">



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org