mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged BRANCHES/DEV/V4.0-BUG-FIX to HEAD:
35637: RemoteCredentialsService and RemoteAlfrescoTicketService, with tests git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@35639 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.remoteconnector;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
import org.alfresco.service.cmr.remoteconnector.RemoteConnectorRequest;
|
||||
import org.alfresco.service.cmr.remoteconnector.RemoteConnectorResponse;
|
||||
import org.alfresco.service.cmr.remoteconnector.RemoteConnectorService;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
||||
import org.alfresco.repo.web.scripts.servlet.BasicHttpAuthenticatorFactory;
|
||||
import org.alfresco.repo.web.scripts.servlet.BasicHttpAuthenticatorFactory.BasicHttpAuthenticator;
|
||||
import org.apache.commons.httpclient.Header;
|
||||
import org.apache.commons.httpclient.HttpMethodBase;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.springframework.extensions.webscripts.Authenticator;
|
||||
import org.springframework.extensions.webscripts.Status;
|
||||
import org.springframework.extensions.webscripts.TestWebScriptServer;
|
||||
import org.springframework.extensions.webscripts.TestWebScriptServer.Request;
|
||||
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
|
||||
import org.springframework.extensions.webscripts.servlet.ServletAuthenticatorFactory;
|
||||
import org.springframework.extensions.webscripts.servlet.WebScriptServletRequest;
|
||||
import org.springframework.extensions.webscripts.servlet.WebScriptServletResponse;
|
||||
|
||||
/**
|
||||
* Testing implementation of {@link RemoteConnectorService} which talks to
|
||||
* the local webscripts only
|
||||
*
|
||||
* @author Nick Burch
|
||||
* @since 4.0.2
|
||||
*/
|
||||
public class LocalWebScriptConnectorServiceImpl implements RemoteConnectorService
|
||||
{
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static Log logger = LogFactory.getLog(LocalWebScriptConnectorServiceImpl.class);
|
||||
|
||||
private WebScriptHelper helper;
|
||||
private LocalAndRemoteAuthenticator auth;
|
||||
|
||||
public LocalWebScriptConnectorServiceImpl(BaseWebScriptTest webScriptTest) throws Exception
|
||||
{
|
||||
this.helper = new WebScriptHelper(webScriptTest);
|
||||
this.auth = new LocalAndRemoteAuthenticator(webScriptTest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new Request object
|
||||
*/
|
||||
public RemoteConnectorRequest buildRequest(String url, String method)
|
||||
{
|
||||
// Ensure we accept this URL
|
||||
String local = "http://localhost:8080/alfresco/";
|
||||
String service = "/service/";
|
||||
if (url.startsWith(local))
|
||||
{
|
||||
// Good, that's probably us, make it a relative url
|
||||
url = url.substring(local.length()-1);
|
||||
|
||||
// Make sure it's a service one
|
||||
if (url.startsWith(service))
|
||||
{
|
||||
// Strip off and use
|
||||
url = url.substring(service.length()-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("Only /service/ local URLs are supported, can't handle " + url);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("Not a local URL: " + url);
|
||||
}
|
||||
|
||||
// Build and return
|
||||
return new RemoteConnectorRequestImpl(url, method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new Request object, using HttpClient method descriptions
|
||||
*/
|
||||
public RemoteConnectorRequest buildRequest(String url, Class<? extends HttpMethodBase> method)
|
||||
{
|
||||
// Get the method name
|
||||
String methodName;
|
||||
try
|
||||
{
|
||||
HttpMethodBase httpMethod = method.getConstructor(String.class).newInstance(url);
|
||||
methodName = httpMethod.getName();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Error identifying method name", e);
|
||||
}
|
||||
|
||||
// Build and return
|
||||
return buildRequest(url, methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the specified request, and return the response
|
||||
*/
|
||||
public RemoteConnectorResponse executeRequest(RemoteConnectorRequest request) throws IOException, AuthenticationException
|
||||
{
|
||||
// Convert the request object
|
||||
RemoteConnectorRequestImpl requestImpl = (RemoteConnectorRequestImpl)request;
|
||||
Request req = new Request(request.getMethod(), request.getURL());
|
||||
req.setType(request.getContentType());
|
||||
|
||||
if (request.getRequestBody() != null)
|
||||
{
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
requestImpl.getRequestBody().writeRequest(baos);
|
||||
req.setBody(baos.toByteArray());
|
||||
}
|
||||
|
||||
// Log
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Performing local " + request.getMethod() + " request to " + request.getURL());
|
||||
|
||||
// Capture the user details, as they may be changed during the request processing
|
||||
Authentication fullAuth = AuthenticationUtil.getFullAuthentication();
|
||||
String runAsUser = AuthenticationUtil.getRunAsUser();
|
||||
|
||||
// If they've specified Authentication details in the request, clear our security context
|
||||
// and switch to that user, to avoid our context confusing the real request
|
||||
Header authHeader = null;
|
||||
Map<String,String> headers = new HashMap<String, String>();
|
||||
for (Header header : request.getRequestHeaders())
|
||||
{
|
||||
if (header.getName().equals("Authorization"))
|
||||
{
|
||||
authHeader = header;
|
||||
}
|
||||
headers.put(header.getName(), header.getValue());
|
||||
}
|
||||
if (authHeader != null)
|
||||
{
|
||||
AuthenticationUtil.clearCurrentSecurityContext();
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("HTTP Authorization found for the request, clearing security context, Auth is " + authHeader);
|
||||
}
|
||||
req.setHeaders(headers);
|
||||
|
||||
// Execute the request against the WebScript Test Framework
|
||||
Response resp;
|
||||
try
|
||||
{
|
||||
resp = helper.sendRequest(req, -1);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Problem requesting", e);
|
||||
}
|
||||
|
||||
// Reset the user details, now we're done performing the request
|
||||
AuthenticationUtil.setFullAuthentication(fullAuth);
|
||||
if (runAsUser != null && !runAsUser.equals(fullAuth.getName()))
|
||||
{
|
||||
AuthenticationUtil.setRunAsUser(runAsUser);
|
||||
}
|
||||
|
||||
// Log
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Response to request was " + resp.getStatus() + " - " + resp);
|
||||
|
||||
// Check the status
|
||||
if (resp.getStatus() == Status.STATUS_UNAUTHORIZED)
|
||||
{
|
||||
throw new AuthenticationException("Not Authorized to access this resource");
|
||||
}
|
||||
if (resp.getStatus() == Status.STATUS_FORBIDDEN)
|
||||
{
|
||||
throw new AuthenticationException("Forbidden to access this resource");
|
||||
}
|
||||
// TODO Handle others too
|
||||
|
||||
// Convert the response
|
||||
String charset = null;
|
||||
String contentType = resp.getContentType();
|
||||
if (contentType != null && contentType.contains("charset="))
|
||||
{
|
||||
int splitAt = contentType.indexOf("charset=") + "charset=".length();
|
||||
charset = contentType.substring(splitAt);
|
||||
}
|
||||
|
||||
InputStream body = new ByteArrayInputStream(resp.getContentAsByteArray());
|
||||
Header[] respHeaders = new Header[0]; // TODO Can't easily get the list...
|
||||
|
||||
RemoteConnectorResponse response = new RemoteConnectorResponseImpl(request, contentType, charset, respHeaders, body);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given request, requesting a JSON response, and
|
||||
* returns the parsed JSON received back
|
||||
*
|
||||
* @throws ParseException If the response is not valid JSON
|
||||
*/
|
||||
public JSONObject executeJSONRequest(RemoteConnectorRequest request) throws ParseException, IOException, AuthenticationException
|
||||
{
|
||||
return RemoteConnectorServiceImpl.doExecuteJSONRequest(request, this);
|
||||
}
|
||||
|
||||
private static class WebScriptHelper
|
||||
{
|
||||
private BaseWebScriptTest test;
|
||||
private Method sendRequest;
|
||||
|
||||
private WebScriptHelper(BaseWebScriptTest test) throws Exception
|
||||
{
|
||||
this.test = test;
|
||||
|
||||
sendRequest = BaseWebScriptTest.class.getDeclaredMethod("sendRequest", Request.class, Integer.TYPE);
|
||||
sendRequest.setAccessible(true);
|
||||
}
|
||||
|
||||
private Response sendRequest(Request request, int expectedStatus) throws Exception
|
||||
{
|
||||
return (Response)sendRequest.invoke(test, request, expectedStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper around {@link BasicHttpAuthenticator}, which uses the
|
||||
* Authentication Context if present, otherwise HTTP Auth
|
||||
*/
|
||||
private static class LocalAndRemoteAuthenticator implements ServletAuthenticatorFactory
|
||||
{
|
||||
private BasicHttpAuthenticatorFactory httpAuthFactory;
|
||||
|
||||
private LocalAndRemoteAuthenticator(BaseWebScriptTest test) throws Exception
|
||||
{
|
||||
// Get the test server
|
||||
Method getServer = BaseWebScriptTest.class.getDeclaredMethod("getServer");
|
||||
getServer.setAccessible(true);
|
||||
TestWebScriptServer server = (TestWebScriptServer)getServer.invoke(test);
|
||||
|
||||
// Grab the real auth factory from the context
|
||||
httpAuthFactory = (BasicHttpAuthenticatorFactory)server.getApplicationContext().getBean("webscripts.authenticator.basic");
|
||||
|
||||
// Wire us into the test
|
||||
server.setServletAuthenticatorFactory(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authenticator create(WebScriptServletRequest req, WebScriptServletResponse res)
|
||||
{
|
||||
// Do we have current details?
|
||||
if (AuthenticationUtil.getFullyAuthenticatedUser() != null)
|
||||
{
|
||||
// There are already details existing
|
||||
// Allow these to be kept and used
|
||||
logger.debug("Existing Authentication found, remaining as " + AuthenticationUtil.getFullyAuthenticatedUser());
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fall back to the http auth one
|
||||
logger.debug("No existing Authentication found, using regular HTTP Auth");
|
||||
return httpAuthFactory.create(req, res);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.remoteticket;
|
||||
|
||||
import org.alfresco.service.cmr.remoteticket.NoCredentialsFoundException;
|
||||
import org.alfresco.service.cmr.remoteticket.NoSuchSystemException;
|
||||
import org.alfresco.service.cmr.remoteticket.RemoteAlfrescoTicketInfo;
|
||||
import org.alfresco.service.cmr.remoteticket.RemoteAlfrescoTicketService;
|
||||
import org.alfresco.repo.remoteconnector.LocalWebScriptConnectorServiceImpl;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cache.EhCacheAdapter;
|
||||
import org.alfresco.repo.remotecredentials.PasswordCredentialsInfoImpl;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
||||
import org.alfresco.service.cmr.remotecredentials.BaseCredentialsInfo;
|
||||
import org.alfresco.service.cmr.remotecredentials.RemoteCredentialsService;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
|
||||
/**
|
||||
* Tests for {@link RemoteAlfrescoTicketServiceImpl}, which work by
|
||||
* looping back to the local repo. Because this tests talks to local
|
||||
* webscripts, it needs to be run in the Remote API package
|
||||
*
|
||||
* TODO Test OAuth support, once added
|
||||
*
|
||||
* @author Nick Burch
|
||||
* @since 4.0.2
|
||||
*/
|
||||
public class RemoteAlfrescoTicketServiceTest extends BaseWebScriptTest
|
||||
{
|
||||
private static final String TEST_REMOTE_SYSTEM_ID = "testingRemoteSystem";
|
||||
private static final String INVALID_REMOTE_SYSTEM_ID = "testingInvalidRemoteSystem";
|
||||
|
||||
private MutableAuthenticationService authenticationService;
|
||||
private RetryingTransactionHelper retryingTransactionHelper;
|
||||
private PersonService personService;
|
||||
|
||||
private RemoteAlfrescoTicketService remoteAlfrescoTicketService;
|
||||
private RemoteCredentialsService remoteCredentialsService;
|
||||
private EhCacheAdapter<String, String> ticketsCache;
|
||||
|
||||
private static final String USER_ONE = "UserOneSecondToo";
|
||||
private static final String USER_TWO = "UserTwoSecondToo";
|
||||
private static final String PASSWORD = "passwordTEST";
|
||||
|
||||
// General methods
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
this.retryingTransactionHelper = (RetryingTransactionHelper)getServer().getApplicationContext().getBean("retryingTransactionHelper");
|
||||
this.authenticationService = (MutableAuthenticationService)getServer().getApplicationContext().getBean("AuthenticationService");
|
||||
this.personService = (PersonService)getServer().getApplicationContext().getBean("PersonService");
|
||||
|
||||
this.remoteAlfrescoTicketService = (RemoteAlfrescoTicketService)getServer().getApplicationContext().getBean("remoteAlfrescoTicketService");
|
||||
this.remoteCredentialsService = (RemoteCredentialsService)getServer().getApplicationContext().getBean("RemoteCredentialsService");
|
||||
this.ticketsCache = (EhCacheAdapter<String, String>)getServer().getApplicationContext().getBean("remoteAlfrescoTicketService.ticketsCache");
|
||||
|
||||
// Do the setup as admin
|
||||
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
|
||||
|
||||
// Add our local system as a remote service
|
||||
remoteAlfrescoTicketService.registerRemoteSystem(TEST_REMOTE_SYSTEM_ID, "http://localhost:8080/alfresco/service/", null);
|
||||
|
||||
// Wire up the loop-back connector
|
||||
((RemoteAlfrescoTicketServiceImpl)remoteAlfrescoTicketService).setRemoteConnectorService(
|
||||
new LocalWebScriptConnectorServiceImpl(this));
|
||||
|
||||
// Ensure the invalid one isn't registered
|
||||
remoteAlfrescoTicketService.registerRemoteSystem(INVALID_REMOTE_SYSTEM_ID, null, null);
|
||||
|
||||
// Create users
|
||||
createUser(USER_ONE);
|
||||
createUser(USER_TWO);
|
||||
|
||||
// Do tests as first user
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception
|
||||
{
|
||||
super.tearDown();
|
||||
|
||||
// Admin user required to delete user
|
||||
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
|
||||
|
||||
// Delete the users, which also zaps their credentials
|
||||
if(personService.personExists(USER_ONE))
|
||||
{
|
||||
personService.deletePerson(USER_ONE);
|
||||
}
|
||||
if(this.authenticationService.authenticationExists(USER_ONE))
|
||||
{
|
||||
this.authenticationService.deleteAuthentication(USER_ONE);
|
||||
}
|
||||
|
||||
if(personService.personExists(USER_TWO))
|
||||
{
|
||||
personService.deletePerson(USER_TWO);
|
||||
}
|
||||
if(this.authenticationService.authenticationExists(USER_TWO))
|
||||
{
|
||||
this.authenticationService.deleteAuthentication(USER_TWO);
|
||||
}
|
||||
|
||||
// Unregister the system
|
||||
remoteAlfrescoTicketService.registerRemoteSystem(TEST_REMOTE_SYSTEM_ID, null, null);
|
||||
}
|
||||
|
||||
private void createUser(String userName)
|
||||
{
|
||||
// if user with given user name doesn't already exist then create user
|
||||
if (this.authenticationService.authenticationExists(userName) == false)
|
||||
{
|
||||
// create user
|
||||
this.authenticationService.createAuthentication(userName, PASSWORD.toCharArray());
|
||||
|
||||
// create person properties
|
||||
PropertyMap personProps = new PropertyMap();
|
||||
personProps.put(ContentModel.PROP_USERNAME, userName);
|
||||
personProps.put(ContentModel.PROP_FIRSTNAME, "First");
|
||||
personProps.put(ContentModel.PROP_LASTNAME, "Last");
|
||||
personProps.put(ContentModel.PROP_EMAIL, "FirstName123.LastName123@email.com");
|
||||
personProps.put(ContentModel.PROP_JOBTITLE, "JobTitle123");
|
||||
personProps.put(ContentModel.PROP_JOBTITLE, "Organisation123");
|
||||
|
||||
// create person node for user
|
||||
this.personService.createPerson(personProps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting, storing and fetching credentials
|
||||
*/
|
||||
public void testGetStoreGetCredentials() throws Exception
|
||||
{
|
||||
// Run this test initially as the first user
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE);
|
||||
|
||||
|
||||
// First, try an invalid system
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.getRemoteCredentials(INVALID_REMOTE_SYSTEM_ID);
|
||||
fail("Shouldn't work for an invalid system");
|
||||
}
|
||||
catch(NoSuchSystemException e) {}
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.storeRemoteCredentials(INVALID_REMOTE_SYSTEM_ID, null, null);
|
||||
fail("Shouldn't work for an invalid system");
|
||||
}
|
||||
catch(NoSuchSystemException e) {}
|
||||
|
||||
|
||||
// Our user starts out without credentials
|
||||
BaseCredentialsInfo credentials =
|
||||
remoteAlfrescoTicketService.getRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(null, credentials);
|
||||
|
||||
|
||||
// Try to store some invalid credentials (real user, but password wrong)
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.storeRemoteCredentials(TEST_REMOTE_SYSTEM_ID, USER_ONE, "invalid");
|
||||
fail("Credentials invalid, shouldn't be allowed");
|
||||
}
|
||||
catch (AuthenticationException e) {}
|
||||
|
||||
// And an invalid user
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.storeRemoteCredentials(TEST_REMOTE_SYSTEM_ID, "thisUSERdoesNOTexist", "invalid");
|
||||
fail("Credentials invalid, shouldn't be allowed");
|
||||
}
|
||||
catch (AuthenticationException e) {}
|
||||
|
||||
|
||||
// Still none there
|
||||
credentials = remoteAlfrescoTicketService.getRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(null, credentials);
|
||||
|
||||
|
||||
// Store some valid ones
|
||||
credentials = remoteAlfrescoTicketService.storeRemoteCredentials(TEST_REMOTE_SYSTEM_ID, USER_ONE, PASSWORD);
|
||||
assertNotNull(credentials);
|
||||
assertEquals(TEST_REMOTE_SYSTEM_ID, credentials.getRemoteSystemName());
|
||||
assertEquals(USER_ONE, credentials.getRemoteUsername());
|
||||
|
||||
// Check we can find them
|
||||
credentials = remoteAlfrescoTicketService.getRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(credentials);
|
||||
assertEquals(TEST_REMOTE_SYSTEM_ID, credentials.getRemoteSystemName());
|
||||
assertEquals(USER_ONE, credentials.getRemoteUsername());
|
||||
|
||||
|
||||
// Store some different, valid credentials for the user
|
||||
credentials = remoteAlfrescoTicketService.storeRemoteCredentials(TEST_REMOTE_SYSTEM_ID, USER_TWO, PASSWORD);
|
||||
assertNotNull(credentials);
|
||||
assertEquals(TEST_REMOTE_SYSTEM_ID, credentials.getRemoteSystemName());
|
||||
assertEquals(USER_TWO, credentials.getRemoteUsername());
|
||||
|
||||
// Check we see the change
|
||||
credentials = remoteAlfrescoTicketService.getRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(credentials);
|
||||
assertEquals(TEST_REMOTE_SYSTEM_ID, credentials.getRemoteSystemName());
|
||||
assertEquals(USER_TWO, credentials.getRemoteUsername());
|
||||
|
||||
|
||||
// Switch to the other user, no credentials there
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(USER_TWO);
|
||||
credentials = remoteAlfrescoTicketService.getRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(null, credentials);
|
||||
|
||||
|
||||
// Switch back, and delete
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE);
|
||||
credentials = remoteAlfrescoTicketService.getRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(credentials);
|
||||
|
||||
boolean deleted = remoteAlfrescoTicketService.deleteRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(true, deleted);
|
||||
|
||||
// Will have gone
|
||||
credentials = remoteAlfrescoTicketService.getRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(null, credentials);
|
||||
|
||||
// Double delete is reported
|
||||
deleted = remoteAlfrescoTicketService.deleteRemoteCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(false, deleted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting cached and non-cached credentials
|
||||
*/
|
||||
public void testGetTicket() throws Exception
|
||||
{
|
||||
// Run this test initially as the first user
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE);
|
||||
|
||||
|
||||
// First, try an invalid system
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.getAlfrescoTicket(INVALID_REMOTE_SYSTEM_ID);
|
||||
fail("Shouldn't work for an invalid system");
|
||||
}
|
||||
catch(NoSuchSystemException e) {}
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.refetchAlfrescoTicket(INVALID_REMOTE_SYSTEM_ID);
|
||||
fail("Shouldn't work for an invalid system");
|
||||
}
|
||||
catch(NoSuchSystemException e) {}
|
||||
|
||||
|
||||
// Can't get or refresh if no credentials exist
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.getAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
fail("Shouldn't work when no credentials");
|
||||
}
|
||||
catch(NoCredentialsFoundException e) {}
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.refetchAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
fail("Shouldn't work when no credentials");
|
||||
}
|
||||
catch(NoCredentialsFoundException e) {}
|
||||
|
||||
|
||||
// Have some stored
|
||||
remoteAlfrescoTicketService.storeRemoteCredentials(TEST_REMOTE_SYSTEM_ID, USER_ONE, PASSWORD);
|
||||
|
||||
|
||||
// A ticket will now exist
|
||||
RemoteAlfrescoTicketInfo ticket = remoteAlfrescoTicketService.getAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(ticket);
|
||||
assertNotNull(ticket.getAsUrlParameters());
|
||||
|
||||
|
||||
// Ask again, will get the same one
|
||||
RemoteAlfrescoTicketInfo ticket2 = remoteAlfrescoTicketService.getAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(ticket2);
|
||||
assertEquals(ticket.getAsUrlParameters(), ticket2.getAsUrlParameters());
|
||||
|
||||
|
||||
// Force a re-fetch, will get another
|
||||
RemoteAlfrescoTicketInfo ticket3 = remoteAlfrescoTicketService.refetchAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(ticket3);
|
||||
assertNotSame(ticket.getAsUrlParameters(), ticket3.getAsUrlParameters());
|
||||
|
||||
// Ask for the ticket again, get the 2nd one again
|
||||
RemoteAlfrescoTicketInfo ticket4 = remoteAlfrescoTicketService.getAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(ticket4);
|
||||
assertEquals(ticket3.getAsUrlParameters(), ticket4.getAsUrlParameters());
|
||||
|
||||
|
||||
// Zap from the cache, will trigger another to be fetched
|
||||
ticketsCache.clear();
|
||||
|
||||
RemoteAlfrescoTicketInfo ticket5 = remoteAlfrescoTicketService.getAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(ticket5);
|
||||
assertNotSame(ticket.getAsUrlParameters(), ticket5.getAsUrlParameters());
|
||||
assertNotSame(ticket3.getAsUrlParameters(), ticket5.getAsUrlParameters());
|
||||
|
||||
|
||||
// Change the password so it's no longer valid
|
||||
PasswordCredentialsInfoImpl creds = (PasswordCredentialsInfoImpl)remoteCredentialsService.getPersonCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(creds);
|
||||
creds.setRemotePassword("INVALID");
|
||||
remoteCredentialsService.updateCredentials(creds);
|
||||
|
||||
// Currently will be marked as still working
|
||||
assertEquals(true, creds.getLastAuthenticationSucceeded());
|
||||
|
||||
|
||||
// Get will work, as ticket was previously cached
|
||||
RemoteAlfrescoTicketInfo ticket6 = remoteAlfrescoTicketService.getAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(ticket6);
|
||||
assertEquals(ticket5.getAsUrlParameters(), ticket6.getAsUrlParameters());
|
||||
|
||||
// Re-fetch will fail with authentication error
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.refetchAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
fail("Shouldn't be able to refetch with wrong details");
|
||||
}
|
||||
catch(AuthenticationException e) {}
|
||||
|
||||
// Now a get will fail too, as the cache will be invalidated
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.getAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
fail("Shouldn't be able to get after refresh with wrong details");
|
||||
}
|
||||
catch(AuthenticationException e) {}
|
||||
|
||||
|
||||
// If we check the credentials, will now be marked as failing
|
||||
creds = (PasswordCredentialsInfoImpl)remoteCredentialsService.getPersonCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(false, creds.getLastAuthenticationSucceeded());
|
||||
|
||||
|
||||
// Change the password back to what it should be, and re-get
|
||||
creds.setRemotePassword(PASSWORD);
|
||||
remoteCredentialsService.updateCredentials(creds);
|
||||
|
||||
RemoteAlfrescoTicketInfo ticket7 = remoteAlfrescoTicketService.getAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
assertNotNull(ticket7);
|
||||
assertNotSame(ticket.getAsUrlParameters(), ticket7.getAsUrlParameters());
|
||||
assertNotSame(ticket3.getAsUrlParameters(), ticket7.getAsUrlParameters());
|
||||
assertNotSame(ticket5.getAsUrlParameters(), ticket7.getAsUrlParameters());
|
||||
|
||||
// Should now be marked as working again
|
||||
creds = (PasswordCredentialsInfoImpl)remoteCredentialsService.getPersonCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(true, creds.getLastAuthenticationSucceeded());
|
||||
|
||||
|
||||
// Check that failure can be marked in a read only transaction
|
||||
creds.setRemotePassword("INVALID");
|
||||
remoteCredentialsService.updateCredentials(creds);
|
||||
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||
public Void execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
remoteAlfrescoTicketService.refetchAlfrescoTicket(TEST_REMOTE_SYSTEM_ID);
|
||||
fail("Shouldn't be able to refetch with wrong details");
|
||||
}
|
||||
catch(AuthenticationException e) {}
|
||||
return null;
|
||||
}
|
||||
}, true, true);
|
||||
|
||||
// Check it was still marked as invalid, despite a read only transaction
|
||||
creds = (PasswordCredentialsInfoImpl)remoteCredentialsService.getPersonCredentials(TEST_REMOTE_SYSTEM_ID);
|
||||
assertEquals(false, creds.getLastAuthenticationSucceeded());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user