Merged V3.2E to HEAD

17246: ETHREEOH-3208: User profiles for users authenticated by immutable subsystems are now read only
         - Introduced MutableAuthenticationService interface, only implemented by Alfresco native authentication service
         - Split out those methods from AuthenticationService that mutate the user store and added isAuthenticationMutable()
         - Now both Alfresco Explorer and Share user profile / password edit link rendering is conditional on isAuthenticationMutable
         - Works with authentication chain containing mixture of internally and externally authenticated users
   17247: Fix failing unit tests
         - rm-public-services-security-context.xml needed to be brought in line with public-services-security-context.xml (and will forever more!)
   17248: ETHREEOH-1593: alfUser cookie value should be base 64 encoded to allow for non-ASCII characters
   17253: *RECORD ONLY* ETHREEOH-2885: web.xml must conform to the schema to work on JBoss

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18098 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2010-01-18 15:32:57 +00:00
parent 3daa7fbf67
commit 9576bd46f5
8 changed files with 49 additions and 30 deletions

View File

@@ -25,6 +25,7 @@
package org.alfresco.web.app.servlet; package org.alfresco.web.app.servlet;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration; import java.util.Enumeration;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
@@ -36,7 +37,6 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.SessionUser; import org.alfresco.repo.SessionUser;
import org.alfresco.repo.management.subsystems.ActivateableBean; import org.alfresco.repo.management.subsystems.ActivateableBean;
@@ -50,7 +50,6 @@ import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
import org.alfresco.web.bean.LoginBean; import org.alfresco.web.bean.LoginBean;
@@ -58,6 +57,8 @@ import org.alfresco.web.bean.repository.User;
import org.alfresco.web.bean.users.UserPreferencesBean; import org.alfresco.web.bean.users.UserPreferencesBean;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.Base64;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.context.support.WebApplicationContextUtils;
@@ -556,13 +557,23 @@ public final class AuthenticationHelper
public static void setUsernameCookie(HttpServletRequest httpRequest, HttpServletResponse httpResponse, String username) public static void setUsernameCookie(HttpServletRequest httpRequest, HttpServletResponse httpResponse, String username)
{ {
Cookie authCookie = getAuthCookie(httpRequest); Cookie authCookie = getAuthCookie(httpRequest);
// Let's Base 64 encode the username so it is a legal cookie value
String encodedUsername;
try
{
encodedUsername = Base64.encodeBytes(username.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
if (authCookie == null) if (authCookie == null)
{ {
authCookie = new Cookie(COOKIE_ALFUSER, username); authCookie = new Cookie(COOKIE_ALFUSER, encodedUsername);
} }
else else
{ {
authCookie.setValue(username); authCookie.setValue(encodedUsername);
} }
authCookie.setPath(httpRequest.getContextPath()); authCookie.setPath(httpRequest.getContextPath());
// TODO: make this configurable - currently 7 days (value in seconds) // TODO: make this configurable - currently 7 days (value in seconds)

View File

@@ -56,7 +56,7 @@ import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
@@ -208,12 +208,12 @@ public class NavigationBean implements Serializable
/** /**
* @param authService The AuthenticationService to set. * @param authService The AuthenticationService to set.
*/ */
public void setAuthenticationService(AuthenticationService authService) public void setAuthenticationService(MutableAuthenticationService authService)
{ {
this.authService = authService; this.authService = authService;
} }
protected AuthenticationService getAuthService() protected MutableAuthenticationService getAuthService()
{ {
if (authService == null) if (authService == null)
this.authService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAuthenticationService(); this.authService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAuthenticationService();
@@ -1024,7 +1024,9 @@ public class NavigationBean implements Serializable
*/ */
public boolean isAllowUserConfig() public boolean isAllowUserConfig()
{ {
return this.clientConfig.getAllowUserConfig(); // For correct behaviour, we ask the authentication chain whether this particular user is mutable
return this.clientConfig.getAllowUserConfig()
&& this.authService.isAuthenticationMutable(this.authService.getCurrentUserName());
} }
@@ -1157,7 +1159,7 @@ public class NavigationBean implements Serializable
UserPreferencesBean preferences; UserPreferencesBean preferences;
/** The Authentication service bean reference */ /** The Authentication service bean reference */
transient private AuthenticationService authService; transient private MutableAuthenticationService authService;
/** The PermissionService reference */ /** The PermissionService reference */
transient private PermissionService permissionService; transient private PermissionService permissionService;

View File

@@ -43,14 +43,13 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.usage.ContentUsageService; import org.alfresco.service.cmr.usage.ContentUsageService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.extensions.surf.util.Pair; import org.springframework.extensions.surf.util.Pair;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
import org.alfresco.web.app.context.UIContextService; import org.alfresco.web.app.context.UIContextService;
@@ -102,7 +101,7 @@ public class CreateUserWizard extends BaseWizardBean
protected String sizeQuotaUnits = null; protected String sizeQuotaUnits = null;
/** AuthenticationService bean reference */ /** AuthenticationService bean reference */
transient private AuthenticationService authenticationService; transient private MutableAuthenticationService authenticationService;
/** PersonService bean reference */ /** PersonService bean reference */
transient private PersonService personService; transient private PersonService personService;
@@ -129,7 +128,7 @@ public class CreateUserWizard extends BaseWizardBean
/** /**
* @param authenticationService The AuthenticationService to set. * @param authenticationService The AuthenticationService to set.
*/ */
public void setAuthenticationService(AuthenticationService authenticationService) public void setAuthenticationService(MutableAuthenticationService authenticationService)
{ {
this.authenticationService = authenticationService; this.authenticationService = authenticationService;
} }
@@ -137,7 +136,7 @@ public class CreateUserWizard extends BaseWizardBean
/** /**
* @return authenticationService * @return authenticationService
*/ */
private AuthenticationService getAuthenticationService() private MutableAuthenticationService getAuthenticationService()
{ {
if (authenticationService == null) if (authenticationService == null)
{ {

View File

@@ -36,7 +36,7 @@ import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.usage.ContentUsageService; import org.alfresco.service.cmr.usage.ContentUsageService;
import org.alfresco.web.app.servlet.DownloadContentServlet; import org.alfresco.web.app.servlet.DownloadContentServlet;
@@ -57,7 +57,7 @@ public class UsersBeanProperties implements Serializable
transient private SearchService searchService; transient private SearchService searchService;
/** AuthenticationService bean reference */ /** AuthenticationService bean reference */
transient private AuthenticationService authenticationService; transient private MutableAuthenticationService authenticationService;
/** PersonService bean reference */ /** PersonService bean reference */
transient private PersonService personService; transient private PersonService personService;
@@ -111,7 +111,7 @@ public class UsersBeanProperties implements Serializable
/** /**
* @return the authenticationService * @return the authenticationService
*/ */
public AuthenticationService getAuthenticationService() public MutableAuthenticationService getAuthenticationService()
{ {
//check for null for cluster environment //check for null for cluster environment
if (authenticationService == null) if (authenticationService == null)
@@ -167,7 +167,7 @@ public class UsersBeanProperties implements Serializable
/** /**
* @param authenticationService The AuthenticationService to set. * @param authenticationService The AuthenticationService to set.
*/ */
public void setAuthenticationService(AuthenticationService authenticationService) public void setAuthenticationService(MutableAuthenticationService authenticationService)
{ {
this.authenticationService = authenticationService; this.authenticationService = authenticationService;
} }

View File

@@ -388,6 +388,15 @@ public class UsersDialog extends BaseDialogBean implements IContextListener, Cha
} }
}; };
public NodePropertyResolver resolverUserMutable = new NodePropertyResolver()
{
public Object get(Node personNode)
{
return properties.getAuthenticationService().isAuthenticationMutable(
(String) personNode.getProperties().get("userName"));
}
};
/** /**
* Action handler to show all the users currently in the system * Action handler to show all the users currently in the system
* *
@@ -404,6 +413,7 @@ public class UsersDialog extends BaseDialogBean implements IContextListener, Cha
{ {
node.addPropertyResolver("sizeLatest", this.resolverUserSizeLatest); node.addPropertyResolver("sizeLatest", this.resolverUserSizeLatest);
node.addPropertyResolver("quota", this.resolverUserQuota); node.addPropertyResolver("quota", this.resolverUserQuota);
node.addPropertyResolver("isMutable", this.resolverUserMutable);
} }
// return null to stay on the same page // return null to stay on the same page

View File

@@ -24,8 +24,6 @@
*/ */
package org.alfresco.web.bean.wizard; package org.alfresco.web.bean.wizard;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable; import java.io.Serializable;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.HashMap; import java.util.HashMap;
@@ -48,13 +46,12 @@ import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
import org.alfresco.web.app.context.UIContextService; import org.alfresco.web.app.context.UIContextService;
import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Node;
@@ -101,7 +98,7 @@ public class NewUserWizard extends AbstractWizardBean
private NodeRef homeSpaceLocation = null; private NodeRef homeSpaceLocation = null;
/** AuthenticationService bean reference */ /** AuthenticationService bean reference */
transient private AuthenticationService authenticationService; transient private MutableAuthenticationService authenticationService;
/** NamespaceService bean reference */ /** NamespaceService bean reference */
transient private NamespaceService namespaceService; transient private NamespaceService namespaceService;
@@ -131,12 +128,12 @@ public class NewUserWizard extends AbstractWizardBean
/** /**
* @param authenticationService The AuthenticationService to set. * @param authenticationService The AuthenticationService to set.
*/ */
public void setAuthenticationService(AuthenticationService authenticationService) public void setAuthenticationService(MutableAuthenticationService authenticationService)
{ {
this.authenticationService = authenticationService; this.authenticationService = authenticationService;
} }
private AuthenticationService getAuthenticationService() private MutableAuthenticationService getAuthenticationService()
{ {
if (authenticationService == null) if (authenticationService == null)
{ {

View File

@@ -36,7 +36,7 @@ import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseSpringTest; import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.TestWithUserUtils; import org.alfresco.util.TestWithUserUtils;
@@ -105,7 +105,7 @@ public class FormsTest
assertNotNull(fileFolderService); assertNotNull(fileFolderService);
this.formsService = (FormsService)super.applicationContext.getBean("FormsService"); this.formsService = (FormsService)super.applicationContext.getBean("FormsService");
assertNotNull(this.formsService); assertNotNull(this.formsService);
final AuthenticationService authenticationService = (AuthenticationService) final MutableAuthenticationService authenticationService = (MutableAuthenticationService)
applicationContext.getBean("authenticationService"); applicationContext.getBean("authenticationService");
authenticationService.clearCurrentSecurityContext(); authenticationService.clearCurrentSecurityContext();
final MutableAuthenticationDao authenticationDAO = (MutableAuthenticationDao) final MutableAuthenticationDao authenticationDAO = (MutableAuthenticationDao)

View File

@@ -138,10 +138,10 @@
<f:facet name="header"> <f:facet name="header">
<h:outputText value="#{msg.actions}" /> <h:outputText value="#{msg.actions}" />
</f:facet> </f:facet>
<a:actionLink value="#{msg.modify}" image="/images/icons/edituser.gif" showLink="false" action="wizard:editUser" actionListener="#{DialogManager.bean.setupUserAction}"> <a:actionLink rendered="#{r.isMutable}" value="#{msg.modify}" image="/images/icons/edituser.gif" showLink="false" action="wizard:editUser" actionListener="#{DialogManager.bean.setupUserAction}">
<f:param name="id" value="#{r.id}" /> <f:param name="id" value="#{r.id}" />
</a:actionLink> </a:actionLink>
<a:actionLink value="#{msg.change_password}" image="/images/icons/change_password.gif" showLink="false" action="dialog:changePassword" actionListener="#{DialogManager.bean.setupUserAction}"> <a:actionLink rendered="#{r.isMutable}" value="#{msg.change_password}" image="/images/icons/change_password.gif" showLink="false" action="dialog:changePassword" actionListener="#{DialogManager.bean.setupUserAction}">
<f:param name="id" value="#{r.id}" /> <f:param name="id" value="#{r.id}" />
</a:actionLink> </a:actionLink>
<a:booleanEvaluator value="#{r.userName != 'admin'}"> <a:booleanEvaluator value="#{r.userName != 'admin'}">