/* * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.cloudfoundry.uaa; import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.uaa.identityproviders.CreateIdentityProviderRequest; import org.cloudfoundry.uaa.identityproviders.CreateIdentityProviderResponse; import org.cloudfoundry.uaa.identityproviders.DeleteIdentityProviderRequest; import org.cloudfoundry.uaa.identityproviders.ExternalGroupMappingMode; import org.cloudfoundry.uaa.identityproviders.GetIdentityProviderRequest; import org.cloudfoundry.uaa.identityproviders.LdapConfiguration; import org.cloudfoundry.uaa.identityproviders.LdapGroupFile; import org.cloudfoundry.uaa.identityproviders.LdapProfileFile; import org.cloudfoundry.uaa.identityproviders.ListIdentityProvidersRequest; import org.cloudfoundry.uaa.identityproviders.ListIdentityProvidersResponse; import org.cloudfoundry.uaa.identityproviders.OAuth2Configuration; import org.cloudfoundry.uaa.identityproviders.SamlConfiguration; import org.cloudfoundry.uaa.identityproviders.TlsConfiguration; import org.cloudfoundry.uaa.identityproviders.UpdateIdentityProviderRequest; import org.cloudfoundry.uaa.identityzones.CreateIdentityZoneRequest; import org.cloudfoundry.uaa.identityzones.CreateIdentityZoneResponse; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.time.Duration; import static org.cloudfoundry.uaa.identityproviders.Type.LDAP; import static org.cloudfoundry.uaa.identityproviders.Type.OAUTH2; import static org.cloudfoundry.uaa.identityproviders.Type.SAML; public final class IdentityProvidersTest extends AbstractIntegrationTest { @Autowired private UaaClient uaaClient; @Autowired private Mono<String> userId; @Test public void createLdapSimpleBind() { String identityZoneName = this.nameFactory.getIdentityZoneName(); String name = this.nameFactory.getIdentityProviderName(); String subdomainName = this.nameFactory.getDomainName(); this.userId .then(userId -> requestCreateIdentityZone(this.uaaClient, identityZoneName, subdomainName)) .then(this.uaaClient.identityProviders() .create(CreateIdentityProviderRequest.builder() .active(true) .configuration(LdapConfiguration.builder() .addShadowUserOnLogin(true) .autoAddGroups(true) .baseUrl(String.format("ldap://%s.url", name)) .groupSearchDepthLimit(10) .groupSearchSubTree(true) .ldapGroupFile(LdapGroupFile.NO_GROUP) .ldapProfileFile(LdapProfileFile.SIMPLE_BIND) .mailAttributeName("mail") .mailSubstituteOverridesLdap(false) .skipSSLVerification(false) .tlsConfiguration(TlsConfiguration.NONE) .userDistinguishedNamePattern("cn={0},ou=Users,dc=test,dc=com") .userDistinguishedNamePatternDelimiter(";") .build()) .identityZoneId(identityZoneName) .name(name) .originKey("ldap") .type(LDAP) .build())) .then(requestListIdentityProviders(this.uaaClient, identityZoneName)) .flatMapIterable(ListIdentityProvidersResponse::getIdentityProviders) .filter(provider -> LDAP.equals(provider.getType())) .as(StepVerifier::create) .expectNextCount(1) .expectComplete() .verify(Duration.ofMinutes(5)); } @Test public void createOAuth() { String identityZoneName = this.nameFactory.getIdentityZoneName(); String name = this.nameFactory.getIdentityProviderName(); String subdomainName = this.nameFactory.getDomainName(); this.userId .then(userId -> requestCreateIdentityZone(this.uaaClient, identityZoneName, subdomainName)) .then(this.uaaClient.identityProviders() .create(CreateIdentityProviderRequest.builder() .active(true) .configuration(OAuth2Configuration.builder() .addShadowUserOnLogin(true) .authUrl("http://auth.url") .relyingPartyId("uaa") .relyingPartySecret("secret") .showLinkText(false) .skipSslVerification(false) .tokenKey("token-key") .tokenUrl("http://token.url") .build()) .identityZoneId(identityZoneName) .name(name) .originKey("oauth2.0") .type(OAUTH2) .build())) .then(requestListIdentityProviders(this.uaaClient, identityZoneName)) .flatMapIterable(ListIdentityProvidersResponse::getIdentityProviders) .filter(provider -> OAUTH2.equals(provider.getType())) .as(StepVerifier::create) .expectNextCount(1) .expectComplete() .verify(Duration.ofMinutes(5)); } @Test public void createSaml() { String identityZoneName = this.nameFactory.getIdentityZoneName(); String name = this.nameFactory.getIdentityProviderName(); String subdomainName = this.nameFactory.getDomainName(); this.userId .then(userId -> requestCreateIdentityZone(this.uaaClient, identityZoneName, subdomainName)) .then(this.uaaClient.identityProviders() .create(CreateIdentityProviderRequest.builder() .active(true) .configuration(SamlConfiguration.builder() .addShadowUserOnLogin(true) .metaDataLocation("<?xml version=\"1.0\" encoding=\"UTF-8\"?><md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"http://www.okta" + ".com/SAML\"><md:IDPSSODescriptor WantAuthnRequestsSigned=\"true\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\"><md:KeyDescriptor " + "use=\"signing\"><ds:KeyInfo xmlns:ds=\"http://www" + ".w3.org/2000/09/xmldsig#\"><ds:X509Data><ds:X509Certificate>MIICmTCCAgKgAwIBAgIGAUPATqmEMA0GCSqGSIb3DQEBBQUAMIGPMQswCQYDVQQGEwJVUzETMBEG" + "\nA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU\nMBIGA1UECwwLU1NPUHJvdmlkZXIxEDAOBgNVBAMMB1Bpdm90YWwxHDAaBgkqhkiG9w0BCQEWDWlu" + "\nZm9Ab2t0YS5jb20wHhcNMTQwMTIzMTgxMjM3WhcNNDQwMTIzMTgxMzM3WjCBjzELMAkGA1UEBhMC\nVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoM" + "\nBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRAwDgYDVQQDDAdQaXZvdGFsMRwwGgYJKoZIhvcN\nAQkBFg1pbmZvQG9rdGEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeil67/TLOiTZU" + "\nWWgW2XEGgFZ94bVO90v5J1XmcHMwL8v5Z/8qjdZLpGdwI7Ph0CyXMMNklpaR/Ljb8fsls3amdT5O\nBw92Zo8ulcpjw2wuezTwL0eC0wY/GQDAZiXL59npE6U+fH1lbJIq92hx0HJSru/0O1q3+A/+jjZL\n3tL" + "/SwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAI5BoWZoH6Mz9vhypZPOJCEKa/K+biZQsA4Zqsuk\nvvphhSERhqk/Nv76Vkl8uvJwwHbQrR9KJx4L3PRkGCG24rix71jEuXVGZUsDNM3CUKnARx4MEab6\nGFHNkZ6DmoT" + "/PFagngecHu+EwmuDtaG0rEkFrARwe+d8Ru0BN558abFb</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid" + "-format:emailAddress</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:SingleSignOnService " + "Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"https://pivotal.oktapreview" + ".com/app/pivotal_pivotalcfstaging_1/k2lw4l5bPODCMIIDBRYZ/sso/saml\"/><md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\" " + "Location=\"https://pivotal.oktapreview.com/app/pivotal_pivotalcfstaging_1/k2lw4l5bPODCMIIDBRYZ/sso/saml\"/></md:IDPSSODescriptor></md:EntityDescriptor>\n") .nameId("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress") .assertionConsumerIndex(0) .metadataTrustCheck(false) .showSamlLink(false) .socketFactoryClassName("org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory") .linkText("IDPEndpointsMockTests Saml Provider:SAML") .groupMappingMode(ExternalGroupMappingMode.EXPLICITLY_MAPPED) .build()) .identityZoneId(identityZoneName) .name(name) .originKey("SAML") .type(SAML) .build())) .then(requestListIdentityProviders(this.uaaClient, identityZoneName)) .flatMapIterable(ListIdentityProvidersResponse::getIdentityProviders) .filter(provider -> SAML.equals(provider.getType())) .as(StepVerifier::create) .expectNextCount(1) .expectComplete() .verify(Duration.ofMinutes(5)); } @Test public void delete() { String identityZoneName = this.nameFactory.getIdentityZoneName(); String name = this.nameFactory.getIdentityProviderName(); String subdomainName = this.nameFactory.getDomainName(); this.userId .then(userId -> requestCreateIdentityZone(this.uaaClient, identityZoneName, subdomainName)) .then(requestCreateIdentityProvider(this.uaaClient, identityZoneName, name)) .then(response -> this.uaaClient.identityProviders() .delete(DeleteIdentityProviderRequest.builder() .identityProviderId(response.getId()) .identityZoneId(response.getIdentityZoneId()) .build())) .then(requestListIdentityProviders(this.uaaClient, identityZoneName)) .flatMapIterable(ListIdentityProvidersResponse::getIdentityProviders) .filter(provider -> name.equals(provider.getName())) .as(StepVerifier::create) .expectComplete() .verify(Duration.ofMinutes(5)); } @Test public void get() { String identityZoneName = this.nameFactory.getIdentityZoneName(); String name = this.nameFactory.getIdentityProviderName(); String subdomainName = this.nameFactory.getDomainName(); this.userId .then(userId -> requestCreateIdentityZone(this.uaaClient, identityZoneName, subdomainName)) .then(requestCreateIdentityProvider(this.uaaClient, identityZoneName, name)) .then(response -> this.uaaClient.identityProviders() .get(GetIdentityProviderRequest.builder() .identityProviderId(response.getId()) .identityZoneId(identityZoneName) .build())) .as(StepVerifier::create) .expectNextCount(1) .expectComplete() .verify(Duration.ofMinutes(5)); } @Test public void list() { String identityZoneName = this.nameFactory.getIdentityZoneName(); String name = this.nameFactory.getIdentityProviderName(); String subdomainName = this.nameFactory.getDomainName(); this.userId .then(userId -> requestCreateIdentityZone(this.uaaClient, identityZoneName, subdomainName)) .then(requestCreateIdentityProvider(this.uaaClient, identityZoneName, name)) .then(this.uaaClient.identityProviders() .list(ListIdentityProvidersRequest.builder() .identityZoneId(identityZoneName) .build())) .flatMapIterable(ListIdentityProvidersResponse::getIdentityProviders) .filter(provider -> OAUTH2.equals(provider.getType())) .as(StepVerifier::create) .expectNextCount(1) .expectComplete() .verify(Duration.ofMinutes(5)); } @Test public void update() { String identityZoneName = this.nameFactory.getIdentityZoneName(); String oldName = this.nameFactory.getIdentityProviderName(); String newName = this.nameFactory.getIdentityProviderName(); String subdomainName = this.nameFactory.getDomainName(); this.userId .then(userId -> requestCreateIdentityZone(this.uaaClient, identityZoneName, subdomainName)) .then(requestCreateIdentityProvider(this.uaaClient, identityZoneName, oldName)) .then(response -> this.uaaClient.identityProviders() .update(UpdateIdentityProviderRequest.builder() .configuration(OAuth2Configuration.builder() .addShadowUserOnLogin(true) .authUrl("http://auth.url") .relyingPartyId("uaa") .relyingPartySecret("secret") .showLinkText(false) .skipSslVerification(false) .tokenKey("token-key") .tokenUrl("http://token.url") .build()) .identityProviderId(response.getId()) .identityZoneId(identityZoneName) .name(newName) .originKey("oauth2.0") .type(OAUTH2) .version(1) .build())) .then(requestListIdentityProviders(this.uaaClient, identityZoneName)) .flatMapIterable(ListIdentityProvidersResponse::getIdentityProviders) .filter(provider -> newName.equals(provider.getName())) .as(StepVerifier::create) .expectNextCount(1) .expectComplete() .verify(Duration.ofMinutes(5)); } private static Mono<CreateIdentityProviderResponse> requestCreateIdentityProvider(UaaClient uaaClient, String identityZoneName, String name) { return uaaClient.identityProviders() .create(CreateIdentityProviderRequest.builder() .active(true) .configuration(OAuth2Configuration.builder() .addShadowUserOnLogin(true) .authUrl("http://auth.url") .relyingPartyId("uaa") .relyingPartySecret("secret") .showLinkText(false) .skipSslVerification(false) .tokenKey("token-key") .tokenUrl("http://token.url") .build()) .identityZoneId(identityZoneName) .name(name) .originKey("oauth2.0") .type(OAUTH2) .build()); } private static Mono<CreateIdentityZoneResponse> requestCreateIdentityZone(UaaClient uaaClient, String identityZoneName, String subdomainName) { return uaaClient.identityZones() .create(CreateIdentityZoneRequest.builder() .identityZoneId(identityZoneName) .name(identityZoneName) .subdomain(subdomainName) .build()); } private static Mono<ListIdentityProvidersResponse> requestListIdentityProviders(UaaClient uaaClient, String identityZoneName) { return uaaClient.identityProviders() .list(ListIdentityProvidersRequest.builder() .identityZoneId(identityZoneName) .build()); } }