From 89602569aebebac22fb1a7c54ac690d47b03bb4f Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Tue, 28 Apr 2015 13:05:27 -0600 Subject: [PATCH 01/11] Bump next develop version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index bcc6e51b451..819d6aab3be 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=2.2.5 +version=2.2.6-SNAPSHOT From bebc1d6635e23c03d76a75d9b12dc0be8cd018d1 Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Wed, 29 Apr 2015 12:39:10 -0600 Subject: [PATCH 02/11] Attempt to keep Java sources files in JAR files rather than directly in a WAR module https://www.pivotaltracker.com/story/show/93097336 [#93097336] --- .../authentication/manager/DynamicLdapAuthenticationManager.java | 0 .../manager/DynamicZoneAwareAuthenticationManager.java | 0 .../cloudfoundry/identity/uaa/zone/IdentityProviderEndpoints.java | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {uaa => login}/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicLdapAuthenticationManager.java (100%) rename {uaa => login}/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicZoneAwareAuthenticationManager.java (100%) rename {uaa => login}/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityProviderEndpoints.java (100%) diff --git a/uaa/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicLdapAuthenticationManager.java b/login/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicLdapAuthenticationManager.java similarity index 100% rename from uaa/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicLdapAuthenticationManager.java rename to login/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicLdapAuthenticationManager.java diff --git a/uaa/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicZoneAwareAuthenticationManager.java b/login/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicZoneAwareAuthenticationManager.java similarity index 100% rename from uaa/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicZoneAwareAuthenticationManager.java rename to login/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/DynamicZoneAwareAuthenticationManager.java diff --git a/uaa/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityProviderEndpoints.java b/login/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityProviderEndpoints.java similarity index 100% rename from uaa/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityProviderEndpoints.java rename to login/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityProviderEndpoints.java From 23d329da6230ff8dbbd4de11ccb7c6e0b05c8ec9 Mon Sep 17 00:00:00 2001 From: Krishna m-Kumar Date: Thu, 19 Mar 2015 18:55:39 +0800 Subject: [PATCH 03/11] Update README.md The current link pointing to a generic doc http://help.github.com/forking/. It must be pointing to the correct UAA repository https://github.com/cloudfoundry/uaa Github contribution for UAA has to be forking this repository. [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc526a45b29..ecdbf9f47ea 100644 --- a/README.md +++ b/README.md @@ -384,7 +384,7 @@ Here are some ways for you to get involved in the community: vote on the ones that you are interested in. * Github is for social coding: if you want to write code, we encourage contributions through pull requests from - [forks of this repository](http://help.github.com/forking/). If you + [forks of this repository](https://github.com/cloudfoundry/uaa). If you want to contribute code this way, please reference an existing issue if there is one as well covering the specific issue you are addressing. Always submit pull requests to the "develop" branch. From 8eb0429e15a941b61a6570179a257a9eaaca350b Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Wed, 29 Apr 2015 12:24:56 -0600 Subject: [PATCH 04/11] Use Client display name if it is available on the profile page https://www.pivotaltracker.com/story/show/92569632 [#92569632] --- .../identity/uaa/login/ProfileController.java | 29 ++++++++-- .../resources/templates/web/approvals.html | 4 +- .../uaa/login/ProfileControllerTests.java | 58 ++++++++++++++----- .../webapp/WEB-INF/spring/oauth-clients.xml | 5 +- .../integration/feature/AppApprovalIT.java | 6 +- 5 files changed, 77 insertions(+), 25 deletions(-) diff --git a/login/src/main/java/org/cloudfoundry/identity/uaa/login/ProfileController.java b/login/src/main/java/org/cloudfoundry/identity/uaa/login/ProfileController.java index 7986e29917e..79a3d647429 100644 --- a/login/src/main/java/org/cloudfoundry/identity/uaa/login/ProfileController.java +++ b/login/src/main/java/org/cloudfoundry/identity/uaa/login/ProfileController.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Cloud Foundry + * Cloud Foundry * Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -14,9 +14,12 @@ import org.cloudfoundry.identity.uaa.authentication.Origin; import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; +import org.cloudfoundry.identity.uaa.client.ClientConstants; import org.cloudfoundry.identity.uaa.oauth.approval.Approval; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @@ -25,20 +28,21 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -/** - * @author Vidya Valmikinathan - */ @Controller public class ProfileController { private final ApprovalsService approvalsService; + private final ClientDetailsService clientDetailsService; @Autowired - public ProfileController(ApprovalsService approvalsService) { + public ProfileController(ApprovalsService approvalsService, + ClientDetailsService clientDetailsService) { this.approvalsService = approvalsService; + this.clientDetailsService = clientDetailsService; } /** @@ -47,11 +51,26 @@ public ProfileController(ApprovalsService approvalsService) { @RequestMapping(value = "/profile", method = RequestMethod.GET) public String get(Authentication authentication, Model model) { Map> approvals = approvalsService.getCurrentApprovalsByClientId(); + Map clientNames = getClientNames(approvals); + model.addAttribute("clientnames", clientNames); model.addAttribute("approvals", approvals); model.addAttribute("isUaaManagedUser", isUaaManagedUser(authentication)); return "approvals"; } + protected Map getClientNames(Map> approvals) { + Map clientNames = new LinkedHashMap<>(); + for (String clientId : approvals.keySet()) { + ClientDetails details = clientDetailsService.loadClientByClientId(clientId); + String name = details.getClientId(); + if (details.getAdditionalInformation()!=null && details.getAdditionalInformation().get(ClientConstants.CLIENT_NAME)!=null) { + name = (String)details.getAdditionalInformation().get(ClientConstants.CLIENT_NAME); + } + clientNames.put(clientId, name); + } + return clientNames; + } + /** * Handle form post for revoking chosen approvals */ diff --git a/login/src/main/resources/templates/web/approvals.html b/login/src/main/resources/templates/web/approvals.html index 310ac6198d1..63201230572 100644 --- a/login/src/main/resources/templates/web/approvals.html +++ b/login/src/main/resources/templates/web/approvals.html @@ -50,7 +50,7 @@

