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

Introduce New Integration Tests to Validate Functionality of IdPs #21913

Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@
import org.wso2.carbon.automation.engine.context.TestUserMode;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.xml.xpath.XPathExpressionException;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.testng.Assert.assertNotNull;

Expand Down Expand Up @@ -96,6 +102,19 @@ public void testGetIdPWithInvalidId() {
validateErrorResponse(response, HttpStatus.SC_NOT_FOUND, "IDP-60002", "random-id");
}

@Test
public void testInvalidSearchAllIdPs() throws XPathExpressionException {
Shenali-SJ marked this conversation as resolved.
Show resolved Hide resolved

Response response = getResponseOfGetWithQueryParams(IDP_API_BASE_PATH, Collections.singletonMap("filter",
Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved
"name sw InvalidIdP"));
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_OK)
.body("totalResults", equalTo(0))
.body("count", equalTo(0));
}

@Test(dependsOnMethods = {"testGetIdPWithInvalidId"})
public void addIdPConflict() throws IOException {

Expand All @@ -120,6 +139,19 @@ public void addIdPWithDuplicateProperties() throws IOException {
validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "IDP-60025");
}

@Test
public void testAddIdPWithDuplicatedPropertyKeys() throws IOException {
Shenali-SJ marked this conversation as resolved.
Show resolved Hide resolved

String body = readResource("add-idp-with-duplicated-property-keys.json");
Shenali-SJ marked this conversation as resolved.
Show resolved Hide resolved
Response response = getResponseOfPost(IDP_API_BASE_PATH, body);
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_BAD_REQUEST)
.body("message", equalTo("Invalid input."))
.body("description", equalTo("One of the given inputs is invalid. Duplicate properties are " +
"found in the request."));
}

@Test(dependsOnMethods = {"addIdPConflict"})
public void testGetIdPFederatedAuthenticatorWithInvalidAuthId() {
Expand Down Expand Up @@ -213,6 +245,50 @@ public void testUpdateIdPWithDuplicateOIDCScopes() throws IOException {
deleteCreatedIdP(oidcIdPId);
}

@Test
public void testUpdateOIDCIdPWithoutOpenidScope() throws IOException {

String body = readResource("add-idp-oidc-standard-based.json");
Response response = getResponseOfPost(IDP_API_BASE_PATH, body);
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_CREATED)
.header(HttpHeaders.LOCATION, notNullValue());

String location = response.getHeader(HttpHeaders.LOCATION);
assertNotNull(location);
String oidcIdPId = location.substring(location.lastIndexOf("/") + 1);
assertNotNull(oidcIdPId);

// update the OIDC IdP without openid scope
String updateBody = readResource("update-idp-oidc-without-openid-scope.json");
Response updateResponse = getResponseOfPut(IDP_API_BASE_PATH + PATH_SEPARATOR + oidcIdPId +
PATH_SEPARATOR + IDP_FEDERATED_AUTHENTICATORS_PATH + PATH_SEPARATOR + OIDC_IDP_ID, updateBody);
updateResponse.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_BAD_REQUEST)
.body("message", equalTo("Invalid OIDC Scopes."))
.body("description", equalTo("Scopes must contain 'openid'."));

deleteCreatedIdP(oidcIdPId);
}

@Test
public void addSamlIdPWithoutMetadata() throws IOException {

String body = readResource("add-saml-idp-without-metadata.json");
Response response = getResponseOfPost(IDP_API_BASE_PATH, body);

response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_BAD_REQUEST)
.body("message", equalTo("Invalid SAML metadata."))
.body("description", equalTo("SAML metadata is invalid/empty."));
}

