Skip to content

Commit

Permalink
Merge pull request #21847 from Shenali-SJ/custom-fed-mgt-integration-…
Browse files Browse the repository at this point in the history
…tests-success

Add success API tests for IdPs with user defined authenticators
  • Loading branch information
Thisara-Welmilla authored Dec 4, 2024
2 parents cc5e064 + 62d2b26 commit ba78b41
Show file tree
Hide file tree
Showing 6 changed files with 636 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.wso2.identity.integration.test.rest.api.server.idp.v1;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.apache.commons.lang.StringUtils;
Expand All @@ -29,8 +30,13 @@
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
import org.wso2.carbon.automation.engine.context.TestUserMode;
import org.wso2.identity.integration.test.rest.api.server.idp.v1.model.AuthenticationType;
import org.wso2.identity.integration.test.rest.api.server.idp.v1.model.Endpoint;
import org.wso2.identity.integration.test.rest.api.server.idp.v1.model.FederatedAuthenticatorRequest;
import org.wso2.identity.integration.test.rest.api.server.idp.v1.util.UserDefinedAuthenticatorPayload;

import java.io.IOException;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -47,9 +53,25 @@
*/
public class IdPSuccessTest extends IdPTestBase {

private static final String FEDERATED_AUTHENTICATOR_ID_PLACEHOLDER = "<FEDERATED_AUTHENTICATOR_ID>";
private static final String FEDERATED_AUTHENTICATOR_PLACEHOLDER = "\"<FEDERATED_AUTHENTICATOR>\"";
private static final String IDP_NAME_PLACEHOLDER = "<IDP_NAME>";
private static final String FEDERATED_AUTHENTICATOR_ID = "Y3VzdG9tQXV0aGVudGljYXRvcg";
private static final String CUSTOM_IDP_NAME = "Custom Auth IDP";
private static final String ENDPOINT_URI = "https://abc.com/authenticate";
private static final String UPDATED_ENDPOINT_URI = "https://xyz.com/authenticate";
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static final String ACCESS_TOKEN = "accessToken";
private static final String USERNAME_VALUE = "testUser";
private static final String ACCESS_TOKEN_VALUE = "testBearerToken";
private static final String PASSWORD_VALUE = "testPassword";
private static final String IDP_NAME = "Google";
private String idPId;
private String customIdPId;
private String idPTemplateId;
private static final String IDP_NAME = "Google";
private UserDefinedAuthenticatorPayload userDefinedAuthenticatorPayload;
private String idpCreatePayload;

@Factory(dataProvider = "restAPIUserConfigProvider")
public IdPSuccessTest(TestUserMode userMode) throws Exception {
Expand All @@ -65,6 +87,50 @@ public IdPSuccessTest(TestUserMode userMode) throws Exception {
public void init() throws IOException {

super.testInit(API_VERSION, swaggerDefinition, tenant);
userDefinedAuthenticatorPayload = createUserDefinedAuthenticatorPayloadWithBasic(ENDPOINT_URI);
idpCreatePayload = readResource("add-idp-with-custom-fed-auth.json");
}

private UserDefinedAuthenticatorPayload createUserDefinedAuthenticatorPayloadWithBasic(String endpointUri) {

UserDefinedAuthenticatorPayload userDefinedAuthenticatorPayload = new UserDefinedAuthenticatorPayload();
userDefinedAuthenticatorPayload.setIsEnabled(true);
userDefinedAuthenticatorPayload.setAuthenticatorId(FEDERATED_AUTHENTICATOR_ID);
userDefinedAuthenticatorPayload.setDefinedBy(FederatedAuthenticatorRequest.DefinedByEnum.USER.toString());

Endpoint endpoint = new Endpoint();
endpoint.setUri(endpointUri);
AuthenticationType authenticationType = new AuthenticationType();
authenticationType.setType(AuthenticationType.TypeEnum.BASIC);
Map<String, Object> properties = new HashMap<>();
properties.put(USERNAME, USERNAME_VALUE);
properties.put(PASSWORD, PASSWORD_VALUE);
authenticationType.setProperties(properties);
endpoint.authentication(authenticationType);
userDefinedAuthenticatorPayload.setEndpoint(endpoint);

return userDefinedAuthenticatorPayload;
}

private UserDefinedAuthenticatorPayload createUserDefinedAuthenticatorPayloadWithBearer(String endpointUri) {

UserDefinedAuthenticatorPayload userDefinedAuthenticatorPayload = new UserDefinedAuthenticatorPayload();
userDefinedAuthenticatorPayload.setIsEnabled(true);
userDefinedAuthenticatorPayload.setAuthenticatorId(FEDERATED_AUTHENTICATOR_ID);
userDefinedAuthenticatorPayload.setDefinedBy(FederatedAuthenticatorRequest.DefinedByEnum.USER.toString());

Endpoint endpoint = new Endpoint();
endpoint.setUri(endpointUri);
AuthenticationType authenticationType = new AuthenticationType();
authenticationType.setType(AuthenticationType.TypeEnum.BEARER);
Map<String, Object> properties = new HashMap<>();
authenticationType.setType(AuthenticationType.TypeEnum.BEARER);
properties.put(ACCESS_TOKEN, ACCESS_TOKEN_VALUE);
authenticationType.setProperties(properties);
endpoint.authentication(authenticationType);
userDefinedAuthenticatorPayload.setEndpoint(endpoint);

return userDefinedAuthenticatorPayload;
}

@AfterClass(alwaysRun = true)
Expand Down Expand Up @@ -260,6 +326,88 @@ public void testGetMetaOutboundConnector() throws IOException {
.body("rulesEnabled", equalTo(false));
}

@Test
public void testAddIdPWithUserDefinedAuthenticator() throws IOException {

String body = idpCreatePayload.replace(FEDERATED_AUTHENTICATOR_ID_PLACEHOLDER,
userDefinedAuthenticatorPayload.getAuthenticatorId());
body = body.replace(FEDERATED_AUTHENTICATOR_PLACEHOLDER,
userDefinedAuthenticatorPayload.convertToJasonPayload());
body = body.replace(IDP_NAME_PLACEHOLDER, CUSTOM_IDP_NAME);
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);
customIdPId = location.substring(location.lastIndexOf("/") + 1);
assertNotNull(customIdPId);
}

@Test(dependsOnMethods = "testAddIdPWithUserDefinedAuthenticator")
public void testGetUserDefinedAuthenticatorsOfIdP() throws XPathExpressionException {

Response response = getResponseOfGet(IDP_API_BASE_PATH + PATH_SEPARATOR + customIdPId +
PATH_SEPARATOR + IDP_FEDERATED_AUTHENTICATORS_PATH);

response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_OK)
.body("defaultAuthenticatorId", equalTo(FEDERATED_AUTHENTICATOR_ID))
.body("authenticators.find { it.authenticatorId == '" + FEDERATED_AUTHENTICATOR_ID + "' }.name",
equalTo(new String(Base64.getDecoder().decode(FEDERATED_AUTHENTICATOR_ID))))
.body("authenticators.find { it.authenticatorId == '" + FEDERATED_AUTHENTICATOR_ID + "' }.isEnabled",
equalTo(true))
.body("authenticators.find { it.authenticatorId == '" + FEDERATED_AUTHENTICATOR_ID + "' }.self",
equalTo(getTenantedRelativePath("/api/server/v1/identity-providers/" +
customIdPId + "/federated-authenticators/" + FEDERATED_AUTHENTICATOR_ID,
context.getContextTenant().getDomain())));
}

@Test(dependsOnMethods = "testGetUserDefinedAuthenticatorsOfIdP")
public void testUpdateUserDefinedAuthenticatorOfIdP() throws JsonProcessingException {

Response response = getResponseOfPut(IDP_API_BASE_PATH + PATH_SEPARATOR + customIdPId +
PATH_SEPARATOR + IDP_FEDERATED_AUTHENTICATORS_PATH + PATH_SEPARATOR + FEDERATED_AUTHENTICATOR_ID,
createUserDefinedAuthenticatorPayloadWithBearer(UPDATED_ENDPOINT_URI)
.convertToJasonPayload());

response.then()
.log().ifValidationFails()
.assertThat()
.statusCode(HttpStatus.SC_OK)
.body("authenticatorId", equalTo(FEDERATED_AUTHENTICATOR_ID))
.body("name", equalTo(new String(Base64.getDecoder().decode(FEDERATED_AUTHENTICATOR_ID))))
.body("definedBy", equalTo("USER"))
.body("endpoint.uri", equalTo(UPDATED_ENDPOINT_URI))
.body("endpoint.authentication.type", equalTo(AuthenticationType.TypeEnum.BEARER.value()));
}

@Test(dependsOnMethods = {"testGetIdPs", "testUpdateUserDefinedAuthenticatorOfIdP"})
public void testDeleteIdPWithUserDefinedAuthenticator() {

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

Response responseOfGet = getResponseOfGet(IDP_API_BASE_PATH + PATH_SEPARATOR + customIdPId);
responseOfGet.then()
.log().ifValidationFails()
.assertThat()
.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 " + customIdPId + "."));

}

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

Expand Down Expand Up @@ -290,6 +438,8 @@ public void testGetIdP() throws IOException {
.body("description", equalTo("IDP for Google Federation"))
.body("isEnabled", equalTo(true))
.body("isPrimary", equalTo(false))
.body("federatedAuthenticators.authenticators.find { it.authenticatorId == '" +
SAMPLE_FEDERATED_AUTHENTICATOR_ID + "' }.definedBy", equalTo("SYSTEM"))
.body("image", equalTo("google-logo-url"))
.body("isFederationHub", equalTo(false))
.body("homeRealmIdentifier", equalTo("localhost"))
Expand All @@ -300,6 +450,7 @@ public void testGetIdP() throws IOException {
public void testGetIdPs() throws Exception {

String baseIdentifier = "identityProviders.find{ it.id == '" + idPId + "' }.";
String baseIdentifierUserDef = "identityProviders.find{ it.id == '" + customIdPId + "' }.";
Response response = getResponseOfGet(IDP_API_BASE_PATH);
response.then()
.log().ifValidationFails()
Expand All @@ -311,6 +462,11 @@ public void testGetIdPs() throws Exception {
.body(baseIdentifier + "image", equalTo("google-logo-url"))
.body(baseIdentifier + "self", equalTo(getTenantedRelativePath(
"/api/server/v1/identity-providers/" + idPId,
context.getContextTenant().getDomain())))
.body(baseIdentifierUserDef + "name", equalTo(CUSTOM_IDP_NAME))
.body(baseIdentifierUserDef + "isEnabled", equalTo(true))
.body(baseIdentifierUserDef + "self", equalTo(getTenantedRelativePath(
"/api/server/v1/identity-providers/" + customIdPId,
context.getContextTenant().getDomain())));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you 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.wso2.identity.integration.test.rest.api.server.idp.v1.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlType;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class AuthenticationType {


@XmlType(name="TypeEnum")
@XmlEnum(String.class)
public enum TypeEnum {

@XmlEnumValue("NONE") NONE(String.valueOf("NONE")), @XmlEnumValue("BEARER") BEARER(String.valueOf("BEARER")), @XmlEnumValue("API_KEY") API_KEY(String.valueOf("API_KEY")), @XmlEnumValue("BASIC") BASIC(String.valueOf("BASIC"));


private String value;

TypeEnum(String v) {
value = v;
}

public String value() {
return value;
}

@Override
public String toString() {
return String.valueOf(value);
}

public static TypeEnum fromValue(String value) {
for (TypeEnum b : TypeEnum.values()) {
if (b.value.equals(value)) {
return b;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}
}

private TypeEnum type;
private Map<String, Object> properties = new HashMap<>();


/**
**/
public AuthenticationType type(TypeEnum type) {

this.type = type;
return this;
}

@ApiModelProperty(example = "BASIC", required = true, value = "")
@JsonProperty("type")
@Valid
@NotNull(message = "Property type cannot be null.")

public TypeEnum getType() {
return type;
}
public void setType(TypeEnum type) {
this.type = type;
}

/**
**/
public AuthenticationType properties(Map<String, Object> properties) {

this.properties = properties;
return this;
}

@ApiModelProperty(example = "{\"username\":\"auth_username\",\"password\":\"auth_password\"}", required = true, value = "")
@JsonProperty("properties")
@Valid
@NotNull(message = "Property properties cannot be null.")

public Map<String, Object> getProperties() {
return properties;
}
public void setProperties(Map<String, Object> properties) {
this.properties = properties;
}


public AuthenticationType putPropertiesItem(String key, Object propertiesItem) {
this.properties.put(key, propertiesItem);
return this;
}



@Override
public boolean equals(java.lang.Object o) {

if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AuthenticationType authenticationType = (AuthenticationType) o;
return Objects.equals(this.type, authenticationType.type) &&
Objects.equals(this.properties, authenticationType.properties);
}

@Override
public int hashCode() {
return Objects.hash(type, properties);
}

@Override
public String toString() {

StringBuilder sb = new StringBuilder();
sb.append("class AuthenticationType {\n");

sb.append(" type: ").append(toIndentedString(type)).append("\n");
sb.append(" properties: ").append(toIndentedString(properties)).append("\n");
sb.append("}");
return sb.toString();
}

/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(java.lang.Object o) {

if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n");
}
}
Loading

0 comments on commit ba78b41

Please sign in to comment.