Third Party Access

- Are you sure you want to revoke access to Cloudbees? + Are you sure you want to revoke access to Cloudbees?

diff --git a/login/src/test/java/org/cloudfoundry/identity/uaa/login/ProfileControllerTests.java b/login/src/test/java/org/cloudfoundry/identity/uaa/login/ProfileControllerTests.java index cc406efd7b8..d4a496db574 100644 --- a/login/src/test/java/org/cloudfoundry/identity/uaa/login/ProfileControllerTests.java +++ b/login/src/test/java/org/cloudfoundry/identity/uaa/login/ProfileControllerTests.java @@ -16,6 +16,7 @@ import org.cloudfoundry.identity.uaa.TestClassNullifier; import org.cloudfoundry.identity.uaa.authentication.Origin; import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; +import org.cloudfoundry.identity.uaa.client.ClientConstants; import org.cloudfoundry.identity.uaa.login.test.ThymeleafConfig; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; import org.junit.After; @@ -31,6 +32,8 @@ import org.springframework.context.annotation.Import; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.client.BaseClientDetails; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @@ -53,6 +56,7 @@ import static org.hamcrest.Matchers.hasKey; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasValue; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.springframework.http.MediaType.TEXT_HTML; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -62,21 +66,22 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -/** - * @author Dave Syer - * - */ @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = ProfileControllerTests.ContextConfiguration.class) public class ProfileControllerTests extends TestClassNullifier { + public static final String THE_ULTIMATE_APP = "The Ultimate App"; + @Autowired WebApplicationContext webApplicationContext; @Autowired ApprovalsService approvalsService; + @Autowired + ClientDetailsService clientDetailsService; + private MockMvc mockMvc; @Before @@ -103,6 +108,10 @@ public void setUp() throws Exception { approvalsByClientId.put("app", Arrays.asList(readApproval, writeApproval)); Mockito.when(approvalsService.getCurrentApprovalsByClientId()).thenReturn(approvalsByClientId); + + BaseClientDetails appClient = new BaseClientDetails("app","thing","thing.read,thing.write","authorization_code", ""); + appClient.addAdditionalInformation(ClientConstants.CLIENT_NAME, THE_ULTIMATE_APP); + Mockito.when(clientDetailsService.loadClientByClientId("app")).thenReturn(appClient); } @After @@ -112,19 +121,37 @@ public void tearDown() { @Test public void testGetProfile() throws Exception { + testGetProfile(THE_ULTIMATE_APP); + } + + @Test + public void testGetProfileNoAppName() throws Exception { + BaseClientDetails appClient = new BaseClientDetails("app","thing","thing.read,thing.write","authorization_code", ""); + Mockito.when(clientDetailsService.loadClientByClientId("app")).thenReturn(appClient); + testGetProfile("app"); + } + + + public void testGetProfile(String name) throws Exception { UaaPrincipal uaaPrincipal = new UaaPrincipal("fake-user-id", "username", "email@example.com", Origin.UAA, null, IdentityZoneHolder.get().getId()); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(uaaPrincipal, null); mockMvc.perform(get("/profile").principal(authentication)) - .andExpect(status().isOk()) - .andExpect(model().attribute("isUaaManagedUser", true)) - .andExpect(model().attribute("approvals", hasKey("app"))) - .andExpect(model().attribute("approvals", hasValue(hasSize(2)))) - .andExpect(content().contentTypeCompatibleWith(TEXT_HTML)) - .andExpect(content().string(containsString("These applications have been granted access to your account."))) - .andExpect(content().string(containsString("Change Password"))); + .andExpect(status().isOk()) + .andExpect(model().attributeExists("clientnames")) + .andExpect(model().attribute("clientnames", hasKey("app"))) + .andExpect(model().attribute("clientnames", hasValue(is(name)))) + .andExpect(model().attribute("isUaaManagedUser", true)) + .andExpect(model().attribute("approvals", hasKey("app"))) + .andExpect(model().attribute("approvals", hasValue(hasSize(2)))) + .andExpect(content().contentTypeCompatibleWith(TEXT_HTML)) + .andExpect(content().string(containsString("These applications have been granted access to your account."))) + .andExpect(content().string(containsString("Change Password"))) + .andExpect(content().string(containsString("

"+name))) + .andExpect(content().string(containsString("Are you sure you want to revoke access to " + name))); } + @Test public void testSpecialMessageWhenNoAppsAreAuthorized() throws Exception { Map> approvalsByClientId = new HashMap>(); @@ -213,8 +240,13 @@ ApprovalsService approvalsService() { } @Bean - ProfileController profileController(ApprovalsService approvalsService) { - return new ProfileController(approvalsService); + ClientDetailsService clientService() { + return Mockito.mock(ClientDetailsService.class); + } + + @Bean + ProfileController profileController(ApprovalsService approvalsService, ClientDetailsService clientDetailsService) { + return new ProfileController(approvalsService, clientDetailsService); } } } diff --git a/uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml b/uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml index e6210f0d816..b8bb255f399 100644 --- a/uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml +++ b/uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml @@ -33,7 +33,7 @@ - + @@ -83,6 +83,7 @@ + @@ -162,7 +163,7 @@ - + diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/AppApprovalIT.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/AppApprovalIT.java index 5f4c606ea95..b1375fe2e50 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/AppApprovalIT.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/AppApprovalIT.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Cloud Foundry + * Cloud Foundry * Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -64,7 +64,7 @@ public class AppApprovalIT { @Value("${integration.test.app_url}") String appUrl; - + @Test public void testApprovingAnApp() throws Exception { ScimUser user = createUnapprovedUser(); @@ -111,7 +111,7 @@ public void testApprovingAnApp() throws Exception { // Revoke app webDriver.findElement(By.linkText("Revoke Access")).click(); - Assert.assertEquals("Are you sure you want to revoke access to app?", webDriver.findElement(By.cssSelector(".revocation-modal p")).getText()); + Assert.assertEquals("Are you sure you want to revoke access to The Ultimate Oauth App?", webDriver.findElement(By.cssSelector(".revocation-modal p")).getText()); // click cancel webDriver.findElement(By.cssSelector("#app-form .revocation-cancel")).click(); From 86114429f5c62f292ba03dd197a24322218e24df Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Wed, 29 Apr 2015 13:59:11 -0600 Subject: [PATCH 05/11] Remove the duplicate property name that occassionally causes java.lang.IllegalStateException: Cannot convert value of type [java.util.LinkedHashSet] to required type [java.lang.String] for property 'internalHostnames': no matching editors or conversion strategy found --- .../identity/uaa/zone/IdentityZoneResolvingFilter.java | 10 ++-------- uaa/src/main/webapp/WEB-INF/spring-servlet.xml | 3 ++- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilter.java b/common/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilter.java index 7ccf68c4853..90eafed1a12 100644 --- a/common/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilter.java +++ b/common/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilter.java @@ -12,7 +12,6 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.zone; -import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.web.filter.OncePerRequestFilter; @@ -22,7 +21,6 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -30,9 +28,6 @@ * This filter ensures that all requests are targeting a specific identity zone * by hostname. If the hostname doesn't match an identity zone, a 404 error is * sent. - * - * @author wtran@pivotal.io - * @author rszumlakowski@pivotal.io * */ public class IdentityZoneResolvingFilter extends OncePerRequestFilter { @@ -82,12 +77,11 @@ public void setIdentityZoneProvisioning(IdentityZoneProvisioning dao) { this.dao = dao; } - @Value("${internalHostnames:localhost}") public void setInternalHostnames(String hostnames) { this.internalHostnames.addAll(Arrays.asList(hostnames.split("[ ,]+"))); } - public void setInternalHostnames(Set hostnames) { - this.internalHostnames.addAll(Collections.unmodifiableSet(hostnames)); + public void setDefaultInternalHostnames(Set hostnames) { + this.internalHostnames.addAll(hostnames); } } diff --git a/uaa/src/main/webapp/WEB-INF/spring-servlet.xml b/uaa/src/main/webapp/WEB-INF/spring-servlet.xml index 04387130bc7..dcf0a3f50cd 100755 --- a/uaa/src/main/webapp/WEB-INF/spring-servlet.xml +++ b/uaa/src/main/webapp/WEB-INF/spring-servlet.xml @@ -98,7 +98,8 @@ - + + #{T(org.cloudfoundry.identity.uaa.util.UaaUrlUtils).getHostForURI(@uaaUrl)} #{T(org.cloudfoundry.identity.uaa.util.UaaUrlUtils).getHostForURI(@loginUrl)} From b066a527fbd50816b4cd6ba651ec0131dac1dc1f Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Wed, 29 Apr 2015 15:00:39 -0600 Subject: [PATCH 06/11] Improve readability/usability of the internal hostnames property https://www.pivotaltracker.com/story/show/93569986 [#93569986] --- .../identity/uaa/UaaConfiguration.java | 14 ++++++- .../uaa/zone/IdentityZoneResolvingFilter.java | 18 ++++++--- .../zone/IdentityZoneResolvingFilterTest.java | 38 +++++++++---------- uaa/src/main/resources/uaa.yml | 11 +++++- .../main/webapp/WEB-INF/spring-servlet.xml | 2 +- .../identity/uaa/login/BootstrapTests.java | 29 +++++++------- uaa/src/test/resources/test/hostnames/uaa.yml | 7 ++++ 7 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 uaa/src/test/resources/test/hostnames/uaa.yml diff --git a/common/src/main/java/org/cloudfoundry/identity/uaa/UaaConfiguration.java b/common/src/main/java/org/cloudfoundry/identity/uaa/UaaConfiguration.java index 6390823dda8..b8bb01b5aa9 100644 --- a/common/src/main/java/org/cloudfoundry/identity/uaa/UaaConfiguration.java +++ b/common/src/main/java/org/cloudfoundry/identity/uaa/UaaConfiguration.java @@ -47,7 +47,10 @@ public class UaaConfiguration { @Pattern(regexp = "(default|postgresql|hsqldb|mysql|oracle)") public String platform; public String spring_profiles; - public String internalHostnames; + + @Valid + public Zones zones; + @URL(message = "issuer.uri must be a valid URL") public String issuerUri; public boolean dump_requests; @@ -92,6 +95,15 @@ public class UaaConfiguration { @Valid public OAuth multitenant; + public static class Zones { + @Valid + public InternalZone internal; + + public static class InternalZone { + public Set hostnames; + } + } + public static class CloudController { @Valid public Database database; diff --git a/common/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilter.java b/common/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilter.java index 90eafed1a12..a50168b0c53 100644 --- a/common/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilter.java +++ b/common/src/main/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilter.java @@ -33,7 +33,7 @@ public class IdentityZoneResolvingFilter extends OncePerRequestFilter { private IdentityZoneProvisioning dao; - private Set internalHostnames = new HashSet<>(); + private Set defaultZoneHostnames = new HashSet<>(); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) @@ -62,10 +62,10 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } private String getSubdomain(String hostname) { - if (internalHostnames.contains(hostname)) { + if (defaultZoneHostnames.contains(hostname)) { return ""; } - for (String internalHostname : internalHostnames) { + for (String internalHostname : defaultZoneHostnames) { if (hostname.endsWith("." + internalHostname)) { return hostname.substring(0, hostname.length() - internalHostname.length() - 1); } @@ -77,11 +77,17 @@ public void setIdentityZoneProvisioning(IdentityZoneProvisioning dao) { this.dao = dao; } - public void setInternalHostnames(String hostnames) { - this.internalHostnames.addAll(Arrays.asList(hostnames.split("[ ,]+"))); + public void setAdditionalInternalHostnames(Set hostnames) { + if (hostnames!=null) { + this.defaultZoneHostnames.addAll(hostnames); + } } public void setDefaultInternalHostnames(Set hostnames) { - this.internalHostnames.addAll(hostnames); + this.defaultZoneHostnames.addAll(hostnames); + } + + public Set getDefaultZoneHostnames() { + return defaultZoneHostnames; } } diff --git a/common/src/test/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilterTest.java b/common/src/test/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilterTest.java index 1e316e5ed0e..3f878262dca 100644 --- a/common/src/test/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilterTest.java +++ b/common/src/test/java/org/cloudfoundry/identity/uaa/zone/IdentityZoneResolvingFilterTest.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.HashSet; -import java.util.LinkedList; import javax.servlet.FilterChain; import javax.servlet.ServletException; @@ -19,45 +18,44 @@ import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.util.StringUtils; public class IdentityZoneResolvingFilterTest { - + private boolean wasFilterExecuted = false; - + @Test public void holderIsSetWithDefaultIdentityZone() { IdentityZoneHolder.clear(); assertEquals(IdentityZone.getUaa(), IdentityZoneHolder.get()); } - + @Test public void holderIsSetWithMatchingIdentityZone() throws Exception { - assertFindsCorrectSubdomain("myzone", "myzone.uaa.mycf.com", "uaa.mycf.com,login.mycf.com"); + assertFindsCorrectSubdomain("myzone", "myzone.uaa.mycf.com", "uaa.mycf.com","login.mycf.com"); } - + @Test public void holderIsSetWithMatchingIdentityZoneWhenSubdomainContainsUaaHostname() throws Exception { - assertFindsCorrectSubdomain("foo.uaa.mycf.com","foo.uaa.mycf.com.uaa.mycf.com", "uaa.mycf.com,login.mycf.com"); + assertFindsCorrectSubdomain("foo.uaa.mycf.com", "foo.uaa.mycf.com.uaa.mycf.com", "uaa.mycf.com", "login.mycf.com"); } @Test public void holderIsSetWithUAAIdentityZone() throws Exception { - assertFindsCorrectSubdomain("", "uaa.mycf.com", "uaa.mycf.com,login.mycf.com"); - assertFindsCorrectSubdomain("", "login.mycf.com", "uaa.mycf.com,login.mycf.com"); + assertFindsCorrectSubdomain("", "uaa.mycf.com", "uaa.mycf.com","login.mycf.com"); + assertFindsCorrectSubdomain("", "login.mycf.com", "uaa.mycf.com","login.mycf.com"); } - - private void assertFindsCorrectSubdomain(final String expectedSubdomain, final String incomingHostname, String internalHostnames) throws ServletException, IOException { + + private void assertFindsCorrectSubdomain(final String expectedSubdomain, final String incomingHostname, String... additionalInternalHostnames) throws ServletException, IOException { IdentityZoneResolvingFilter filter = new IdentityZoneResolvingFilter(); IdentityZoneProvisioning dao = Mockito.mock(IdentityZoneProvisioning.class); filter.setIdentityZoneProvisioning(dao); - filter.setInternalHostnames(internalHostnames); + filter.setAdditionalInternalHostnames(new HashSet<>(Arrays.asList(additionalInternalHostnames))); IdentityZone identityZone = new IdentityZone(); identityZone.setSubdomain(expectedSubdomain); Mockito.when(dao.retrieveBySubdomain(Mockito.eq(expectedSubdomain))).thenReturn(identityZone); - + MockHttpServletRequest request = new MockHttpServletRequest(); request.setServerName(incomingHostname); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -69,13 +67,13 @@ public void doFilter(ServletRequest request, ServletResponse response) throws IO wasFilterExecuted = true; } }; - + filter.doFilter(request, response, filterChain); assertTrue(wasFilterExecuted); Mockito.verify(dao).retrieveBySubdomain(Mockito.eq(expectedSubdomain)); assertEquals(IdentityZone.getUaa(), IdentityZoneHolder.get()); } - + @Test public void holderIsNotSetWithNonMatchingIdentityZone() throws Exception { String incomingSubdomain = "not_a_zone"; @@ -86,16 +84,16 @@ public void holderIsNotSetWithNonMatchingIdentityZone() throws Exception { IdentityZoneProvisioning dao = Mockito.mock(IdentityZoneProvisioning.class); FilterChain chain = Mockito.mock(FilterChain.class); filter.setIdentityZoneProvisioning(dao); - filter.setInternalHostnames(uaaHostname); - + filter.setAdditionalInternalHostnames(new HashSet<>(Arrays.asList(uaaHostname))); + IdentityZone identityZone = new IdentityZone(); identityZone.setSubdomain(incomingSubdomain); Mockito.when(dao.retrieveBySubdomain(Mockito.eq(incomingSubdomain))).thenThrow(new EmptyResultDataAccessException(1)); - + MockHttpServletRequest request = new MockHttpServletRequest(); request.setServerName(incomingHostname); MockHttpServletResponse response = new MockHttpServletResponse(); - + filter.doFilter(request, response, chain); assertEquals(HttpServletResponse.SC_NOT_FOUND, response.getStatus()); assertEquals(IdentityZone.getUaa(), IdentityZoneHolder.get()); diff --git a/uaa/src/main/resources/uaa.yml b/uaa/src/main/resources/uaa.yml index fdc835f09cf..4bd2db3b3ca 100755 --- a/uaa/src/main/resources/uaa.yml +++ b/uaa/src/main/resources/uaa.yml @@ -36,9 +36,16 @@ #SET PASSWORD FOR 'root'@'localhost' = PASSWORD('changeme'); #SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('changeme'); -# A comprehensive list of hostnames routed to the UAA. The UAA uses this to resolve subdomains for Identity Zones. +# A comprehensive list of hostnames routed to the UAA default zone. The UAA uses this to resolve subdomains for Identity Zones. # Defaults to 'localhost' -#internalHostnames: localhost,uaa.example.com,login.example.com +#zones: +# internal: +# hostnames: +# - host1.domain.com +# - host2 +# - testzone3.localhost +# - testzone4.localhost + #authentication: # policy: diff --git a/uaa/src/main/webapp/WEB-INF/spring-servlet.xml b/uaa/src/main/webapp/WEB-INF/spring-servlet.xml index dcf0a3f50cd..56f66244ad0 100755 --- a/uaa/src/main/webapp/WEB-INF/spring-servlet.xml +++ b/uaa/src/main/webapp/WEB-INF/spring-servlet.xml @@ -98,7 +98,6 @@ - #{T(org.cloudfoundry.identity.uaa.util.UaaUrlUtils).getHostForURI(@uaaUrl)} @@ -106,6 +105,7 @@ localhost + diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/BootstrapTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/BootstrapTests.java index 8bf0c45b322..9b468967cf0 100755 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/BootstrapTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/BootstrapTests.java @@ -102,7 +102,6 @@ public void cleanup() throws Exception { System.clearProperty("spring.profiles.active"); System.clearProperty("uaa.url"); System.clearProperty("login.url"); - System.clearProperty("internalHostnames"); if (context != null) { context.close(); } @@ -130,29 +129,31 @@ public void testRootContextDefaults() throws Exception { assertEquals(864000, context.getBean("webSSOprofileConsumer", WebSSOProfileConsumerImpl.class).getMaxAuthenticationAge()); IdentityZoneResolvingFilter filter = context.getBean(IdentityZoneResolvingFilter.class); Set defaultHostnames = new HashSet<>(Arrays.asList(uaa, login, "localhost")); - - Field internalHostnames = filter.getClass().getDeclaredField("internalHostnames"); - internalHostnames.setAccessible(true); - - assertEquals(internalHostnames.get(filter), defaultHostnames); - + assertEquals(filter.getDefaultZoneHostnames(), defaultHostnames); } @Test public void testInternalHostnames() throws Exception { + String uaa = "uaa.some.test.domain.com"; + String login = uaa.replace("uaa", "login"); + System.setProperty("uaa.url", "https://" + uaa + ":555/uaa"); + System.setProperty("login.url", "https://" + login + ":555/uaa"); + context = getServletContext(null, "login.yml","test/hostnames/uaa.yml", "file:./src/main/webapp/WEB-INF/spring-servlet.xml"); + IdentityZoneResolvingFilter filter = context.getBean(IdentityZoneResolvingFilter.class); + Set defaultHostnames = new HashSet<>(Arrays.asList(uaa, login, "localhost", "host1.domain.com", "host2", "test3.localhost", "test4.localhost")); + assertEquals(filter.getDefaultZoneHostnames(), defaultHostnames); + } + + @Test + public void testDefaultInternalHostnames() throws Exception { String uaa = "uaa.some.test.domain.com"; String login = uaa.replace("uaa", "login"); System.setProperty("uaa.url", "https://"+uaa+":555/uaa"); System.setProperty("login.url", "https://"+login+":555/uaa"); - System.setProperty("internalHostnames", "some-other-hostname.com"); context = getServletContext(null, "login.yml","uaa.yml", "file:./src/main/webapp/WEB-INF/spring-servlet.xml"); IdentityZoneResolvingFilter filter = context.getBean(IdentityZoneResolvingFilter.class); - Set defaultHostnames = new HashSet<>(Arrays.asList(uaa, login, "localhost", "some-other-hostname.com")); - - Field internalHostnames = filter.getClass().getDeclaredField("internalHostnames"); - internalHostnames.setAccessible(true); - - assertEquals(internalHostnames.get(filter), defaultHostnames); + Set defaultHostnames = new HashSet<>(Arrays.asList(uaa, login, "localhost")); + assertEquals(filter.getDefaultZoneHostnames(), defaultHostnames); } @Test diff --git a/uaa/src/test/resources/test/hostnames/uaa.yml b/uaa/src/test/resources/test/hostnames/uaa.yml new file mode 100644 index 00000000000..4c67fa5fb7f --- /dev/null +++ b/uaa/src/test/resources/test/hostnames/uaa.yml @@ -0,0 +1,7 @@ +zones: + internal: + hostnames: + - host1.domain.com + - host2 + - test3.localhost + - test4.localhost \ No newline at end of file From 3ff146ec36424b4fee53f93a182ac01aed764651 Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Thu, 30 Apr 2015 09:18:32 -0600 Subject: [PATCH 07/11] Add in test cases and configuration options for DB parameters https://www.pivotaltracker.com/story/show/93580504 [#93580504] --- .../identity/uaa/UaaConfiguration.java | 8 ++ .../src/main/resources/spring/data-source.xml | 1 + .../identity/uaa/login/BootstrapTests.java | 87 ++++++++++++------- 3 files changed, 66 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/org/cloudfoundry/identity/uaa/UaaConfiguration.java b/common/src/main/java/org/cloudfoundry/identity/uaa/UaaConfiguration.java index b8bb01b5aa9..69f861a17f3 100644 --- a/common/src/main/java/org/cloudfoundry/identity/uaa/UaaConfiguration.java +++ b/common/src/main/java/org/cloudfoundry/identity/uaa/UaaConfiguration.java @@ -117,6 +117,14 @@ public static class Database { public String username; @NotNull(message = "Database password is required") public String password; + + public int maxactive; + public int maxidle; + public boolean removeabandoned; + public boolean logabandoned; + public int abandonedtimeout; + public long evictionintervalms; + } public static class Logging { diff --git a/common/src/main/resources/spring/data-source.xml b/common/src/main/resources/spring/data-source.xml index d269c6e97bd..676a6793dc3 100755 --- a/common/src/main/resources/spring/data-source.xml +++ b/common/src/main/resources/spring/data-source.xml @@ -26,6 +26,7 @@ + diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/BootstrapTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/BootstrapTests.java index 9b468967cf0..2b6220bbc24 100755 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/BootstrapTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/BootstrapTests.java @@ -14,8 +14,8 @@ import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory; import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory; +import org.apache.tomcat.jdbc.pool.DataSource; import org.cloudfoundry.identity.uaa.authentication.Origin; -import org.cloudfoundry.identity.uaa.config.YamlPropertiesFactoryBean; import org.cloudfoundry.identity.uaa.config.YamlServletProfileInitializer; import org.cloudfoundry.identity.uaa.login.saml.IdentityProviderConfigurator; import org.cloudfoundry.identity.uaa.login.saml.IdentityProviderDefinition; @@ -34,15 +34,10 @@ import org.springframework.beans.factory.xml.ResourceEntityResolver; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.GenericXmlApplicationContext; -import org.springframework.core.env.PropertiesPropertySource; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; import org.springframework.mock.web.MockRequestDispatcher; import org.springframework.mock.web.MockServletConfig; import org.springframework.mock.web.MockServletContext; import org.springframework.security.saml.log.SAMLDefaultLogger; -import org.springframework.security.saml.websso.WebSSOProfileConsumer; import org.springframework.security.saml.websso.WebSSOProfileConsumerImpl; import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; import org.springframework.util.ReflectionUtils; @@ -53,9 +48,7 @@ import javax.servlet.RequestDispatcher; import java.io.File; import java.io.IOException; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -63,12 +56,9 @@ import java.util.Scanner; import java.util.Set; -import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; public class BootstrapTests { @@ -107,7 +97,7 @@ public void cleanup() throws Exception { } Set removeme = new HashSet<>(); for ( Map.Entry entry : System.getProperties().entrySet()) { - if (entry.getKey().toString().startsWith("login.")) { + if (entry.getKey().toString().startsWith("login.") || entry.getKey().toString().startsWith("database.")) { removeme.add(entry.getKey().toString()); } } @@ -133,27 +123,64 @@ public void testRootContextDefaults() throws Exception { } @Test - public void testInternalHostnames() throws Exception { - String uaa = "uaa.some.test.domain.com"; - String login = uaa.replace("uaa", "login"); - System.setProperty("uaa.url", "https://" + uaa + ":555/uaa"); - System.setProperty("login.url", "https://" + login + ":555/uaa"); - context = getServletContext(null, "login.yml","test/hostnames/uaa.yml", "file:./src/main/webapp/WEB-INF/spring-servlet.xml"); - IdentityZoneResolvingFilter filter = context.getBean(IdentityZoneResolvingFilter.class); - Set defaultHostnames = new HashSet<>(Arrays.asList(uaa, login, "localhost", "host1.domain.com", "host2", "test3.localhost", "test4.localhost")); - assertEquals(filter.getDefaultZoneHostnames(), defaultHostnames); + public void testInternalHostnamesWithDBSettings() throws Exception { + try { + String uaa = "uaa.some.test.domain.com"; + String login = uaa.replace("uaa", "login"); + System.setProperty("uaa.url", "https://" + uaa + ":555/uaa"); + System.setProperty("login.url", "https://" + login + ":555/uaa"); + System.setProperty("database.maxactive", "50"); + System.setProperty("database.maxidle", "5"); + System.setProperty("database.removeabandoned", "true"); + System.setProperty("database.logabandoned", "false"); + System.setProperty("database.abandonedtimeout", "45"); + System.setProperty("database.evictionintervalms", "30000"); + context = getServletContext(null, "login.yml", "test/hostnames/uaa.yml", "file:./src/main/webapp/WEB-INF/spring-servlet.xml"); + IdentityZoneResolvingFilter filter = context.getBean(IdentityZoneResolvingFilter.class); + Set defaultHostnames = new HashSet<>(Arrays.asList(uaa, login, "localhost", "host1.domain.com", "host2", "test3.localhost", "test4.localhost")); + assertEquals(filter.getDefaultZoneHostnames(), defaultHostnames); + DataSource ds = context.getBean(DataSource.class); + assertEquals(50, ds.getMaxActive()); + assertEquals(5, ds.getMaxIdle()); + assertTrue(ds.isRemoveAbandoned()); + assertFalse(ds.isLogAbandoned()); + assertEquals(45, ds.getRemoveAbandonedTimeout()); + assertEquals(30000, ds.getTimeBetweenEvictionRunsMillis()); + } finally { + System.clearProperty("database.maxactive"); + System.clearProperty("database.maxidle"); + System.clearProperty("database.removeabandoned"); + System.clearProperty("database.logabandoned"); + System.clearProperty("database.abandonedtimeout"); + System.clearProperty("database.evictionintervalms"); + } } @Test - public void testDefaultInternalHostnames() throws Exception { - String uaa = "uaa.some.test.domain.com"; - String login = uaa.replace("uaa", "login"); - System.setProperty("uaa.url", "https://"+uaa+":555/uaa"); - System.setProperty("login.url", "https://"+login+":555/uaa"); - context = getServletContext(null, "login.yml","uaa.yml", "file:./src/main/webapp/WEB-INF/spring-servlet.xml"); - IdentityZoneResolvingFilter filter = context.getBean(IdentityZoneResolvingFilter.class); - Set defaultHostnames = new HashSet<>(Arrays.asList(uaa, login, "localhost")); - assertEquals(filter.getDefaultZoneHostnames(), defaultHostnames); + public void testDefaultInternalHostnamesAndNoDBSettings() throws Exception { + try { + //travis profile script overrides these properties + System.setProperty("database.maxactive", "100"); + System.setProperty("database.maxidle", "10"); + String uaa = "uaa.some.test.domain.com"; + String login = uaa.replace("uaa", "login"); + System.setProperty("uaa.url", "https://" + uaa + ":555/uaa"); + System.setProperty("login.url", "https://" + login + ":555/uaa"); + context = getServletContext(null, "login.yml", "uaa.yml", "file:./src/main/webapp/WEB-INF/spring-servlet.xml"); + IdentityZoneResolvingFilter filter = context.getBean(IdentityZoneResolvingFilter.class); + Set defaultHostnames = new HashSet<>(Arrays.asList(uaa, login, "localhost")); + assertEquals(filter.getDefaultZoneHostnames(), defaultHostnames); + DataSource ds = context.getBean(DataSource.class); + assertEquals(100, ds.getMaxActive()); + assertEquals(10, ds.getMaxIdle()); + assertFalse(ds.isRemoveAbandoned()); + assertTrue(ds.isLogAbandoned()); + assertEquals(300, ds.getRemoveAbandonedTimeout()); + assertEquals(15000, ds.getTimeBetweenEvictionRunsMillis()); + } finally { + System.clearProperty("database.maxactive"); + System.clearProperty("database.maxidle"); + } } @Test From f70fdf01cc110fdf00565188b888b1a545460844 Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Fri, 1 May 2015 11:44:31 -0600 Subject: [PATCH 08/11] Handle SAML metadata that does not have the urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressurn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\n"; + private static String xmlWithoutHeader = + " MIICmTCCAgKgAwIBAgIGAUPATqmEMA0GCSqGSIb3DQEBBQUAMIGPMQswCQYDVQQGEwJVUzETMBEG\n" + + "A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU\n" + + "MBIGA1UECwwLU1NPUHJvdmlkZXIxEDAOBgNVBAMMB1Bpdm90YWwxHDAaBgkqhkiG9w0BCQEWDWlu\n" + + "Zm9Ab2t0YS5jb20wHhcNMTQwMTIzMTgxMjM3WhcNNDQwMTIzMTgxMzM3WjCBjzELMAkGA1UEBhMC\n" + + "VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoM\n" + + "BE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRAwDgYDVQQDDAdQaXZvdGFsMRwwGgYJKoZIhvcN\n" + + "AQkBFg1pbmZvQG9rdGEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeil67/TLOiTZU\n" + + "WWgW2XEGgFZ94bVO90v5J1XmcHMwL8v5Z/8qjdZLpGdwI7Ph0CyXMMNklpaR/Ljb8fsls3amdT5O\n" + + "Bw92Zo8ulcpjw2wuezTwL0eC0wY/GQDAZiXL59npE6U+fH1lbJIq92hx0HJSru/0O1q3+A/+jjZL\n" + + "3tL/SwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAI5BoWZoH6Mz9vhypZPOJCEKa/K+biZQsA4Zqsuk\n" + + "vvphhSERhqk/Nv76Vkl8uvJwwHbQrR9KJx4L3PRkGCG24rix71jEuXVGZUsDNM3CUKnARx4MEab6\n" + + "GFHNkZ6DmoT/PFagngecHu+EwmuDtaG0rEkFrARwe+d8Ru0BN558abFburn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressurn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\n"; IdentityProviderConfigurator conf = null; Map> data = null; IdentityProviderDefinition singleAdd = null; + IdentityProviderDefinition singleAddWithoutHeader = null; private static final String singleAddAlias = "sample-alias"; String sampleYaml = " providers:\n" + @@ -115,6 +129,7 @@ public void setUp() throws Exception { conf = new IdentityProviderConfigurator(); parseYaml(sampleYaml); singleAdd = new IdentityProviderDefinition(xml, singleAddAlias,"sample-nameID",1,true,true,"sample-link-test","sample-icon-url","uaa"); + singleAddWithoutHeader = new IdentityProviderDefinition(xmlWithoutHeader, singleAddAlias,"sample-nameID",1,true,true,"sample-link-test","sample-icon-url","uaa"); } private void parseYaml(String sampleYaml) { @@ -146,6 +161,14 @@ public void testSingleAddProviderDefinition() throws Exception { testGetIdentityProviderDefinitions(6, false); } + @Test + public void testSingleAddProviderWithoutXMLHeader() throws Exception { + conf.setIdentityProviders(data); + conf.afterPropertiesSet(); + conf.addIdentityProviderDefinition(singleAddWithoutHeader); + testGetIdentityProviderDefinitions(6, false); + } + @Test(expected = NullPointerException.class) public void testAddNullProvider() { conf.addIdentityProviderDefinition(null); From 67b10b8d33d74eef2b8c5e89e16239f19f7de061 Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Thu, 30 Apr 2015 14:25:27 -0600 Subject: [PATCH 09/11] Adjust identity client example https://www.pivotaltracker.com/story/show/93132630 [#93132630] --- uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml | 6 +++--- .../identity/uaa/mock/token/TokenMvcMockTests.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml b/uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml index b8bb255f399..b40fee870e0 100644 --- a/uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml +++ b/uaa/src/main/webapp/WEB-INF/spring/oauth-clients.xml @@ -117,9 +117,9 @@ - - - + + + diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java index b18e3228f38..6099bfd0d6d 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java @@ -1674,10 +1674,10 @@ public void testGetTokenScopesNotInAuthentication() throws Exception { OAuth2Authentication a1 = tokenServices.loadAuthentication(oauthToken.accessToken); - assertEquals(2, a1.getOAuth2Request().getScope().size()); + assertEquals(4, a1.getOAuth2Request().getScope().size()); assertThat( a1.getOAuth2Request().getScope(), - containsInAnyOrder(new String[] {zoneadmingroup, "openid"}) + containsInAnyOrder(new String[] {zoneadmingroup, "openid", "cloud_controller.read", "cloud_controller.write"}) ); } From 811abb8a782dba424fa7762cc2d3a8186e6180bb Mon Sep 17 00:00:00 2001 From: Filip Hanik Date: Fri, 1 May 2015 16:08:15 -0600 Subject: [PATCH 10/11] [skip ci] Perform a clean and don't print that we published anything --- scripts/deploy-and-finish-release.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/deploy-and-finish-release.sh b/scripts/deploy-and-finish-release.sh index dcc506029de..2a893896c34 100755 --- a/scripts/deploy-and-finish-release.sh +++ b/scripts/deploy-and-finish-release.sh @@ -24,6 +24,7 @@ set -x git checkout releases/$1 #./gradlew clean artifactoryPublish +./gradlew clean git checkout $branch_to_push_to git merge releases/$1 --no-ff -m "Merge branch 'releases/$1'" git tag -a $1 -m "$1 release of the UAA" @@ -39,8 +40,8 @@ git push origin $branch_to_release_from set +x -echo Artifacts published to Artifactory from releases/$1 -echo +#echo Artifacts published to Artifactory from releases/$1 +#echo echo releases/$1 has been merged into $branch_to_push_to, tagged and pushed echo echo releases/$1 has been merged into $branch_to_release_from From 868833dc370ce9a95fe4f9ef55838d8835d45718 Mon Sep 17 00:00:00 2001 From: Chris Dutra Date: Fri, 1 May 2015 15:55:12 -0700 Subject: [PATCH 11/11] Bump release version to 2.2.6 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 819d6aab3be..d13ea101cca 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=2.2.6-SNAPSHOT +version=2.2.6