/**
* Deletes an Identity Provider by its ID and verifies the deletion.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.hamcrest.Matchers;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
Expand Down Expand Up @@ -50,6 +51,8 @@ public class IdPSuccessTest extends IdPTestBase {
private String idPId;
private String idPTemplateId;
private static final String IDP_NAME = "Google";
private static final String AUTHENTICATOR_NAME = "GoogleOIDCAuthenticator";
private static final String DEFINED_BY_SYSTEM = "SYSTEM";

@Factory(dataProvider = "restAPIUserConfigProvider")
public IdPSuccessTest(TestUserMode userMode) throws Exception {
Expand Down Expand Up @@ -277,6 +280,85 @@ public void testAddIdP() throws IOException {
assertNotNull(idPId);
}

@Test()
public void addIdPWithoutAuthenticator() throws IOException {

String body = readResource("add-idp-without-authenticator.json");
Response response = getResponseOfPost(IDP_API_BASE_PATH, body);
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_CREATED)
.body("federatedAuthenticators.authenticators", Matchers.emptyIterable())
.header(HttpHeaders.LOCATION, notNullValue());

String location = response.getHeader(HttpHeaders.LOCATION);
assertNotNull(location);
String idpIdWithoutAuth = location.substring(location.lastIndexOf("/") + 1);
assertNotNull(idpIdWithoutAuth);

deleteCreatedIdP(idpIdWithoutAuth);
}

// TODO: add a comment
Shenali-SJ marked this conversation as resolved.
Show resolved Hide resolved
@Test
public void addIdPWithDuplicatedOIDCScopes() throws IOException {

String body = readResource("add-oidc-idp-with-duplicated-scopes.json");
Response response = getResponseOfPost(IDP_API_BASE_PATH, body);
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_CREATED)
.header(HttpHeaders.LOCATION, notNullValue());

String location = response.getHeader(HttpHeaders.LOCATION);
assertNotNull(location);
String oidcIdpId = location.substring(location.lastIndexOf("/") + 1);
assertNotNull(oidcIdpId);

deleteCreatedIdP(oidcIdpId);
}

// TODO: add a comment
@Test
public void addOIDCIdPWithoutOpenidScope() throws IOException {

String body = readResource("add-oidc-idp-without-openid-scope.json");
Response response = getResponseOfPost(IDP_API_BASE_PATH, body);
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_CREATED)
.header(HttpHeaders.LOCATION, notNullValue());

String location = response.getHeader(HttpHeaders.LOCATION);
assertNotNull(location);
String oidcIdpId = location.substring(location.lastIndexOf("/") + 1);
assertNotNull(oidcIdpId);

deleteCreatedIdP(oidcIdpId);
}

@Test
public void addSAMLStandardBasedIdP() throws IOException {

String body = readResource("add-saml-idp.json");
Response response = getResponseOfPost(IDP_API_BASE_PATH, body);
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_CREATED)
.header(HttpHeaders.LOCATION, notNullValue());

String location = response.getHeader(HttpHeaders.LOCATION);
assertNotNull(location);
String samlIdpId = location.substring(location.lastIndexOf("/") + 1);
assertNotNull(samlIdpId);

deleteCreatedIdP(samlIdpId);
}

@Test(dependsOnMethods = {"testAddIdP"})
public void testGetIdP() throws IOException {

Expand Down Expand Up @@ -381,7 +463,7 @@ public void testUpdateIdPFederatedAuthenticator() throws IOException {
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_OK)
.body("definedBy", equalTo("SYSTEM"));
.body("definedBy", equalTo(DEFINED_BY_SYSTEM));
}

@Test(dependsOnMethods = {"testUpdateIdPFederatedAuthenticator"})
Expand All @@ -398,7 +480,7 @@ public void testGetIdPFederatedAuthenticator() throws IOException {
.body("isEnabled", equalTo(true))
.body("isDefault", equalTo(true))
.body("properties", notNullValue())
.body("definedBy", equalTo("SYSTEM"))
.body("definedBy", equalTo(DEFINED_BY_SYSTEM))
.body("properties.find{ it.key == 'ClientId' }.value", equalTo
("165474950684-7mvqd8m6hieb8mdnffcarnku2aua0tpl.apps.googleusercontent.com"))
.body("properties.find{ it.key == 'ClientSecret' }.value", equalTo("testclientsecret"))
Expand Down Expand Up @@ -630,7 +712,21 @@ public void testPatchIdP() throws IOException {
.body("certificate.certificates", nullValue());
}

@Test(dependsOnMethods = {"testPatchIdP"})
@Test(dependsOnMethods = "testPatchIdP")
public void testExportIDPToFile() {

Response response = getResponseOfGet(IDP_API_BASE_PATH + PATH_SEPARATOR + idPId + PATH_SEPARATOR +
"export");
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_OK)
.body("identityProviderName", equalTo(IDP_NAME))
.body("federatedAuthenticatorConfigs.find { it.name == '" + AUTHENTICATOR_NAME + "' }.definedByType",
equalTo(DEFINED_BY_SYSTEM));
}

@Test(dependsOnMethods = {"testExportIDPToFile"})
public void testDeleteIdP() {

getResponseOfDelete(IDP_API_BASE_PATH + PATH_SEPARATOR + idPId)
Expand Down Expand Up @@ -760,4 +856,27 @@ public void testDeleteIdPTemplate() throws Exception {
.assertThat()
.statusCode(HttpStatus.SC_NO_CONTENT);
}

/**
* Deletes an Identity Provider by its ID and verifies the deletion.
*
* @param idPId ID of the Identity Provider to be deleted.
*/
private void deleteCreatedIdP(String idPId) {

Response response = getResponseOfDelete(IDP_API_BASE_PATH + PATH_SEPARATOR + idPId);
response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_NO_CONTENT);

