Author: sohil.shah(a)jboss.com
Date: 2007-01-28 15:09:47 -0500 (Sun, 28 Jan 2007)
New Revision: 6109
Added:
trunk/cms/src/main/org/jboss/portal/cms/workflow/PublishAssignmentHandler.java
Modified:
trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ACLEnforcer.java
trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProvider.java
trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProviderImpl.java
trunk/core-cms/src/main/org/jboss/portal/core/cms/ui/admin/CMSAdminPortlet.java
trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/main.jsp
trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/pending_items.jsp
trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/viewfile.jsp
trunk/workflow/build.log
trunk/workflow/build.xml
trunk/workflow/src/main/org/jboss/portal/workflow/cms/ApprovePublish.java
trunk/workflow/src/main/org/jboss/portal/workflow/cms/ApprovePublishImpl.java
trunk/workflow/src/main/org/jboss/portal/workflow/cms/Content.java
trunk/workflow/src/resources/portal-workflow-sar/META-INF/jboss-service.xml
Log:
[JBPORTAL-931],[JBPORTAL-372] - Updated the CMS Approval Workflow
[GUI,Security,IdentityModule]
Modified: 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 2007-01-28
20:08:11 UTC (rev 6108)
+++ trunk/cms/src/main/org/jboss/portal/cms/impl/jcr/command/ACLEnforcer.java 2007-01-28
20:09:47 UTC (rev 6109)
@@ -24,6 +24,7 @@
import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.Set;
import java.util.HashSet;
import java.util.StringTokenizer;
@@ -36,7 +37,10 @@
import org.jboss.portal.cms.security.AuthorizationManager;
import org.jboss.portal.identity.User;
+import org.jboss.portal.identity.Role;
+import org.jboss.portal.workflow.cms.ApprovePublish;
+
/**
* ACLEnforcer checks proper access privileges for actions before
* the Command objects are allowed to execute and do their job on the CMS
@@ -53,6 +57,7 @@
private static final int read = 0;
private static final int write = 1;
private static final int manage = 2;
+ private static final int manageWorkflow = 3;
private AuthorizationManager authorizationManager = null;
@@ -104,11 +109,13 @@
User loggedInUser = (User)cmsSecurityContext.getIdentity();
JCRCommand command =
(JCRCommand)cmsSecurityContext.getAttribute("command");
+ //get the action code of the action being protected
int actionCode = -1;
if(command != null)
{
actionCode = this.getActionCode(command);
}
+
switch(actionCode)
{
case read:
@@ -131,6 +138,13 @@
String path =
(String)cmsSecurityContext.getAttribute("applyFilter");
hasAccess = this.computeToolAccess(loggedInUser,path);
}
+ //check if workflow management protection needs to be enforced
+ else
if(cmsSecurityContext.getAttribute("manageWorkflow")!=null)
+ {
+ ApprovePublish service = (ApprovePublish)cmsSecurityContext.
+ getAttribute("approvePublish");
+ hasAccess =
this.computeWorkflowManagementAccess(loggedInUser,service.getManagers());
+ }
break;
}
@@ -489,6 +503,48 @@
return toolAccess;
}
+
+ /**
+ *
+ * @param user
+ * @return
+ */
+ private boolean computeWorkflowManagementAccess(User user,Set managerRoles)
+ {
+ if(managerRoles == null || managerRoles.isEmpty())
+ {
+ return false;
+ }
+
+ //now check to see if the currently logged in user has workflow management access
+ try
+ {
+ boolean hasAccess = false;
+
+ Set userRoles = this.authorizationManager.getProvider().
+ getMembershipModule().getRoles(user);
+
+ if(userRoles != null)
+ {
+ for(Iterator itr=userRoles.iterator();itr.hasNext();)
+ {
+ Role userRole = (Role)itr.next();
+ String userRoleName = userRole.getName();
+ if(managerRoles.contains(userRoleName))
+ {
+ hasAccess = true;
+ break;
+ }
+ }
+ }
+
+ return hasAccess;
+ }
+ catch(Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
//----------------------------------------------------------------------------------------------------------------------------------------------
/**
*
Modified: trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProvider.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProvider.java 2007-01-28
20:08:11 UTC (rev 6108)
+++ trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProvider.java 2007-01-28
20:09:47 UTC (rev 6109)
@@ -25,6 +25,8 @@
import org.jboss.portal.security.spi.provider.AuthorizationDomain;
import org.jboss.portal.security.spi.provider.DomainConfigurator;
+import org.jboss.portal.identity.MembershipModule;
+
/**
* Created on : Jan 24, 2007
* @author Sohil Shah - sohil.shah(a)jboss.com
@@ -55,4 +57,10 @@
* @return
*/
public String getCriteriaURI(String name,String value);
+
+ /**
+ *
+ * @return
+ */
+ public MembershipModule getMembershipModule();
}
Modified: trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProviderImpl.java
===================================================================
---
trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProviderImpl.java 2007-01-28
20:08:11 UTC (rev 6108)
+++
trunk/cms/src/main/org/jboss/portal/cms/security/AuthorizationProviderImpl.java 2007-01-28
20:09:47 UTC (rev 6109)
@@ -204,6 +204,14 @@
{
return "criteria://"+name+"/"+value;
}
+
+ /**
+ *
+ */
+ public MembershipModule getMembershipModule()
+ {
+ return this.membershipModule;
+ }
//--------------------------------------------------------------------------------------------------------------
/**
*
Added: trunk/cms/src/main/org/jboss/portal/cms/workflow/PublishAssignmentHandler.java
===================================================================
--- trunk/cms/src/main/org/jboss/portal/cms/workflow/PublishAssignmentHandler.java
(rev 0)
+++
trunk/cms/src/main/org/jboss/portal/cms/workflow/PublishAssignmentHandler.java 2007-01-28
20:09:47 UTC (rev 6109)
@@ -0,0 +1,178 @@
+/******************************************************************************
+ * 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.workflow;
+
+import org.apache.log4j.Logger;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.net.URLEncoder;
+import java.text.MessageFormat;
+
+import javax.naming.InitialContext;
+
+import org.jbpm.graph.exe.*;
+import org.jbpm.taskmgmt.def.*;
+import org.jbpm.taskmgmt.exe.Assignable;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+//import org.jboss.portal.core.modules.MailModule;
+
+import org.jboss.portal.identity.IdentityServiceController;
+import org.jboss.portal.identity.MembershipModule;
+import org.jboss.portal.identity.UserModule;
+import org.jboss.portal.identity.RoleModule;
+import org.jboss.portal.identity.UserProfileModule;
+import org.jboss.portal.identity.IdentityContext;
+import org.jboss.portal.identity.User;
+
+import org.jboss.portal.workflow.cms.Content;
+
+
+/**
+ *
+ * Created on : Dec 20, 2006
+ * @author Sohil Shah - sohil.shah(a)jboss.com
+ *
+ */
+public class PublishAssignmentHandler implements AssignmentHandler
+{
+ private static Logger log = Logger.getLogger(PublishAssignmentHandler.class);
+
+ /*private static MailModule mailModule = null;
+
+ private static IdentityServiceController identityServiceController = null;
+ private static MembershipModule membershipModule = null;
+ private static UserModule userModule = null;
+ private static RoleModule roleModule = null;
+ private static UserProfileModule profileModule = null;
+ static
+ {
+ try
+ {
+ InitialContext context = new InitialContext();
+ mailModule = (MailModule)context.lookup("java:portal/MailModule");
+
+ identityServiceController = (IdentityServiceController)context.
+ lookup("java:/portal/IdentityServiceController");
+ membershipModule =
(MembershipModule)identityServiceController.getIdentityContext().
+ getObject(IdentityContext.TYPE_MEMBERSHIP_MODULE);
+ userModule = (UserModule)identityServiceController.getIdentityContext().
+ getObject(IdentityContext.TYPE_USER_MODULE);
+ roleModule = (RoleModule)identityServiceController.getIdentityContext().
+ getObject(IdentityContext.TYPE_ROLE_MODULE);
+ profileModule = (UserProfileModule)identityServiceController.getIdentityContext().
+ getObject(IdentityContext.TYPE_USER_PROFILE_MODULE);
+ }
+ catch(Exception e)
+ {
+ //mailModule = null;
+ throw new RuntimeException(e);
+ }
+ }*/
+
+ /**
+ *
+ */
+ public void assign(Assignable assignable,ExecutionContext executionContext)
+ {
+ int taskInstances = 0;
+ Collection assignedTasks = executionContext.getTaskMgmtInstance().getTaskInstances();
+ if(assignedTasks!=null)
+ {
+ taskInstances = assignedTasks.size();
+ }
+
+ if(taskInstances == 1)
+ {
+ String[] managers =
(String[])executionContext.getContextInstance().getVariable("managers");
+ if(managers!=null && managers.length>0)
+ {
+ //this.notifyManagers(executionContext,managers[0]);
+ assignable.setActorId(managers[0]);
+
+ for(int i=1;i<managers.length;i++)
+ {
+ //this.notifyManagers(executionContext,managers[i]);
+ TaskInstance t = executionContext.getTaskMgmtInstance().
+ createTaskInstance(((TaskInstance)assignable).getTask(),executionContext);
+ t.setActorId(managers[i]);
+ }
+ }
+ }
+ }
+
+ //Now that the Manager Approval/Denial GUI is integrated..no need to use the email
+ //as the Manager screen
+ /**
+ *
+ * @param email
+ */
+ /*private void notifyManagers(ExecutionContext executionContext,String managerRole)
+ {
+ try
+ {
+ Set users = membershipModule.getUsers(roleModule.findRoleByName(managerRole));
+ if(users != null)
+ {
+ for(Iterator itr=users.iterator();itr.hasNext();)
+ {
+ User user = (User)itr.next();
+ String email = (String)profileModule.getProperty(user, User.INFO_USER_EMAIL_REAL);
+ long processId = executionContext.getProcessInstance().getId();
+ String from =
(String)executionContext.getContextInstance().getVariable("from");
+ String to = email;
+ String subject =
(String)executionContext.getContextInstance().getVariable("subject");
+ String body =
(String)executionContext.getContextInstance().getVariable("body");
+ Content content =
(Content)executionContext.getContextInstance().getVariable("content");
+
+ Object[] arguments =
+ {
+ content.getPath(),
+ content.getMimeType(),
+ content.getSizeStr(),
+ content.getCreationDateStr(),
+ content.getUserName(),
+ String.valueOf(processId),
+ URLEncoder.encode(email, "UTF-8"),
+ String.valueOf(processId),
+ URLEncoder.encode(email, "UTF-8")
+ };
+ body = MessageFormat.format(body, arguments);
+
+ System.out.println("----------------------------------------");
+ System.out.println("Notification being sent to----->"+to);
+ System.out.println("----------------------------------------");
+
+ //mailModule.send(from,to,subject,body);
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ //eat it for now
+ log.error(this, e);
+ }
+ }*/
+}
Modified: trunk/core-cms/src/main/org/jboss/portal/core/cms/ui/admin/CMSAdminPortlet.java
===================================================================
---
trunk/core-cms/src/main/org/jboss/portal/core/cms/ui/admin/CMSAdminPortlet.java 2007-01-28
20:08:11 UTC (rev 6108)
+++
trunk/core-cms/src/main/org/jboss/portal/core/cms/ui/admin/CMSAdminPortlet.java 2007-01-28
20:09:47 UTC (rev 6109)
@@ -35,9 +35,11 @@
import org.jboss.portal.cms.model.Content;
import org.jboss.portal.cms.model.File;
import org.jboss.portal.cms.model.Folder;
+import org.jboss.portal.cms.security.CMSPermission;
import org.jboss.portal.cms.security.Criteria;
import org.jboss.portal.cms.security.Permission;
import org.jboss.portal.cms.security.AuthorizationManager;
+import org.jboss.portal.cms.security.PortalCMSSecurityContext;
import org.jboss.portal.cms.util.FileUtil;
import org.jboss.portal.cms.util.NodeUtil;
import org.jboss.portal.core.cms.command.StreamContentCommand;
@@ -49,6 +51,7 @@
import org.jboss.portal.identity.RoleModule;
import org.jboss.portal.identity.User;
import org.jboss.portal.identity.UserModule;
+import org.jboss.portal.security.PortalPermission;
import org.jboss.portal.server.request.URLContext;
import org.jboss.portal.server.request.URLFormat;
import org.jboss.portal.workflow.WorkflowException;
@@ -200,6 +203,10 @@
rReq.setAttribute("folders", folders);
rReq.setAttribute("files", files);
rReq.setAttribute("currpath", sPath);
+
+ //manage workflow accessibility check
+ rReq.setAttribute("manageWorkflowAccessible", new
Boolean(this.isWorkflowManagementAccessible(rReq)));
+
javax.portlet.PortletRequestDispatcher prd =
getPortletContext().getRequestDispatcher(CMSAdminConstants.CMS_JSP_PATH +
"/main.jsp");
prd.include(rReq, rRes);
}
@@ -267,6 +274,10 @@
rRes.setContentType("text/html");
rReq.setAttribute("currpath", sPath);
rReq.setAttribute("contents", contents);
+
+ //manage workflow accessibility check
+ rReq.setAttribute("manageWorkflowAccessible", new
Boolean(this.isWorkflowManagementAccessible(rReq)));
+
javax.portlet.PortletRequestDispatcher prd =
getPortletContext().getRequestDispatcher(CMSAdminConstants.CMS_JSP_PATH +
"/viewfile.jsp");
prd.include(rReq, rRes);
}
@@ -1077,35 +1088,59 @@
}
else if (CMSAdminConstants.OP_APPROVE.equals(op))
{
- String sManager = aReq.getParameter("manager"); // TODO: fix with
identity module integration
+ String sManager = aReq.getUser().getUserName();
String sPID = aReq.getParameter("pid");
-
try
{
this.getApprovePublish().processManagerResponse(Long.parseLong(sPID),
sManager, true);
}
catch (Exception e)
{
- // TODO: fix me.
+ //show an error message on the pending item screen
+ aRes.setRenderParameter("path",
aReq.getParameter("path"));
+ aRes.setRenderParameter("exception", e.getMessage());
+
+ String from = aReq.getParameter("from");
+ if(from == null || from.trim().length()==0)
+ {
+ aRes.setRenderParameter("op",
CMSAdminConstants.OP_VIEWPENDING);
+ }
+ else
+ {
+ aRes.setRenderParameter("op", from);
+ }
+ return;
}
aRes.setRenderParameter("path",
aReq.getParameter("path"));
aRes.setRenderParameter("op", CMSAdminConstants.OP_VIEWFILE);
}
else if (CMSAdminConstants.OP_DENY.equals(op))
{
- String sManager = aReq.getParameter("manager"); // TODO: fix with
identity module integration
- String sPID = aReq.getParameter("pid");
-
- try
- {
- this.getApprovePublish().processManagerResponse(Long.parseLong(sPID),
sManager, false);
- }
- catch (Exception e)
- {
- // TODO: fix me.
- }
- aRes.setRenderParameter("path",
aReq.getParameter("path"));
- aRes.setRenderParameter("op", CMSAdminConstants.OP_VIEWFILE);
+ String sManager = aReq.getUser().getUserName();
+ String sPID = aReq.getParameter("pid");
+ try
+ {
+ this.getApprovePublish().processManagerResponse(Long.parseLong(sPID),
sManager, false);
+ }
+ catch (Exception e)
+ {
+ //show an error message on the pending item screen
+ aRes.setRenderParameter("path",
aReq.getParameter("path"));
+ aRes.setRenderParameter("exception", e.getMessage());
+
+ String from = aReq.getParameter("from");
+ if(from == null || from.trim().length()==0)
+ {
+ aRes.setRenderParameter("op",
CMSAdminConstants.OP_VIEWPENDING);
+ }
+ else
+ {
+ aRes.setRenderParameter("op", from);
+ }
+ return;
+ }
+ aRes.setRenderParameter("path",
aReq.getParameter("path"));
+ aRes.setRenderParameter("op", CMSAdminConstants.OP_VIEWFILE);
}
}
else
@@ -1362,6 +1397,25 @@
return false;
}
}
+
+ /**
+ *
+ * @return
+ */
+ private boolean isWorkflowManagementAccessible(JBossRenderRequest renderRequest)
+ {
+ boolean isAccessible = false;
+
+ User user = renderRequest.getUser();
+ PortalCMSSecurityContext securityContext = new PortalCMSSecurityContext(user);
+ securityContext.setAttribute("manageWorkflow", "true");
+ securityContext.setAttribute("approvePublish", this.approvePublish);
+
+ PortalPermission cmsPermission = new CMSPermission(securityContext);
+ isAccessible = this.authorizationManager.checkPermission(cmsPermission);
+
+ return isAccessible;
+ }
/** @return */
private void initializeApprovePublishWorkflow()
Modified: trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/main.jsp
===================================================================
--- trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/main.jsp 2007-01-28
20:08:11 UTC (rev 6108)
+++ trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/main.jsp 2007-01-28
20:09:47 UTC (rev 6109)
@@ -19,6 +19,7 @@
List files = (List)request.getAttribute("files");
String createDate = "";
String modifiedDate = "";
+ Boolean manageWorkflowAccessible =
(Boolean)request.getAttribute("manageWorkflowAccessible");
%>
<br>
@@ -96,10 +97,12 @@
<portlet:param name="path" value="<%= sCurrPath %>"/>
<portlet:param name="returnOp" value="<%=
CMSAdminConstants.OP_MAIN %>"/>
</portlet:renderURL>">${n:i18n("CMS_SECURE")}</a></li>
+ <%if(manageWorkflowAccessible.booleanValue()){%>
<li><a href="<portlet:renderURL>
<portlet:param name="op" value="<%=
CMSAdminConstants.OP_VIEWPENDING %>"/>
<portlet:param name="path" value="<%= sCurrPath %>"/>
</portlet:renderURL>">${n:i18n("CMS_APPROVAL")}</a></li>
+ <%}%>
<%
if (!"/".equals(sCurrPath))
{
Modified:
trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/pending_items.jsp
===================================================================
---
trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/pending_items.jsp 2007-01-28
20:08:11 UTC (rev 6108)
+++
trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/pending_items.jsp 2007-01-28
20:09:47 UTC (rev 6109)
@@ -13,6 +13,7 @@
<%
String sCurrPath = (String)request.getAttribute("currpath");
Collection pendingQueue = (Collection)request.getAttribute("pendingQueue");
+ String exception = request.getParameter("exception");
String rowClass = "portlet-section-body";
%>
@@ -58,6 +59,22 @@
<br/><br/>
+<!-- show any errors here -->
+<%if(exception!=null && exception.trim().length()>0){%>
+<table width="100%">
+<th colspan="2" align="center"
class="portlet-section-header">Error:</th>
+<tr colspan="2" align="center">
+ <td colspan="2">
+ <font color="red">
+ <%=exception%>
+ </font>
+ </td>
+</tr>
+</table>
+<br/><br/>
+<%}%>
+
+<!-- the table listing the pending queue items -->
<div align="center"><font
class="portlet-font-dim"><b>Pending Approval
Queue</b></font></div>
<br/>
<table width="100%" border="0" cellspacing="0"
cellpadding="0">
@@ -73,9 +90,7 @@
for (Iterator itr = pendingQueue.iterator(); itr.hasNext();)
{
%>
- <%
- // TODO: need accessor for approvalpid in Content, for param in links below.
- // TODO: need security access to get current manager as param for links below.
+ <%
org.jboss.portal.workflow.cms.Content cour =
(org.jboss.portal.workflow.cms.Content)itr.next();
String linkPath = cour.getPath().substring(0,
cour.getPath().lastIndexOf("/"));
@@ -111,17 +126,15 @@
</td>
<td>
<a href="<portlet:actionURL>
- <portlet:param name="op" value="<%=
CMSAdminConstants.OP_APPROVE %>"/>
- <portlet:param name="pid" value="TODO"/>
- <portlet:param name="manager" value="TODO"/>
- <portlet:param name="path" value="<%= cour.getPath()
%>"/>
+ <portlet:param name="op" value="<%=
CMSAdminConstants.OP_APPROVE %>"/>
+ <portlet:param name="pid"
value="<%=cour.getProcessId()%>"/>
+ <portlet:param name="path"
value="<%=linkPath%>"/>
</portlet:actionURL>">${n:i18n("CMS_APPROVE")}</a>
<a href="<portlet:actionURL>
<portlet:param name="op" value="<%=
CMSAdminConstants.OP_DENY %>"/>
- <portlet:param name="pid" value="TODO"/>
- <portlet:param name="manager" value="TODO"/>
- <portlet:param name="path" value="<%= cour.getPath()
%>"/>
+ <portlet:param name="pid"
value="<%=cour.getProcessId()%>"/>
+ <portlet:param name="path"
value="<%=linkPath%>"/>
</portlet:actionURL>">${n:i18n("CMS_DENY")}</a>
</td>
</tr>
Modified: trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/viewfile.jsp
===================================================================
---
trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/viewfile.jsp 2007-01-28
20:08:11 UTC (rev 6108)
+++
trunk/core-cms/src/resources/portal-cms-war/WEB-INF/jsp/cms/admin/viewfile.jsp 2007-01-28
20:09:47 UTC (rev 6109)
@@ -37,6 +37,9 @@
String modifiedDate = "";
String rowClass = "portlet-section-body";
+
+ String exception = request.getParameter("exception");
+ Boolean manageWorkflowAccessible =
(Boolean)request.getAttribute("manageWorkflowAccessible");
%>
<br>
@@ -126,10 +129,12 @@
<portlet:param name="path" value="<%= sCurrPath %>"/>
<portlet:param name="returnOp" value="<%=
CMSAdminConstants.OP_VIEWFILE %>"/>
</portlet:renderURL>">${n:i18n("CMS_SECURE")}</a></li>
+ <%if(manageWorkflowAccessible.booleanValue()){%>
<li><a href="<portlet:renderURL>
<portlet:param name="op" value="<%=
CMSAdminConstants.OP_VIEWPENDING %>"/>
<portlet:param name="path" value="<%= sCurrPath %>"/>
</portlet:renderURL>">${n:i18n("CMS_APPROVAL")}</a></li>
+ <%}%>
</ul>
<!--[if lte IE
6]></td></tr></table></a><![endif]-->
</li>
@@ -300,6 +305,21 @@
%>
<br/><br/>
+<!-- show any errors here -->
+<%if(exception!=null && exception.trim().length()>0){%>
+<table width="100%">
+<th colspan="2" align="center"
class="portlet-section-header">Error:</th>
+<tr colspan="2" align="center">
+ <td colspan="2">
+ <font color="red">
+ <%=exception%>
+ </font>
+ </td>
+</tr>
+</table>
+<br/><br/>
+<%}%>
+
<div align="center"><font
class="portlet-font-dim"><b>Pending Approval
Queue</b></font></div>
<br/>
<table width="100%" border="0" cellspacing="0"
cellpadding="0">
@@ -308,7 +328,9 @@
<td
class="portlet-table-text"><b>${n:i18n("CMS_SIZE")}</b></td>
<td
class="portlet-table-text"><b>${n:i18n("CMS_CREATED")}</b></td>
<td
class="portlet-table-text"><b>${n:i18n("CMS_CREATED_BY")}</b></td>
+ <%if(manageWorkflowAccessible.booleanValue()){%>
<td
class="portlet-table-text"><b>${n:i18n("CMS_ACTION")}</b></td>
+ <%}%>
</tr>
<%int i = 0;%>
<%
@@ -316,8 +338,6 @@
{
%>
<%
- // TODO: need accessor for approvalpid in Content, for param in links below.
- // TODO: need security access to get current manager as param for links below.
org.jboss.portal.workflow.cms.Content cour =
(org.jboss.portal.workflow.cms.Content)itr.next();
if (i % 2 == 0)
{
@@ -343,21 +363,23 @@
<!-- User who requested approval -->
<td><%= cour.getUserName() %>
</td>
+ <%if(manageWorkflowAccessible.booleanValue()){%>
<td>
<a href="<portlet:actionURL>
- <portlet:param name="op" value="<%=
CMSAdminConstants.OP_APPROVE %>"/>
- <portlet:param name="pid" value="TODO"/>
- <portlet:param name="manager" value="TODO"/>
- <portlet:param name="path" value="<%= sCurrPath
%>"/>
+ <portlet:param name="op"
value="<%=CMSAdminConstants.OP_APPROVE%>"/>
+ <portlet:param name="pid"
value="<%=cour.getProcessId()%>"/>
+ <portlet:param name="path"
value="<%=sCurrPath%>"/>
+ <portlet:param name="from"
value="<%=CMSAdminConstants.OP_VIEWFILE%>"/>
</portlet:actionURL>">${n:i18n("CMS_APPROVE")}</a>
<a href="<portlet:actionURL>
- <portlet:param name="op" value="<%=
CMSAdminConstants.OP_DENY %>"/>
- <portlet:param name="pid" value="TODO"/>
- <portlet:param name="manager" value="TODO"/>
- <portlet:param name="path" value="<%= sCurrPath
%>"/>
+ <portlet:param name="op"
value="<%=CMSAdminConstants.OP_DENY%>"/>
+ <portlet:param name="pid"
value="<%=cour.getProcessId()%>"/>
+ <portlet:param name="path"
value="<%=sCurrPath%>"/>
+ <portlet:param name="from"
value="<%=CMSAdminConstants.OP_VIEWFILE%>"/>
</portlet:actionURL>">${n:i18n("CMS_DENY")}</a>
</td>
+ <%}%>
</tr>
<%}%>
</table>
Modified: trunk/workflow/build.log
===================================================================
--- trunk/workflow/build.log 2007-01-28 20:08:11 UTC (rev 6108)
+++ trunk/workflow/build.log 2007-01-28 20:09:47 UTC (rev 6109)
@@ -1,51 +1,43 @@
-
-configure:
-Overriding previous definition of reference to apache.ant.classpath
-
-configure-modules:
-
-configure-defaults:
-Overriding previous definition of reference to javac.classpath
-
-configure-tools:
-
-_configure:jbossaop:task:
-
-_configure:xdoclet:task:
-
-_configure:xdoclet:ejbdoclet:
-
-_configure:xdoclet:jmxdoclet:
-
-_default:compile-classes:
- [mkdir] Created dir: /Users/julien/java/jboss-portal-2.6/workflow/output/classes
- [mkdir] Created dir: /Users/julien/java/jboss-portal-2.6/workflow/output/gen/classes
- [javac] Compiling 12 source files to
/Users/julien/java/jboss-portal-2.6/workflow/output/classes
-
-_default:check-exists-etc:
-
-_default:compile-etc:
- [mkdir] Created dir: /Users/julien/java/jboss-portal-2.6/workflow/output/etc
- [copy] Copying 1 file to /Users/julien/java/jboss-portal-2.6/workflow/output/etc
-
-_default:check-exists-resources:
-
-_default:compile-resources:
- [mkdir] Created dir: /Users/julien/java/jboss-portal-2.6/workflow/output/resources
- [copy] Copying 6 files to
/Users/julien/java/jboss-portal-2.6/workflow/output/resources
- [copy] Copied 10 empty directories to 1 empty directory under
/Users/julien/java/jboss-portal-2.6/workflow/output/resources
-
-compile:
-
-output:
- [mkdir] Created dir: /Users/julien/java/jboss-portal-2.6/workflow/output/lib
- [jar] Building jar:
/Users/julien/java/jboss-portal-2.6/workflow/output/lib/portal-workflow-lib.jar
- [copy] Copying 2 files to
/Users/julien/java/jboss-portal-2.6/workflow/output/lib/portal-workflow.war
-
-_default:most:
-
-most:
-
-main:
-
-BUILD SUCCESSFUL
+
+configure:
+Overriding previous definition of reference to apache.ant.classpath
+
+configure-modules:
+
+configure-defaults:
+Overriding previous definition of reference to javac.classpath
+
+configure-tools:
+
+_configure:jbossaop:task:
+
+_configure:xdoclet:task:
+
+_configure:xdoclet:ejbdoclet:
+
+_configure:xdoclet:jmxdoclet:
+
+_default:compile-classes:
+ [depend] Deleted 1 out of date files in 0 seconds
+ [javac] Compiling 1 source file to
C:\projects\core-portal\jboss-portal-trunk\workflow\output\classes
+
+_default:check-exists-etc:
+
+_default:compile-etc:
+
+_default:check-exists-resources:
+
+_default:compile-resources:
+
+compile:
+
+output:
+ [jar] Building jar:
C:\projects\core-portal\jboss-portal-trunk\workflow\output\lib\portal-workflow-lib.jar
+
+_default:most:
+
+most:
+
+main:
+
+BUILD SUCCESSFUL
Modified: trunk/workflow/build.xml
===================================================================
--- trunk/workflow/build.xml 2007-01-28 20:08:11 UTC (rev 6108)
+++ trunk/workflow/build.xml 2007-01-28 20:09:47 UTC (rev 6109)
@@ -118,6 +118,7 @@
<path id="dependentmodule.classpath">
<path refid="jboss.portal-common.classpath"/>
<path refid="jboss.portal-jems.classpath"/>
+ <path refid="jboss.portal-identity.classpath"/>
</path>
Modified: trunk/workflow/src/main/org/jboss/portal/workflow/cms/ApprovePublish.java
===================================================================
--- trunk/workflow/src/main/org/jboss/portal/workflow/cms/ApprovePublish.java 2007-01-28
20:08:11 UTC (rev 6108)
+++ trunk/workflow/src/main/org/jboss/portal/workflow/cms/ApprovePublish.java 2007-01-28
20:09:47 UTC (rev 6109)
@@ -22,6 +22,8 @@
******************************************************************************/
package org.jboss.portal.workflow.cms;
+import java.util.Set;
+
import org.jboss.portal.workflow.WorkflowException;
import java.util.Collection;
@@ -68,4 +70,13 @@
* @throws WorkflowException
*/
public Collection getAllPendingInQueue() throws WorkflowException;
+
+ /**
+ * Returns role names of Roles that are designated to be Managers in this workflow.
+ * Managers approve/deny all content publish requests before the content goes live in
the
+ * CMS
+ *
+ * @return a Set of role names
+ */
+ public Set getManagers();
}
Modified: trunk/workflow/src/main/org/jboss/portal/workflow/cms/ApprovePublishImpl.java
===================================================================
---
trunk/workflow/src/main/org/jboss/portal/workflow/cms/ApprovePublishImpl.java 2007-01-28
20:08:11 UTC (rev 6108)
+++
trunk/workflow/src/main/org/jboss/portal/workflow/cms/ApprovePublishImpl.java 2007-01-28
20:09:47 UTC (rev 6109)
@@ -22,12 +22,22 @@
******************************************************************************/
package org.jboss.portal.workflow.cms;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.HashSet;
+
import org.apache.log4j.Logger;
+
import org.jboss.portal.common.util.JNDI;
import org.jboss.portal.common.util.Tools;
-import org.jboss.portal.jems.as.system.AbstractJBossService;
-import org.jboss.portal.workflow.WorkflowException;
-import org.jboss.portal.workflow.service.WorkflowService;
+
import org.jbpm.JbpmContext;
import org.jbpm.db.GraphSession;
import org.jbpm.graph.def.ProcessDefinition;
@@ -37,15 +47,19 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import javax.xml.parsers.DocumentBuilderFactory;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
+import org.jboss.portal.identity.IdentityServiceController;
+import org.jboss.portal.identity.IdentityContext;
+import org.jboss.portal.identity.MembershipModule;
+import org.jboss.portal.identity.UserModule;
+import org.jboss.portal.identity.Role;
+import org.jboss.portal.jems.as.system.AbstractJBossService;
+
+import org.jboss.portal.workflow.WorkflowException;
+import org.jboss.portal.workflow.service.WorkflowService;
+
+
+
/**
* Created on : Dec 19, 2006
*
@@ -62,15 +76,20 @@
*
*/
private WorkflowService workflowService = null;
+ private IdentityServiceController identityServiceController = null;
private String process = null;
private String processName = null;
- private String managerEmails = null;
+ private String managerRoles = null;
private String[] managers = null;
+ private Set managerSet = null;
private boolean overwrite = false;
private String from = null;
private String subject = null;
private String body = null;
private JNDI.Binding jndiBinding;
+
+ private MembershipModule membershipModule = null;
+ private UserModule userModule = null;
private String jndiName = null;
@@ -141,12 +160,20 @@
}
//process managers that can serve as approvers/rejecters
- StringTokenizer st = new StringTokenizer(this.managerEmails, ",");
+ StringTokenizer st = new StringTokenizer(this.managerRoles, ",");
this.managers = new String[st.countTokens()];
+ this.managerSet = new HashSet();
for (int i = 0; i < managers.length; i++)
{
this.managers[i] = st.nextToken();
+ this.managerSet.add(this.managers[i]);
}
+
+ this.membershipModule =
(MembershipModule)identityServiceController.getIdentityContext().
+ getObject(IdentityContext.TYPE_MEMBERSHIP_MODULE);
+
+ this.userModule = (UserModule)identityServiceController.getIdentityContext().
+ getObject(IdentityContext.TYPE_USER_MODULE);
}
/**
@@ -189,15 +216,15 @@
/** @return the managerRoles */
- public String getManagerEmails()
+ public String getManagerRoles()
{
- return managerEmails;
+ return managerRoles;
}
- /** @param managerEmails the manager emails to set */
- public void setManagerEmails(String managerEmails)
+ /** @param managerRoles the manager managerRoles to set */
+ public void setManagerRoles(String managerRoles)
{
- this.managerEmails = managerEmails;
+ this.managerRoles = managerRoles;
}
@@ -224,8 +251,26 @@
{
this.jndiName = jndiName;
}
+
+ /**
+ *
+ */
+ public IdentityServiceController getIdentityServiceController()
+ {
+ return identityServiceController;
+ }
+ /**
+ *
+ * @param identityServiceController
+ */
+ public void setIdentityServiceController(
+ IdentityServiceController identityServiceController)
+ {
+ this.identityServiceController = identityServiceController;
+ }
+
/** @return the body */
public String getBody()
{
@@ -330,9 +375,10 @@
* @param approved true if approved, false if rejected
*/
public void processManagerResponse(long processId, String manager, boolean approved)
throws WorkflowException
- {
+ {
JbpmContext jbpmContext = null;
ProcessInstance processInstance = null;
+ boolean isManager = false;
try
{
jbpmContext = this.workflowService.getJbpmConfiguration().createJbpmContext();
@@ -354,8 +400,9 @@
for (Iterator itr = allTasks.iterator(); itr.hasNext();)
{
TaskInstance cour = (TaskInstance)itr.next();
- if (cour.getActorId().equals(manager))
+ if (this.isManager(manager,cour.getActorId()))
{
+ isManager = true;
log.debug("Manager=" + cour.getActorId() + "(" +
processId + ")");
//check and make sure this task instance is not marked for deletion
@@ -390,6 +437,12 @@
{
jbpmContext.save(processInstance);
}
+
+ if(!isManager)
+ {
+ WorkflowException we = new WorkflowException("You are not authorized to
Approve/Deny content publish requests");
+ throw we;
+ }
Tools.safeClose(jbpmContext);
}
}
@@ -431,6 +484,7 @@
if (criteriaPath.trim().equals(filePath.trim()))
{
+ content.setProcessId(String.valueOf(cour.getId()));
pendingQueue.add(content);
}
}
@@ -476,6 +530,7 @@
//apply proper criteria to extract pending content only for the
specified file
if (content != null)
{
+ content.setProcessId(String.valueOf(cour.getId()));
pendingQueue.add(content);
}
}
@@ -488,5 +543,44 @@
}
return pendingQueue;
}
-
+
+ /**
+ *
+ * @return
+ */
+ public Set getManagers()
+ {
+ return this.managerSet;
+ }
+
//----------------------------------------------------------------------------------------------------------------
+ /**
+ * checks to see if the user trying to approve/deny a publish request belongs to the
+ * approved list of managers
+ *
+ * @param user
+ * @param managerRole
+ * @return
+ */
+ private boolean isManager(String user,String managerRole) throws Exception
+ {
+ boolean isManager = false;
+
+ Set userRoles = this.membershipModule.getRoles(
+ this.userModule.findUserByUserName(user));
+ if(userRoles != null)
+ {
+ for(Iterator itr=userRoles.iterator();itr.hasNext();)
+ {
+ Role cour = (Role)itr.next();
+ if(cour.getName().equalsIgnoreCase(managerRole))
+ {
+ //user is allowed to be a manager for this workflow
+ isManager = true;
+ break;
+ }
+ }
+ }
+
+ return isManager;
+ }
}
Modified: trunk/workflow/src/main/org/jboss/portal/workflow/cms/Content.java
===================================================================
--- trunk/workflow/src/main/org/jboss/portal/workflow/cms/Content.java 2007-01-28 20:08:11
UTC (rev 6108)
+++ trunk/workflow/src/main/org/jboss/portal/workflow/cms/Content.java 2007-01-28 20:09:47
UTC (rev 6109)
@@ -40,6 +40,8 @@
private String mimeType = null;
private int size = 0;
private Date creationDate = null;
+
+ private String processId = null;
/**
*
@@ -145,4 +147,22 @@
}
return date;
}
+
+ /**
+ *
+ * @return
+ */
+ public String getProcessId()
+ {
+ return processId;
+ }
+
+ /**
+ *
+ * @param processId
+ */
+ public void setProcessId(String processId)
+ {
+ this.processId = processId;
+ }
}
Modified: trunk/workflow/src/resources/portal-workflow-sar/META-INF/jboss-service.xml
===================================================================
--- trunk/workflow/src/resources/portal-workflow-sar/META-INF/jboss-service.xml 2007-01-28
20:08:11 UTC (rev 6108)
+++ trunk/workflow/src/resources/portal-workflow-sar/META-INF/jboss-service.xml 2007-01-28
20:09:47 UTC (rev 6109)
@@ -71,6 +71,9 @@
<depends optional-attribute-name="WorkflowService"
proxy-type="attribute">
portal:service=Workflow,type=WorkflowService
</depends>
+ <depends optional-attribute-name="IdentityServiceController"
proxy-type="attribute">
+ portal:service=Module,type=IdentityServiceController
+ </depends>
<!-- JBPM process definition -->
<attribute name="Process">
<![CDATA[
@@ -81,7 +84,7 @@
</start-state>
<task-node name="request_approval" signal="first">
<task name="approve_publish">
- <assignment
class="org.jboss.portal.core.cms.workflow.PublishAssignmentHandler"/>
+ <assignment
class="org.jboss.portal.cms.workflow.PublishAssignmentHandler"/>
<event type="task-start">
<action
class="org.jboss.portal.cms.workflow.FinalizePublish"/>
</event>
@@ -111,15 +114,14 @@
-->
<attribute name="Overwrite">false</attribute>
<!--
- a comma separated list email addresses of managers that can
- approve/reject content publish requests
-
- TODO: once a GUI is fully integrated with the workflow
- this will be modified to be a list of roles and then
- the corresponding users will be treated as managers
+ a comma separated list of portal roles that are designated
+ to act as workflow managers. They are allowed to
+ approve/reject content publish requests
-->
- <attribute
name="ManagerEmails">sohil.shah@jboss.com,sshah(a)redhat.com</attribute>
- <attribute name="From">do-not-reply(a)jboss.com</attribute>
+ <attribute name="ManagerRoles">Admin</attribute>
+
+ <!-- Now that a manager GUI is integrated..no need for email based manager
screen -->
+ <!--attribute name="From">do-not-reply(a)jboss.com</attribute>
<attribute name="Subject">Content Approval
Requested</attribute>
<attribute name="Body">
<![CDATA[
@@ -141,7 +143,7 @@
<a
href="http://localhost/workflow/reject?pId={7}&manager={8}">Reject</a>
]]>
- </attribute>
+ </attribute-->
<attribute
name="JNDIName">java:portal/ApprovePublishWorkflow</attribute>
</mbean>
</server>