/* * Copyright (c) 2008-2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.auth; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.NewCookie; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.emc.storageos.model.auth.AuthnUpdateParam; import com.emc.storageos.model.auth.RoleAssignmentChanges; import com.emc.storageos.model.auth.RoleAssignmentEntry; import com.emc.storageos.model.tenant.TenantResponse; import com.sun.jersey.api.client.*; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.client.filter.ClientFilter; import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; import com.sun.jersey.api.client.filter.LoggingFilter; import com.emc.storageos.api.service.ApiTestBase; import com.emc.storageos.model.password.PasswordResetParam; import com.emc.storageos.services.util.EnvConfig; /** * Basic unit tests for authentication service */ public class AuthSvcTests extends ApiTestBase { private static final String PASSWORD = EnvConfig.get("sanity", "authsvc.AuthSvcTests.password"); private static final String USER_NAME = EnvConfig.get("sanity", "authsvc.AuthSvcTests.username"); public static String LOCATION_HEADER = "Location"; protected static String baseApiServiceURL; protected static String baseAuthServiceURL; protected static boolean runLongTests = false; protected static boolean runProxyTokenTests = false; protected static int timeToWaitInMinutes = 1; // 1 minute protected static boolean initDone = false; /** * Conveninence method to create a Client, and add authentication info * if desired. If addAuthFilter is set to true, credentials will be added * to a Basic Auth filter, and 302 will be followed manually, adding the auth token * on the final redirect to the service location. If addAuthFilter is set to * false, a regular 302 follow up will be done, no headers or basic auth will be * added. * * @throws NoSuchAlgorithmException */ protected Client createHttpsClient(final String username, final String password, boolean addAuthFilters) throws NoSuchAlgorithmException { // Disable server certificate validation as we are using // self-signed certificate disableCertificateValidation(); final ClientConfig config = new DefaultClientConfig(); final Client c = Client.create(config); c.addFilter(new LoggingFilter()); if (addAuthFilters) { c.setFollowRedirects(false); // do a "modified 302" below with copying the header c.addFilter(new HTTPBasicAuthFilter(username, password)); c.addFilter(new ClientFilter() { @Override public ClientResponse handle(ClientRequest request) throws ClientHandlerException { if (_savedTokens.containsKey(username)) { ArrayList<Object> token = new ArrayList<Object>(); token.add(_savedTokens.get(username)); request.getHeaders().put(AUTH_TOKEN_HEADER, token); } ClientResponse response = getNext().handle(request); if (response.getHeaders() != null && response.getHeaders().get(AUTH_TOKEN_HEADER) != null) { _savedTokens.put(username, response.getHeaders().getFirst(AUTH_TOKEN_HEADER)); } if (response.getHeaders() != null && response.getHeaders().get(AUTH_PROXY_TOKEN_HEADER) != null) { _savedProxyTokens.put(username, response.getHeaders().getFirst(AUTH_PROXY_TOKEN_HEADER)); } if (response.getStatus() == 302) { WebResource wb = c.resource(response.getLocation()); response = wb.header(AUTH_TOKEN_HEADER, _savedTokens.get(username)). get(ClientResponse.class); } return response; } }); } else { // no auth filter, and do a regular 302 follow up, don't copy any auth token. c.setFollowRedirects(true); } return c; } protected Client createCookieHttpsClient(final String username, final String password) throws NoSuchAlgorithmException { // Disable server certificate validation as we are using // self-signed certificate disableCertificateValidation(); final ClientConfig config = new DefaultClientConfig(); final Client c = Client.create(config); c.addFilter(new LoggingFilter()); c.setFollowRedirects(false); c.addFilter(new HTTPBasicAuthFilter(username, password)); c.addFilter(new ClientFilter() { private ArrayList<Object> cookies; private ArrayList<Object> getCookiesToSet() { if (cookies != null && !cookies.isEmpty()) { ArrayList<Object> cookiesToSet = new ArrayList<Object>(); StringBuilder cookieToAdd = new StringBuilder(); for (Object cookieRaw : cookies) { NewCookie cookie = (NewCookie) cookieRaw; cookieToAdd.append(cookie.getName()); cookieToAdd.append("="); cookieToAdd.append(cookie.getValue()); cookieToAdd.append("; "); } cookiesToSet.add(cookieToAdd); return cookiesToSet; } return null; } @Override public ClientResponse handle(ClientRequest request) throws ClientHandlerException { ArrayList<Object> cookiesToSet = getCookiesToSet(); if (cookiesToSet != null) { request.getHeaders().put("Cookie", cookiesToSet); } ClientResponse response = getNext().handle(request); if (response.getCookies() != null) { if (cookies == null) { cookies = new ArrayList<Object>(); } // simple addAll just for illustration (should probably check for duplicates and expired cookies) cookies.addAll(response.getCookies()); } if (response.getStatus() == 302) { WebResource wb = c.resource(response.getLocation()); cookiesToSet = getCookiesToSet(); if (cookiesToSet != null) { response = wb.header("Cookie", cookiesToSet).get(ClientResponse.class); } else { response = wb.get(ClientResponse.class); } } return response; } }); return c; } @Before public synchronized void setup() throws Exception { initLoadBalancer(true); baseAuthServiceURL = baseUrls.get(0); baseApiServiceURL = baseUrls.get(0); if (!initDone) { // only do this once setupLicenseAndInitialPasswords(); initDone = true; } } @Test public void coreTests() throws Exception { String runLongTestsStr = System.getenv("RUN_LONG_TESTS"); runLongTests = (runLongTestsStr != null && runLongTestsStr.equalsIgnoreCase("true")) ? true : false; String runProxyTokenTestsStr = System.getenv("RUN_PROXY_TOKEN_EXPIRY_TESTS"); runProxyTokenTests = (runProxyTokenTestsStr != null && runProxyTokenTestsStr.equalsIgnoreCase("true")) ? true : false; // TOKEN TESTS WebResource rRoot = createHttpsClient(USER_NAME, PASSWORD, true).resource(baseAuthServiceURL); WebResource rSysmonitor = createHttpsClient("sysmonitor", PASSWORD, true).resource(baseAuthServiceURL); ClientResponse resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get(USER_NAME)); String token1 = (String) _savedTokens.get(USER_NAME); WebResource rRootNoHandler = createHttpsClient(USER_NAME, PASSWORD, false).resource(baseAuthServiceURL); resp = rRootNoHandler.path("/login").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); _savedTokens.remove(USER_NAME); resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, token1).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRootNoHandler.path("/logout").header(AUTH_TOKEN_HEADER, token1).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); String expiredToken = token1; _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); String token2 = (String) _savedTokens.get(USER_NAME); Assert.assertFalse(token1.equals(token2)); // bad token and no credentials resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, "bad-token").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); // no credentials and expired token resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, expiredToken).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); // Authenticate three times, save distinct tokens. Then call logout with the force flag. // After that, none of the tokens should work. resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get(USER_NAME)); String multiTokenTestToken1 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get(USER_NAME)); String multiTokenTestToken2 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get(USER_NAME)); String multiTokenTestToken3 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); // verify we have 3 distinct tokens. Three logins with the same user, // should result in 3 distinct tokens. Assert.assertFalse(multiTokenTestToken1.equals(multiTokenTestToken2)); Assert.assertFalse(multiTokenTestToken2.equals(multiTokenTestToken3)); resp = rSysmonitor.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // Try to logout root as the sysmonitor user verify it fails with 403 resp = rSysmonitor.path("/logout").queryParam("username", USER_NAME).get(ClientResponse.class); Assert.assertEquals(403, resp.getStatus()); // All tokens should still be good resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, multiTokenTestToken1).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, multiTokenTestToken2).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, multiTokenTestToken3).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRootNoHandler.path("/logout").header(AUTH_TOKEN_HEADER, multiTokenTestToken1).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // All tokens except the one used in logout should still be good resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, multiTokenTestToken1).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, multiTokenTestToken2).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, multiTokenTestToken3).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // Now call force logout using one of the remaining tokens. This should invalidate // itself and the other remaining one. resp = rRootNoHandler.path("/logout").queryParam("force", "true"). header(AUTH_TOKEN_HEADER, multiTokenTestToken2).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // All tokens should now be expired resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, multiTokenTestToken2).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, multiTokenTestToken3).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); // Login the sysmonitor user a few times and save the tokens resp = rSysmonitor.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get("sysmonitor")); String secadminLogoutTestToken1 = (String) _savedTokens.get("sysmonitor"); _savedTokens.remove("sysmonitor"); resp = rSysmonitor.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get("sysmonitor")); String secadminLogoutTestToken2 = (String) _savedTokens.get("sysmonitor"); _savedTokens.remove("sysmonitor"); resp = rSysmonitor.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get("sysmonitor")); String secadminLogoutTestToken3 = (String) _savedTokens.get("sysmonitor"); resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); String rootToken = (String) _savedTokens.get(USER_NAME); resp = rRoot.path("/logout").queryParam("username", "sysmonitor").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // root token should still be valid resp = rRootNoHandler.path("/login").header(AUTH_TOKEN_HEADER, rootToken).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // All sysmonitor tokens should now be expired WebResource rSysMonitorNoHandler = createHttpsClient("sysmonitor", PASSWORD, false).resource(baseAuthServiceURL); resp = rSysMonitorNoHandler.path("/login").header(AUTH_TOKEN_HEADER, secadminLogoutTestToken1).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rSysMonitorNoHandler.path("/login").header(AUTH_TOKEN_HEADER, secadminLogoutTestToken2).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rSysMonitorNoHandler.path("/login").header(AUTH_TOKEN_HEADER, secadminLogoutTestToken3).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); // TOKEN TESTS WITH ACCESS TO API RESOURCE USING AUTO REDIRECT _savedTokens.clear(); // Access api resource directly with credentials WebResource rApiUser = createHttpsClient(USER_NAME, PASSWORD, true).resource(baseApiServiceURL); WebResource rAuthUser = createHttpsClient(USER_NAME, PASSWORD, true).resource(baseAuthServiceURL); resp = rApiUser.path("/tenant").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // logout String apiUserToken = (String) _savedTokens.get(USER_NAME); resp = rAuthUser.path("/logout").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // Login first, get a token, then use it to access the api resource separately _savedTokens.clear(); resp = rAuthUser.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); apiUserToken = (String) _savedTokens.get(USER_NAME); rApiUser = createHttpsClient("", "", false).resource(baseApiServiceURL); resp = rApiUser.path("/tenant").header(AUTH_TOKEN_HEADER, apiUserToken).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // API access with no credentials or token resp = rApiUser.path("/tenant").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); // COOKIE TESTS rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseAuthServiceURL); resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNull(resp.getHeaders().getFirst(HttpHeaders.SET_COOKIE)); // formlogin tests // Making sure it can filter the cross site scripting attack by not appending source string if source string contains script tag WebResource rRootNoRedirect = createHttpsClient("", "", false).resource(baseAuthServiceURL); resp = rRootNoRedirect.path("/formlogin").queryParam("service", "someService") .queryParam("source", "\"><sCrIpT>alert(14035908.687)</ScRiPt><form \"").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); String entity = resp.getEntity(String.class); Assert.assertTrue(entity.contains("action=")); Assert.assertFalse(entity.contains("\"><sCrIpT>alert(14035908.687)</ScRiPt><form \"")); // get formlogin page from apisvc by using ?using-formlogin // TODO: fix this test once apisvc/login?using-formlogin is working again // (it is currently broken) /* * WebResource formRes = createHttpsClient("", "", false).resource(baseApiServiceURL); * resp = formRes.path("/login").queryParam("using-cookies", "true") * .queryParam("using-formlogin", "true") * .queryParam("service", "someService") * .get(ClientResponse.class); * Assert.assertEquals(200, resp.getStatus()); * String entity = resp.getEntity(String.class); * Assert.assertTrue(entity.contains("form action=")); */ rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseAuthServiceURL); resp = rRoot.path("/login").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(resp.getHeaders().getFirst(HttpHeaders.SET_COOKIE)); String tokenCookie = resp.getHeaders().getFirst(HttpHeaders.SET_COOKIE); Assert.assertTrue(tokenCookie.startsWith(AUTH_TOKEN_HEADER)); rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseApiServiceURL); resp = rRoot.path("/tenant").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRoot.path("/logout").queryParam("force", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRoot.path("/tenant").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); // using-cookies default test rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseApiServiceURL); resp = rRoot.path("/login").queryParam("using-cookies", "").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRoot.path("/logout").queryParam("force", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRoot.path("/tenant").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseApiServiceURL); resp = rRoot.path("/tenant").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseApiServiceURL); resp = rRoot.path("/tenant").queryParam("using-cookies", "false").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); if (runLongTests) { // test limits on number of tokens per user // delete all tokens for root first rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseApiServiceURL); resp = rRoot.path("/tenant").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRoot.path("/logout").queryParam("force", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); rRoot = createHttpsClient(USER_NAME, PASSWORD, true).resource(baseApiServiceURL); _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get(USER_NAME)); rootToken = (String) _savedTokens.get(USER_NAME); for (int i = 0; i < 99; i++) { rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseApiServiceURL); resp = rRoot.path("/tenant").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); } rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseApiServiceURL); resp = rRoot.path("/tenant").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); String error = resp.getEntity(String.class); Assert.assertTrue(error, error.contains("Max number of tokens exceeded for this user")); // logout all rRoot = createHttpsClient("", "", false).resource(baseApiServiceURL); resp = rRoot.path("/logout").queryParam("force", "true") .header(AUTH_TOKEN_HEADER, rootToken).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // new login rRoot = createCookieHttpsClient(USER_NAME, PASSWORD).resource(baseApiServiceURL); resp = rRoot.path("/tenant").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // test limit, same as above, but for proxyuser. proxyuser can have 1000 tokens. // test limits on number of tokens per user // delete all tokens for root first WebResource rProxyUser = createCookieHttpsClient("proxyuser", PASSWORD).resource(baseApiServiceURL); resp = rProxyUser.path("/tenant").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rProxyUser.path("/logout").queryParam("force", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); rProxyUser = createHttpsClient("proxyuser", PASSWORD, true).resource(baseApiServiceURL); _savedTokens.remove("proxyuser"); resp = rProxyUser.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); Assert.assertNotNull(_savedTokens.get("proxyuser")); String proxyUserToken = (String) _savedTokens.get("proxyuser"); for (int i = 0; i < 999; i++) { rProxyUser = createCookieHttpsClient("proxyuser", PASSWORD).resource(baseApiServiceURL); resp = rProxyUser.path("/tenant").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); } rProxyUser = createCookieHttpsClient("proxyuser", PASSWORD).resource(baseApiServiceURL); resp = rProxyUser.path("/tenant").queryParam("using-cookies", "true").get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); Assert.assertTrue(resp.getEntity(String.class).contains("Max number of tokens exceeded for this user")); // logout all rProxyUser = createHttpsClient("proxyuser", PASSWORD, false).resource(baseApiServiceURL); resp = rProxyUser.path("/logout").queryParam("force", "true") .header(AUTH_TOKEN_HEADER, proxyUserToken).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); } if (runProxyTokenTests) { runProxyTokenExpiryTest(); } } private void runProxyTokenExpiryTest() throws Exception { try { String timeToWaitInMinsStr = System.getenv("TIME_TO_WAIT_IN_MINUTES_SET_IN_SECURITY_MODULE_XML"); int timeToWaitInMinutes = Integer.parseInt(timeToWaitInMinsStr); } catch (Exception e) { timeToWaitInMinutes = 1; } WebResource rRoot = createHttpsClient(SYSADMIN, SYSADMIN_PASS_WORD, true).resource(baseAuthServiceURL); rRoot.path("/login").get(ClientResponse.class); // post authProvider updateADConfig(); // login with a user from ldap WebResource rSanityUser = createHttpsClient(ROOTUSER, AD_PASS_WORD, true).resource( baseAuthServiceURL); rSanityUser.path("/login").get(ClientResponse.class); TenantResponse tenant = rSanityUser.path("/tenant").get(TenantResponse.class); // make the user a tenant_admin RoleAssignmentChanges changes = new RoleAssignmentChanges(); RoleAssignmentEntry addTenantAdmin = new RoleAssignmentEntry(); addTenantAdmin.setSubjectId(ROOTUSER); addTenantAdmin.getRoles().add("TENANT_ADMIN"); changes.setAdd(new ArrayList<RoleAssignmentEntry>()); changes.getAdd().add(addTenantAdmin); rRoot.path("/tenants/" + tenant.getTenant() + "/role-assignments").put(changes); // create a proxy token for that user ClientResponse resp = rSanityUser.path("/proxytoken").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); String proxyToken = (String) _savedProxyTokens.get(ROOTUSER); Assert.assertNotNull(proxyToken); // logon with proxyuser WebResource rProxy = createHttpsClient(PROXY_USER, PROXY_USER_PWD, true).resource( baseApiServiceURL); rProxy.path("/login").get(ClientResponse.class); // try to get sanity user's tenant as proxy user with proxy token // should get a 200 resp = rProxy.path("/tenants/" + tenant.getTenant()).header(AUTH_PROXY_TOKEN_HEADER, proxyToken) .get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // wait x amount of time for token to expire Thread.sleep(timeToWaitInMinutes * 60 * 1000); // try to get sanity user's tenant as proxy user with proxy token // should get a 200 again resp = rProxy.path("/tenants/" + tenant.getTenant()).header(AUTH_PROXY_TOKEN_HEADER, proxyToken) .get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // do a put on the authprovider so it is disabled AuthnUpdateParam updateParam = new AuthnUpdateParam(); updateParam.setDisable(true); rRoot.path("/vdc/admin/authnproviders/" + _goodADConfig).put(updateParam); // wait x amount of time for token to expire Thread.sleep(timeToWaitInMinutes * 60 * 1000); // try to get the tenant with proxy user using the proxy token // should fail with a 401 resp = rProxy.path("/tenants/" + tenant.getTenant()).header(AUTH_PROXY_TOKEN_HEADER, proxyToken) .get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); } @Test public void passwordManipulationTests() throws Exception { // TEST 1: change root's password with the logout option. // 1. login with root, get 3 tokens. // 2. change root's password with logout option. Make sure all 3 tokens are gone WebResource rRoot = createHttpsClient(USER_NAME, PASSWORD, true).resource(baseAuthServiceURL); _savedTokens.remove(USER_NAME); ClientResponse resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); String rootToken1 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); String rootToken2 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); String rootToken3 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); resetPassword(USER_NAME, "newp", null, true); rRoot = createHttpsClient("", "", false).resource(baseAuthServiceURL); resp = rRoot.path("/tenant").header(AUTH_TOKEN_HEADER, rootToken1).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rRoot.path("/tenant").header(AUTH_TOKEN_HEADER, rootToken2).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rRoot.path("/tenant").header(AUTH_TOKEN_HEADER, rootToken3).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); // reset root's password to the original resetPassword(USER_NAME, PASSWORD, "newp", true); // TEST 2: change proxy user's password. Make sure root's token is not wiped out. // Only proxyuser's. // 1. Login with proxyuser, 3 times. // 2. have root logout proxyuser _savedTokens.remove("proxyuser"); WebResource rProxy = createHttpsClient("proxyuser", PASSWORD, true).resource(baseAuthServiceURL); resp = rProxy.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); String proxyToken1 = (String) _savedTokens.get("proxyuser"); _savedTokens.remove("proxyuser"); resp = rProxy.path("/login").get(ClientResponse.class); String proxyToken2 = (String) _savedTokens.get("proxyuser"); _savedTokens.remove("proxyuser"); resp = rProxy.path("/login").get(ClientResponse.class); String proxyToken3 = (String) _savedTokens.get("proxyuser"); _savedTokens.remove("proxyuser"); String rootResetToken = resetPassword("proxyuser", "newp", null, true); rProxy = createHttpsClient("", "", false).resource(baseAuthServiceURL); resp = rProxy.path("/tenant").header(AUTH_TOKEN_HEADER, proxyToken1).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rProxy.path("/tenant").header(AUTH_TOKEN_HEADER, proxyToken2).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rProxy.path("/tenant").header(AUTH_TOKEN_HEADER, proxyToken3).get(ClientResponse.class); Assert.assertEquals(401, resp.getStatus()); resp = rProxy.path("/tenant").header(AUTH_TOKEN_HEADER, rootResetToken).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // reset proxyuser password to the original resetPassword("proxyuser", PASSWORD, null, true); // TEST 3: Login root three times. Change its password but with logout=false. None of the // tokens should have been killed. rRoot = createHttpsClient(USER_NAME, PASSWORD, true).resource(baseAuthServiceURL); _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); rootToken1 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); rootToken2 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); resp = rRoot.path("/login").get(ClientResponse.class); rootToken3 = (String) _savedTokens.get(USER_NAME); _savedTokens.remove(USER_NAME); resetPassword(USER_NAME, "newp", null, false); rRoot = createHttpsClient("", "", false).resource(baseAuthServiceURL); resp = rRoot.path("/tenant").header(AUTH_TOKEN_HEADER, rootToken1).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRoot.path("/tenant").header(AUTH_TOKEN_HEADER, rootToken2).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); resp = rRoot.path("/tenant").header(AUTH_TOKEN_HEADER, rootToken3).get(ClientResponse.class); Assert.assertEquals(200, resp.getStatus()); // reset root's password to the original and kill the previous sessions resetPassword(USER_NAME, PASSWORD, "newp", true); } /** * Routine to reset a user's password, with various parameters to account for different * scenarios * * @param user user for which to change the password * @param newPassword new password for the user * @param rootAltPasswd if the password change is happening after root's password was already changed, * provide the current password for the root user, otherwise ChangeMe is assumed. * @param logout true if the sessions of the user need to be terminated as part of the password reset * @return the auth token of the root user's connection that did the reset * @throws NoSuchAlgorithmException */ private String resetPassword(String user, String newPassword, String rootAltPasswd, boolean logout) throws NoSuchAlgorithmException { PasswordResetParam passwordReset = new PasswordResetParam(); passwordReset.setPassword(newPassword); passwordReset.setUsername(user); ClientResponse resp; _savedTokens.remove(USER_NAME); WebResource rRoot = createHttpsClient(USER_NAME, rootAltPasswd == null ? PASSWORD : rootAltPasswd, true). resource(baseAuthServiceURL); resp = rRoot.path("/login").get(ClientResponse.class); String rootResetToken = (String) _savedTokens.get(USER_NAME); Assert.assertEquals(200, resp.getStatus()); resp = rRoot.path("/password/reset/").queryParam("logout_user", Boolean.toString(logout)). put(ClientResponse.class, passwordReset); Assert.assertEquals(200, resp.getStatus()); // if the user whose password was just changed was root, then you need to // relogin with the new password otherwise the cluster check below will fail with 401 if (user.equals(USER_NAME)) { _savedTokens.remove(USER_NAME); rRoot = createHttpsClient(USER_NAME, newPassword, true).resource(baseAuthServiceURL); resp = rRoot.path("/login").get(ClientResponse.class); rootResetToken = (String) _savedTokens.get(USER_NAME); Assert.assertEquals(200, resp.getStatus()); } String info = ""; Boolean notStable = true; while (notStable) { try { Thread.sleep(2000); System.out.println("Waiting for stable cluster state."); } catch (InterruptedException e) { // Empty on purpose } resp = rRoot.path("/upgrade/cluster-state").get(ClientResponse.class); info = resp.getEntity(String.class); if (info.contains("<cluster_state>STABLE</cluster_state>")) { notStable = false; System.out.println("Cluster state is stable."); } } return rootResetToken; } }