Response responseOfGet = getResponseOfGet(IDP_API_BASE_PATH + PATH_SEPARATOR + idPId);
responseOfGet.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_NOT_FOUND)
.body("message", equalTo("Resource not found."))
.body("description", equalTo("Unable to find a resource matching the provided identity " +
"provider identifier " + idPId + "."));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
"name": "Google-3",
"description": "IDP for Google Federation",
"image": "google-logo-url",
"isPrimary": false,
"isFederationHub": false,
"homeRealmIdentifier": "localhost",
"certificate": {
"certificates": [
"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURzRENDQXBpZ0F3SUJBZ0lKQUs0eml2ckVsYzBJTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdETVJFd0R3WUQKVlFRRERBaENkV1JrYUdsdFlURUxNQWtHQTFVRUJoTUNVMHd4RURBT0JnTlZCQWdNQjFkbGMzUmxjbTR4RURBTwpCZ05WQkFjTUIwTnZiRzl0WW04eERUQUxCZ05WQkFvTUJGZFRUekl4Q3pBSkJnTlZCQXNNQWxGQk1TRXdId1lKCktvWklodmNOQVFrQkZoSmlkV1JrYUdsdFlYVkFkM052TWk1amIyMHdJQmNOTVRrd056RTJNRFF5TXpFd1doZ1AKTXpBeE9ERXhNVFl3TkRJek1UQmFNSUdETVJFd0R3WURWUVFEREFoQ2RXUmthR2x0WVRFTE1Ba0dBMVVFQmhNQwpVMHd4RURBT0JnTlZCQWdNQjFkbGMzUmxjbTR4RURBT0JnTlZCQWNNQjBOdmJHOXRZbTh4RFRBTEJnTlZCQW9NCkJGZFRUekl4Q3pBSkJnTlZCQXNNQWxGQk1TRXdId1lKS29aSWh2Y05BUWtCRmhKaWRXUmthR2x0WVhWQWQzTnYKTWk1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDcFo3V09VMTZpeGpiQwpiWGR3R3JhTW5xbmxnb2kzMDN5aVFxbHAySzlWTmZHT21nTlFhdFdlbjB0MVVWcjYxd0Y4eVlHaDJyc1lnbithCjhwYXVmUVVQQ1laeFRFR1FpT2RPZ0RNcE5tWW82ZHU2K2MvenJqcHNncGh5SHIxNEZPVHAxaVRDSXBmanVwVjEKd1BUeXJveURySGRvMkpuOHI3V3F1cklJVTRBYllBN2NrdVVqL0tqYUovTTZrZitwRFd5SVJvaDBKTFJlWWM4UQp5bmhYcjdrQWp5RnFqNitnWndBYkh4ckhrckVzYTJoVjQ0UFJXWjFQUERxTCswVU8veE1hQW5udndsdGd4QlVpCkhLUTFXWDVwdVVPaC9kQTQ5b0RsbEpraHpxd2d5eDQxc1FYbFNhVmdKaklUZVdSQmdvNnh6ajNmd3VvenBGS1gKbzRaeXBITDNBZ01CQUFHakl6QWhNQjhHQTFVZEVRUVlNQmFDQkhkemJ6S0NDSGR6YnpJdVkyOXRnZ1IzYzI4eQpNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUJTSzBKa1pyYlpvYmRDNHhZSG1IcnlVbkZVbkZZWUFvZmc0TFVGCkJRbWxDY0NKR0ZwR1BtN2ZDWHM0Y0h4Z0hPVTN5SkhtQ2pYaU9FRTc2dzhIU0NRcVhkNmROSEwxRkxtN0pqQTUKTEZmbHhiWXNOcmVVNVpJTmREVGZvWmxSSXR0Mkd4MlpIa3pjQVRJZm1yUFNwODV2WDhGem1mbTNBVTVpM3FXZQo4a2YyZk5nQjlMbE5XRFk1V09paVlHUWMrRk13WWdLcDJkNGM3dzMrWnRTUXJWRy9YdGpqYTJYV09Xdm1sV3dLCnB4b3pyNjIvTTdUUmVkc3hJNU90bzJvWExGZXp1MUdCWHdpNEFaempMSFVsNWpSR2hMbkNZa05qdWZGZi9EQ0cKeUFWdnpMVXQwZ2F0b0dJdTV2eG9la05JVWV5YTZpRzJBaG9jSmM0SEJMT3l4TXE3Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
]
},
"alias": "https://localhost:9444/oauth2/token",
"claims": {
"userIdClaim": {
"uri": "http://wso2.org/claims/username"
},
"roleClaim": {
"uri": "http://wso2.org/claims/role"
},
"provisioningClaims": [
{
"claim": {
"uri": "http://wso2.org/claims/username"
},
"defaultValue": "sathya"
}
]
},
"roles": {
"mappings": [
{
"idpRole": "google-manager",
"localRole": "admin"
}
],
"outboundProvisioningRoles": [
"admin"
]
},
"federatedAuthenticators": {
"defaultAuthenticatorId": "R29vZ2xlT0lEQ0F1dGhlbnRpY2F0b3I",
"authenticators": [
{
"authenticatorId": "R29vZ2xlT0lEQ0F1dGhlbnRpY2F0b3I",
"isEnabled": true,
"properties": [
{
"key": "AdditionalQueryParameters",
"value": "scope=openid email profile"
},
{
"key": "ClientId",
"value": "165474950684-7mvqd8m6hieb8mdnffcarnku2aua0tpl.apps.googleusercontent.com"
},
{
"key": "ClientSecret",
"value": "testclientsecret"
},
{
"key": "callbackUrl",
"value": "https://mydomain2.com:9443/commonauth"
}
]
}
]
},
"provisioning": {
"jit": {
"isEnabled": true,
"scheme": "PROVISION_SILENTLY",
"userstore": "PRIMARY"
},
"outboundConnectors": {
"defaultConnectorId": "c2NpbQ",
"connectors": [
{
"connectorId": "c2NpbQ",
"isEnabled": true,
"blockingEnabled": false,
"rulesEnabled": false,
"properties": [
{
"key": "scim-user-ep",
"value": "https://localhost:9445/userinfo"
},
{
"key": "scim-username",
"value": "admin"
},
{
"key": "scim-username",
"value": "admin2"
},
{
"key": "scim-enable-pwd-provisioning",
"value": "true"
},
{
"key": "scim-password",
"value": "admin"
},
{
"key": "commonAuthQueryParams",
"value": "scope=openid country profile"
},
{
"key": "Scopes",
"value": "openid country profile"
}
]
}
]
}
}
}
Loading