From 6f8b21034165a3ab1d546b397f153355277c8b60 Mon Sep 17 00:00:00 2001 From: Gavin Cornwell Date: Mon, 6 Jun 2011 20:36:57 +0000 Subject: [PATCH] ALF-8615: ACTVT 106: Alfresco WAR includes all the necessary assets to run the Activiti Admin UI ALF-8616: ACTVT 107: Enterprise build overlays required Activiti Admin UI files NOTE: To get the Activiti Admin UI you need to do an Enterprise build. If you're using the exploded targets there are no extra steps. If you are using the default, WAR based targets you will first need to run "ant include-activiti-admin-ui" in the 'enterpriseprojects' folder. Due to the way we build our WAR file the original source file has to be changed, there is a potential this may be accidentally comitted, hence the extra manual step. In a continuous build this step is automated and the changes reverted when a new build is performed just as all the other enterprise overlay files are. To see the Activiti Admin UI go to http://localhost:8080/alfresco/activiti-admin. If you login into Explorer first you'll go to straight to the app, otherwise a login dialog will be displayed. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28220 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../web/activiti/ActivitiLoggedInUser.java | 105 ++++++++++ .../web/activiti/AlfrescoLoginHandler.java | 183 ++++++++++++++++++ source/web/WEB-INF/web.xml | 10 +- 3 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 source/java/org/alfresco/repo/web/activiti/ActivitiLoggedInUser.java create mode 100644 source/java/org/alfresco/repo/web/activiti/AlfrescoLoginHandler.java diff --git a/source/java/org/alfresco/repo/web/activiti/ActivitiLoggedInUser.java b/source/java/org/alfresco/repo/web/activiti/ActivitiLoggedInUser.java new file mode 100644 index 0000000000..537d9d7184 --- /dev/null +++ b/source/java/org/alfresco/repo/web/activiti/ActivitiLoggedInUser.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ + +package org.alfresco.repo.web.activiti; + +import org.activiti.explorer.identity.LoggedInUser; + +/** + * Logged in user for Activiti admin ui, based on the authenticated person node + * properties. + * + * @author Frederik Heremans + */ +public class ActivitiLoggedInUser implements LoggedInUser +{ + + private static final long serialVersionUID = 1L; + + private String id; + + private String firstName; + + private String lastName; + + private boolean admin; + + private boolean user; + + public ActivitiLoggedInUser(String id) + { + this.id = id; + } + + public String getFirstName() + { + return firstName; + } + + public String getFullName() + { + return getFirstName() + " " + getLastName(); + } + + public String getId() + { + return id; + } + + public String getLastName() + { + return lastName; + } + + public String getPassword() + { + // Password is not exposed, not needed anymore after authentication + return null; + } + + public boolean isAdmin() + { + return admin; + } + + public boolean isUser() + { + return user; + } + + public void setFirstName(String firstName) + { + this.firstName = firstName; + } + + public void setLastName(String lastName) + { + this.lastName = lastName; + } + + public void setAdmin(boolean admin) + { + this.admin = admin; + } + + public void setUser(boolean user) + { + this.user = user; + } +} diff --git a/source/java/org/alfresco/repo/web/activiti/AlfrescoLoginHandler.java b/source/java/org/alfresco/repo/web/activiti/AlfrescoLoginHandler.java new file mode 100644 index 0000000000..558c131b13 --- /dev/null +++ b/source/java/org/alfresco/repo/web/activiti/AlfrescoLoginHandler.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ + +package org.alfresco.repo.web.activiti; + +import java.io.Serializable; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.activiti.explorer.ExplorerApp; +import org.activiti.explorer.identity.LoggedInUser; +import org.activiti.explorer.ui.login.LoginHandler; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.namespace.QName; + +/** + * Handler for logging in into the Activiti administration UI, authenticates + * against Alfresco {@link AuthenticationService} and + * {@link AuthenticationService}. + * + * @author Frederik Heremans + */ +public class AlfrescoLoginHandler implements LoginHandler +{ + protected AuthenticationService authenticationService; + protected PersonService personService; + protected NodeService nodeService; + protected AuthorityService authorityService; + + @Override + public LoggedInUser authenticate(String userName, String password) + { + LoggedInUser loggedInUser = null; + + if (checkCredentials(userName, password)) + { + // Check if the user has the rights to use administrative + // capabilities + if (authorityService.isAdminAuthority(userName)) + { + loggedInUser = createLoggedInUser(userName); + } + } + return loggedInUser; + } + + @Override + public LoggedInUser authenticate() + { + LoggedInUser loggedInUser = null; + try + { + String authenticatedUser = authenticationService.getCurrentUserName(); + if (authenticatedUser != null && authorityService.isAdminAuthority(authenticatedUser)) + { + loggedInUser = createLoggedInUser(authenticatedUser); + } + } + catch (AuthenticationException ae) + { + // Ignore, no user in current security-context + } + catch(net.sf.acegisecurity.AuthenticationException ae2) + { + // Ignore, no user in current security-context + } + return loggedInUser; + } + + @Override + public void logout(LoggedInUser loggedInUser) + { + // Clear context + authenticationService.clearCurrentSecurityContext(); + } + + protected LoggedInUser createLoggedInUser(String userName) + { + final NodeRef personNode = personService.getPerson(userName); + final Map allProperties = nodeService.getProperties(personNode); + + // Create user based on node properties + final ActivitiLoggedInUser loggedInUser = new ActivitiLoggedInUser(userName); + loggedInUser.setFirstName((String) allProperties.get(ContentModel.PROP_FIRSTNAME)); + loggedInUser.setLastName((String) allProperties.get(ContentModel.PROP_LASTNAME)); + + // Indicate user can use and administer the app + loggedInUser.setUser(true); + loggedInUser.setAdmin(true); + + return loggedInUser; + } + + protected boolean checkCredentials(String userName, String password) + { + try + { + authenticationService.authenticate(userName, password.toCharArray()); + return true; + } + catch (AuthenticationException ae) + { + return false; + } + } + + public void setAuthenticationService(AuthenticationService authenticationService) + { + this.authenticationService = authenticationService; + } + + public void setPersonService(PersonService personService) + { + this.personService = personService; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setAuthorityService(AuthorityService authorityService) + { + this.authorityService = authorityService; + } + + @Override + public void onRequestEnd(HttpServletRequest req, HttpServletResponse res) + { + // Nothing to do here + } + + @Override + public void onRequestStart(HttpServletRequest req, HttpServletResponse res) + { + if(ExplorerApp.get().getLoggedInUser() != null) { + // Revalidate the ticket, if any the user is logged in to make sure all + // calls to alfresco from activiti happen in right security context + try + { + authenticationService.validate(authenticationService.getCurrentTicket()); + } + catch (AuthenticationException ae) + { + ticketExpired(); + } + catch(net.sf.acegisecurity.AuthenticationException ae2) + { + ticketExpired(); + } + } + } + + private void ticketExpired() + { + ExplorerApp.get().close(); + } + +} diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml index ce57bae73b..a3f30d4e89 100644 --- a/source/web/WEB-INF/web.xml +++ b/source/web/WEB-INF/web.xml @@ -99,6 +99,8 @@ org.apache.myfaces.ERROR_HANDLING false + + Authentication Filter @@ -321,6 +323,8 @@ com.sun.xml.ws.transport.http.servlet.WSServletContextListener + + @@ -524,7 +528,9 @@ authenticatorServlet org.alfresco.repo.web.scripts.servlet.AuthenticatorServlet - + + + Faces Servlet /faces/* @@ -709,6 +715,8 @@ cmisbrowser /cmisbrowser/* + + 60