Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove more IdP tests #2742

Merged
merged 2 commits into from
Feb 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
import org.cloudfoundry.identity.uaa.provider.IdentityProvider;
import org.cloudfoundry.identity.uaa.provider.JdbcIdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.provider.SamlIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.provider.saml.idp.SamlServiceProvider;
import org.cloudfoundry.identity.uaa.scim.ScimUser;
import org.cloudfoundry.identity.uaa.scim.jdbc.JdbcScimUserProvisioning;
import org.cloudfoundry.identity.uaa.user.UaaAuthority;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.hamcrest.BaseMatcher;
Expand All @@ -29,39 +27,24 @@
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.web.context.WebApplicationContext;
import org.xml.sax.InputSource;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.StringReader;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import static org.apache.logging.log4j.Level.DEBUG;
import static org.apache.logging.log4j.Level.WARN;
import static org.cloudfoundry.identity.uaa.authentication.SamlResponseLoggerBinding.X_VCAP_REQUEST_ID_HEADER;
import static org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils.getUaaSecurityContext;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
import static org.springframework.http.HttpHeaders.HOST;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.securityContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@DefaultTestContext
class SamlAuthenticationMockMvcTests {
Expand All @@ -72,7 +55,6 @@ class SamlAuthenticationMockMvcTests {
private IdentityZone idpZone;
private String spZoneEntityId;
private IdentityProvider<SamlIdentityProviderDefinition> idp;
private SamlServiceProvider samlServiceProvider;

@Autowired
private MockMvc mockMvc;
Expand Down Expand Up @@ -125,72 +107,6 @@ void putBackOriginalLogger() {
loggingAuditService.setLogger(originalAuditServiceLogger);
}

@Disabled("The test depends on IDP endpoints, which was removed.")
@Test
void sendAuthnRequestToIdp() throws Exception {
createIdp();

String idpEntityId = idpZone.getSubdomain() + ".cloudfoundry-saml-login";
MvcResult mvcResult = mockMvc.perform(
get("/uaa/saml/discovery")
.contextPath("/uaa")
.header(HOST, spZone.getSubdomain() + ".localhost:8080")
.param("returnIDParam", "idp")
.param("entityID", spZoneEntityId)
.param("idp", idp.getOriginKey())
.param("isPassive", "true")
)
.andExpect(status().isFound())
.andReturn();

mvcResult = mockMvc.perform(
get(mvcResult.getResponse().getRedirectedUrl())
.contextPath("/uaa")
.header(HOST, spZone.getSubdomain() + ".localhost:8080")
.session((MockHttpSession) mvcResult.getRequest().getSession())

)
.andDo(print())
.andExpect(status().isOk())
.andReturn();

String body = mvcResult.getResponse().getContentAsString();
String relayState = extractRelayState(body);
String samlRequest = extractSamlRequest(body);
mockMvc.perform(
post("/uaa/saml/idp/SSO/alias/" + idpEntityId)
.contextPath("/uaa")
.header(HOST, idpZone.getSubdomain() + ".localhost:8080")
.param("RelayState", relayState)
.param("SAMLRequest", samlRequest)
)
.andExpect(status().isFound())
.andExpect(redirectedUrl("http://" + idpZone.getSubdomain() + ".localhost:8080/uaa/login"));
}

@Disabled("The test depends on IDP endpoints, which was removed.")
@Test
void validateStaticAttributes(
) throws Exception {
createIdp();

samlServiceProvider.getConfig().getStaticCustomAttributes().put("portal_id", "portal");
samlServiceProvider.getConfig().getStaticCustomAttributes().put("portal_emails", Arrays.asList("portal1@portal.test", "portal2@portal.test"));

String samlResponse = performIdpAuthentication();
String xml = extractAssertion(samlResponse, true);
XPath xpath = XPathFactory.newInstance().newXPath();
String emails = (String) xpath.evaluate("//*[local-name()='Attribute'][@*[local-name()='Name' and .='portal_emails']]", new InputSource(new StringReader(xml)), XPathConstants.STRING);
assertThat(emails, containsString("portal1@portal.test"));
assertThat(emails, containsString("portal2@portal.test"));
}

private ResultActions postSamlResponse(
final String xml
) throws Exception {
return postSamlResponse(xml, "", "", "");
}

private ResultActions postSamlResponse(
final String xml,
final String queryString,
Expand Down Expand Up @@ -306,23 +222,6 @@ public void describeTo(Description description) {
}
}

private String performIdpAuthentication() throws Exception {
return performIdpAuthentication(Collections.singletonList("uaa.user"));
}

private String performIdpAuthentication(List<String> authorityNames) throws Exception {
List<GrantedAuthority> grantedAuthorityList = authorityNames.stream().map(UaaAuthority::authority).collect(Collectors.toList());
RequestPostProcessor marissa = securityContext(getUaaSecurityContext("marissa", webApplicationContext, idpZone.getId(), grantedAuthorityList));
return mockMvc.perform(
get("/saml/idp/initiate")
.header("Host", idpZone.getSubdomain() + ".localhost")
.param("sp", spZoneEntityId)
.with(marissa)
)
.andDo(print())
.andReturn().getResponse().getContentAsString();
}

private String getSamlMetadata(String subdomain, String url) throws Exception {
return mockMvc.perform(
get(url)
Expand Down Expand Up @@ -373,32 +272,4 @@ private IdentityZone createZone(String zoneIdPrefix, BaseClientDetails adminClie
adminClient, IdentityZoneHolder.getCurrentZoneId()
).getIdentityZone();
}

private static String extractAssertion(String response, boolean decode) {
String searchFor = "name=\"SAMLResponse\" value=\"";
return extractFormParameter(searchFor, response, decode);
}

private static String extractSamlRequest(String response) {
String searchFor = "name=\"SAMLRequest\" value=\"";
return extractFormParameter(searchFor, response, false);
}

private static String extractRelayState(String response) {
String searchFor = "name=\"RelayState\" value=\"";
return extractFormParameter(searchFor, response, false);
}

private static String extractFormParameter(String searchFor, String response, boolean decode) {
int start = response.indexOf(searchFor) + searchFor.length();
assertThat("Must find the SAML response in output\n" + response, start, greaterThan(searchFor.length()));
int end = response.indexOf("\"/>", start);
assertThat("Must find the SAML response in output\n" + response, end, greaterThan(start));
String encoded = response.substring(start, end);
if (decode) {
return new String(Base64.getDecoder().decode(encoded));
} else {
return encoded;
}
}
}
Loading