diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/common/RESTTestBase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/common/RESTTestBase.java index a6cb31dbaa..a8f0478e67 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/common/RESTTestBase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/common/RESTTestBase.java @@ -1,17 +1,19 @@ /* - * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019-2024, WSO2 LLC. (http://www.wso2.com). * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. + * 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. + * 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.common; @@ -321,6 +323,21 @@ protected Response getResponseOfGetWithQueryParams(String endpointUri, Map h .delete(endpointURI); } + /** + * Invoke the given endpointURL for DELETE with OAuth2 authentication, using the provided access token. + * + * @param endpointURL Endpoint to be invoked. + * @param accessToken OAuth2 access token. + * @return Response. + */ + protected Response getResponseOfDeleteWithOAuth2(String endpointURL, String accessToken) { + + return given().auth().preemptive().oauth2(accessToken) + .contentType(ContentType.JSON) + .when() + .delete(endpointURL); + } + /** * Validate the response to be in the following desired format of Error Response * { * "code": "some_error_code", * "message": "Some Error Message", * "description": "Some Error Description", - * "traceId"" : "corelation-id", + * "traceId"" : "correlation-id", * } * * @param response API error response @@ -774,6 +842,29 @@ protected void validateErrorResponse(Response response, int httpStatusCode, Stri validateErrorDescription(response, errorCode, errorDescriptionArgs); } + /** + * Validate the response to be in the following desired format of Error Response. + * { + * "code": "some_error_code", + * "message": "Some Error Message", + * "description": "Some Error Description" + * } + * + * @param response API error response. + * @param httpStatusCode HTTP status code. + * @param errorCode Error code. + * @param errorDescriptionArgs Placeholder values if error description in RESTAPIErrors.properties contains + * dynamic values. + */ + protected void validateErrorResponseWithoutTraceId(Response response, int httpStatusCode, String errorCode, + String... errorDescriptionArgs) { + + validateHttpStatusCode(response, httpStatusCode); + validateResponseElement(response, "code", is(errorCode)); + validateErrorMessage(response, errorCode); + validateErrorDescription(response, errorCode, errorDescriptionArgs); + } + /** * Validate http status code of the response * diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementBaseTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementBaseTest.java index 9f8bd3aa41..d81b8be152 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementBaseTest.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementBaseTest.java @@ -15,6 +15,7 @@ * specific language governing permissions and limitations * under the License. */ + package org.wso2.identity.integration.test.rest.api.server.organization.management.v1; import io.restassured.RestAssured; diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementFailureTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementFailureTest.java index 539dc0fa84..8eced2102f 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementFailureTest.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementFailureTest.java @@ -15,41 +15,31 @@ * specific language governing permissions and limitations * under the License. */ + package org.wso2.identity.integration.test.rest.api.server.organization.management.v1; -import com.nimbusds.oauth2.sdk.AccessTokenResponse; -import com.nimbusds.oauth2.sdk.AuthorizationGrant; -import com.nimbusds.oauth2.sdk.ClientCredentialsGrant; -import com.nimbusds.oauth2.sdk.Scope; -import com.nimbusds.oauth2.sdk.TokenRequest; -import com.nimbusds.oauth2.sdk.TokenResponse; -import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; -import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; -import com.nimbusds.oauth2.sdk.auth.Secret; -import com.nimbusds.oauth2.sdk.http.HTTPResponse; -import com.nimbusds.oauth2.sdk.id.ClientID; -import io.restassured.http.ContentType; import io.restassured.response.Response; import org.apache.http.HttpHeaders; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.json.JSONException; -import org.json.JSONObject; -import org.testng.Assert; -import org.testng.annotations.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +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.application.management.v1.model.ApplicationListItem; -import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.OpenIDConnectConfiguration; import org.wso2.identity.integration.test.restclients.OAuth2RestClient; import org.wso2.identity.integration.test.utils.OAuth2Constant; +import org.wso2.identity.integration.test.utils.OAuth2Util; import java.io.IOException; import java.net.URI; -import java.util.Iterator; -import java.util.Optional; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; -import static io.restassured.RestAssured.given; import static org.hamcrest.core.IsNull.notNullValue; import static org.testng.Assert.assertNotNull; @@ -58,13 +48,12 @@ */ public class OrganizationManagementFailureTest extends OrganizationManagementBaseTest { - private String organizationID; - private String selfServiceAppId; - private String selfServiceAppClientId; - private String selfServiceAppClientSecret; - private String m2mToken; private final String invalidM2MToken = "06c1f4e2-3339-44e4-a825-96585e3653b1"; private final String invalidOrganizationID = "06c1f4e2-3339-44e4-a825-96585e3653b1"; + + private List organizationIDs = new ArrayList<>(); + private String applicationID; + private String m2mToken; private HttpClient client; protected OAuth2RestClient restClient; @@ -90,7 +79,7 @@ public void init() throws Exception { public void testConclude() throws Exception { super.conclude(); - deleteApplication(selfServiceAppId); + OAuth2Util.deleteApplication(oAuth2RestClient, applicationID); oAuth2RestClient.closeHttpClient(); } @@ -103,366 +92,251 @@ public static Object[][] restAPIUserConfigProvider() { }; } - @Test(groups = "selfOnboardingTests") - public void createApplicationForSelfOrganizationOnboardService() throws IOException, JSONException { + @DataProvider(name = "organizationRequestBodies") + public Object[][] organizationRequestBodyFilePaths() { - String endpointURL = "applications"; - String body = readResource("create-organization-self-service-app-request.body.json"); - - Response response = given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) - .contentType(ContentType.JSON) - .body(body).when().post(endpointURL); - response.then() - .log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_CREATED); - - Optional b2bSelfServiceApp = oAuth2RestClient.getAllApplications().getApplications() - .stream().filter(application -> application.getName().equals("b2b-self-service-app")).findAny(); - Assert.assertTrue(b2bSelfServiceApp.isPresent(), "B2B self service application is not created"); - selfServiceAppId = b2bSelfServiceApp.get().getId(); - - JSONObject jsonObject = new JSONObject(readResource("organization-self-service-apis.json")); - - for (Iterator apiNameIterator = jsonObject.keys(); apiNameIterator.hasNext(); ) { - String apiName = apiNameIterator.next(); - Object requiredScopes = jsonObject.get(apiName); - - Response aPIResource = - given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential).when() - .queryParam("filter", "identifier eq " + apiName).get("api-resources"); - aPIResource.then().log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_OK); - String apiUUID = aPIResource.getBody().jsonPath().getString("apiResources[0].id"); - - JSONObject authorizedAPIRequestBody = new JSONObject(); - authorizedAPIRequestBody.put("id", apiUUID); - authorizedAPIRequestBody.put("policyIdentifier", "RBAC"); - authorizedAPIRequestBody.put("scopes", requiredScopes); - - Response authorizedAPIResponse = - given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) - .contentType(ContentType.JSON).body(authorizedAPIRequestBody.toString()).when() - .post("applications/" + selfServiceAppId + "/authorized-apis"); - authorizedAPIResponse.then().log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_OK); - } + return new Object[][] { + {"add-greater-hospital-organization-request-body.json"}, + {"add-smaller-hospital-organization-request-body.json"} + }; } - @Test(groups = "selfOnboardingTests", dependsOnMethods = "createApplicationForSelfOrganizationOnboardService") - public void getM2MAccessToken() throws Exception { - - OpenIDConnectConfiguration openIDConnectConfiguration = oAuth2RestClient - .getOIDCInboundDetails(selfServiceAppId); - selfServiceAppClientId = openIDConnectConfiguration.getClientId(); - selfServiceAppClientSecret = openIDConnectConfiguration.getClientSecret(); - AuthorizationGrant clientCredentialsGrant = new ClientCredentialsGrant(); - ClientID clientID = new ClientID(selfServiceAppClientId); - Secret clientSecret = new Secret(selfServiceAppClientSecret); - ClientAuthentication clientAuth = new ClientSecretBasic(clientID, clientSecret); - Scope scope = new Scope("SYSTEM"); + @Test + public void testGetM2MAccessToken() throws Exception { + String apiAuthorizations = readResource("organization-self-service-apis.json"); URI tokenEndpoint = new URI(getTenantQualifiedURL(OAuth2Constant.ACCESS_TOKEN_ENDPOINT, tenantInfo.getDomain())); - TokenRequest request = new TokenRequest(tokenEndpoint, clientAuth, clientCredentialsGrant, scope); - HTTPResponse tokenHTTPResp = request.toHTTPRequest().send(); - Assert.assertNotNull(tokenHTTPResp, "Access token http response is null."); - - TokenResponse tokenResponse = TokenResponse.parse(tokenHTTPResp); - AccessTokenResponse accessTokenResponse = tokenResponse.toSuccessResponse(); - m2mToken = accessTokenResponse.getTokens().getAccessToken().getValue(); - Assert.assertNotNull(m2mToken, "The retrieved M2M Token is null in the token response."); - - Scope scopesInResponse = accessTokenResponse.getTokens().getAccessToken().getScope(); - Assert.assertTrue(scopesInResponse.contains("internal_organization_create"), - "Requested scope is missing in the token response"); + applicationID = OAuth2Util.createOIDCApplication(oAuth2RestClient, client, apiAuthorizations, + authenticatingUserName, authenticatingCredential); + m2mToken = OAuth2Util.getM2MAccessToken(oAuth2RestClient, applicationID, tokenEndpoint); } - @Test(groups = "selfOnboardingTests", dependsOnMethods = "getM2MAccessToken") - public void testSelfOnboardOrganization() throws IOException { + @Test(dependsOnMethods = "testGetM2MAccessToken", dataProvider = "organizationRequestBodies") + public void testSelfOnboardOrganization(String requestBodyPath) throws Exception { - String body = readResource("add-organization-request-body.json"); - Response response = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(body) - .when() - .post(ORGANIZATION_MANAGEMENT_API_BASE_PATH); + String body = readResource(requestBodyPath); + Response response = getResponseOfPostWithOAuth2(ORGANIZATION_MANAGEMENT_API_BASE_PATH, body, m2mToken); response.then() .log().ifValidationFails() .assertThat() .statusCode(HttpStatus.SC_CREATED) .header(HttpHeaders.LOCATION, notNullValue()); - String location = response.getHeader(HttpHeaders.LOCATION); assertNotNull(location); - organizationID = location.substring(location.lastIndexOf("/") + 1); + String organizationID = location.substring(location.lastIndexOf("/") + 1); assertNotNull(organizationID); + organizationIDs.add(organizationID); } - @Test(groups = "discoveryConfigTests", dependsOnGroups = "selfOnboardingTests") + @Test(dependsOnMethods = "testSelfOnboardOrganization") + public void testGetDiscoveryConfigWithoutAddingConfig() { + + String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; + Response response = getResponseOfGetWithOAuth2(endpointURL, m2mToken); + validateErrorResponse(response, HttpStatus.SC_NOT_FOUND, "OCM-60002"); + } + + @Test(dependsOnMethods = "testGetDiscoveryConfigWithoutAddingConfig") public void testAddDiscoveryAttributesWithoutAddingConfig() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; String requestBody = readResource("add-discovery-attributes-request-body.json"); - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .post(endpointURL); - validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); + requestBody = requestBody.replace("${organizationID}", organizationIDs.get(0)); + Response response = getResponseOfPostWithOAuth2(endpointURL, requestBody, m2mToken); + validateErrorResponseWithoutTraceId(response, HttpStatus.SC_BAD_REQUEST, "ORG-60080"); } - @Test(groups = "discoveryConfigTests", dependsOnMethods = "testAddDiscoveryAttributesWithoutAddingConfig") + @Test(dependsOnMethods = "testAddDiscoveryAttributesWithoutAddingConfig") public void testAddInvalidDiscoveryConfig() throws IOException { String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; String invalidRequestBody = readResource("invalid-discovery-config-request-body.json"); - Response response = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(invalidRequestBody) - .when() - .post(endpointURL); - validateHttpStatusCode(response, HttpStatus.SC_BAD_REQUEST); + Response response = getResponseOfPostWithOAuth2(endpointURL, invalidRequestBody, m2mToken); + validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "UE-10000"); } - @Test(groups = "discoveryConfigTests", dependsOnMethods = "testAddInvalidDiscoveryConfig") + @Test(dependsOnMethods = "testAddInvalidDiscoveryConfig") public void testAddDiscoveryConfigUnauthorized() throws IOException { String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; String requestBody = readResource("add-discovery-config-request-body.json"); - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .post(endpointURL); + Response response = getResponseOfPostWithOAuth2(endpointURL, requestBody, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - @Test(groups = "discoveryConfigTests", dependsOnMethods = "testAddDiscoveryConfigUnauthorized") + @Test(dependsOnMethods = "testAddDiscoveryConfigUnauthorized") public void testAddExistingDiscoveryConfig() throws IOException { String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; String requestBody = readResource("add-discovery-config-request-body.json"); - Response firstResponse = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .post(endpointURL); + Response firstResponse = getResponseOfPostWithOAuth2(endpointURL, requestBody, m2mToken); validateHttpStatusCode(firstResponse, HttpStatus.SC_CREATED); - Response secondResponse = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .post(endpointURL); - validateHttpStatusCode(secondResponse, HttpStatus.SC_CONFLICT); + Response secondResponse = getResponseOfPostWithOAuth2(endpointURL, requestBody, m2mToken); + validateErrorResponse(secondResponse, HttpStatus.SC_CONFLICT, "OCM-60003"); } - @Test(groups = "discoveryConfigTests", dependsOnMethods = "testAddExistingDiscoveryConfig") + @Test(dependsOnMethods = "testAddExistingDiscoveryConfig") public void testGetDiscoveryConfigUnauthorized() { String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .when() - .get(endpointURL); + Response response = getResponseOfGetWithOAuth2(endpointURL, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - @Test(groups = "discoveryTests", dependsOnGroups = "discoveryConfigTests") + @Test(dependsOnMethods = "testGetDiscoveryConfigUnauthorized") public void testAddInvalidDiscoveryAttributesToOrganization() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; String invalidRequestBody = readResource("add-invalid-discovery-attributes-request-body.json"); - invalidRequestBody = invalidRequestBody.replace("${organizationID}", organizationID); - Response response = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(invalidRequestBody) - .when() - .post(endpointURL); - validateHttpStatusCode(response, HttpStatus.SC_BAD_REQUEST); + invalidRequestBody = invalidRequestBody.replace("${organizationID}", organizationIDs.get(0)); + Response response = getResponseOfPostWithOAuth2(endpointURL, invalidRequestBody, m2mToken); + validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "UE-10000"); } - @Test(groups = "discoveryTests", dependsOnMethods = "testAddInvalidDiscoveryAttributesToOrganization") + @Test(dependsOnMethods = "testAddInvalidDiscoveryAttributesToOrganization") public void testAddDiscoveryAttributesToNonExistingOrganization() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; - String invalidRequestBody = readResource("add-discovery-attributes-request-body.json"); - invalidRequestBody = invalidRequestBody.replace(invalidOrganizationID, organizationID); - Response response = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(invalidRequestBody) - .when() - .post(endpointURL); - validateHttpStatusCode(response, HttpStatus.SC_NOT_FOUND); + String requestBody = readResource("add-discovery-attributes-request-body.json"); + requestBody = requestBody.replace("${organizationID}", invalidOrganizationID); + Response response = getResponseOfPostWithOAuth2(endpointURL, requestBody, m2mToken); + validateErrorResponseWithoutTraceId(response, HttpStatus.SC_NOT_FOUND, "ORG-60015", + invalidOrganizationID); } - @Test(groups = "discoveryTests", dependsOnMethods = "testAddDiscoveryAttributesToNonExistingOrganization") + @Test(dependsOnMethods = "testAddDiscoveryAttributesToNonExistingOrganization") public void testAddDiscoveryAttributesToOrganizationUnauthorized() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; String requestBody = readResource("add-discovery-attributes-request-body.json"); - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .post(endpointURL); + requestBody = requestBody.replace("${organizationID}", organizationIDs.get(0)); + Response response = getResponseOfPostWithOAuth2(endpointURL, requestBody, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - @Test(groups = "discoveryTests", dependsOnMethods = "testAddDiscoveryAttributesToOrganizationUnauthorized") - public void testAddExistingDiscoveryAttributesToOrganization() throws IOException { + @Test(dependsOnMethods = "testAddDiscoveryAttributesToOrganizationUnauthorized") + public void testAddDiscoveryAttributesWhenAlreadyAdded() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; String requestBody = readResource("add-discovery-attributes-request-body.json"); - requestBody = requestBody.replace("${organizationID}", organizationID); - Response firstResponse = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .post(endpointURL); + requestBody = requestBody.replace("${organizationID}", organizationIDs.get(0)); + Response firstResponse = getResponseOfPostWithOAuth2(endpointURL, requestBody, m2mToken); validateHttpStatusCode(firstResponse, HttpStatus.SC_CREATED); - Response secondResponse = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .post(endpointURL); - validateHttpStatusCode(secondResponse, HttpStatus.SC_BAD_REQUEST); + Response secondResponse = getResponseOfPostWithOAuth2(endpointURL, requestBody, m2mToken); + validateErrorResponseWithoutTraceId(secondResponse, HttpStatus.SC_BAD_REQUEST, "ORG-60085", + organizationIDs.get(0)); } - @Test(groups = "discoveryTests", dependsOnMethods = "testAddExistingDiscoveryAttributesToOrganization") + @Test(dependsOnMethods = "testAddDiscoveryAttributesWhenAlreadyAdded") public void testGetDiscoveryAttributesToOrganizationsUnauthorized() { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .when() - .get(endpointURL); + Response response = getResponseOfGetWithOAuth2(endpointURL, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - @Test(groups = "discoveryTests", dependsOnMethods = "testGetDiscoveryAttributesToOrganizationsUnauthorized") + @Test(dependsOnMethods = "testGetDiscoveryAttributesToOrganizationsUnauthorized") public void testGetDiscoveryAttributesOfNonExistingOrganization() { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + invalidOrganizationID + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .when() - .get(endpointURL); - validateHttpStatusCode(response, HttpStatus.SC_NOT_FOUND); + Response response = getResponseOfGetWithOAuth2(endpointURL, m2mToken); + validateErrorResponseWithoutTraceId(response, HttpStatus.SC_NOT_FOUND, "ORG-60015", + invalidOrganizationID); } - @Test(groups = "discoveryTests", dependsOnMethods = "testGetDiscoveryAttributesOfNonExistingOrganization") + @Test(dependsOnMethods = "testGetDiscoveryAttributesOfNonExistingOrganization") public void testGetDiscoveryAttributesToOrganizationUnauthorized() { - String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID + String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationIDs.get(0) + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .when() - .get(endpointURL); + Response response = getResponseOfGetWithOAuth2(endpointURL, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - @Test(groups = "discoveryTests", dependsOnMethods = "testGetDiscoveryAttributesToOrganizationUnauthorized") + @Test(dependsOnMethods = "testGetDiscoveryAttributesToOrganizationUnauthorized") public void testDeleteDiscoveryAttributesOfNonExistingOrganization() { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + invalidOrganizationID + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .when() - .get(endpointURL); - validateHttpStatusCode(response, HttpStatus.SC_NOT_FOUND); + Response response = getResponseOfDeleteWithOAuth2(endpointURL, m2mToken); + validateErrorResponseWithoutTraceId(response, HttpStatus.SC_NOT_FOUND, "ORG-60015", + invalidOrganizationID); } - @Test(groups = "discoveryTests", dependsOnMethods = "testDeleteDiscoveryAttributesOfNonExistingOrganization") + @Test(dependsOnMethods = "testDeleteDiscoveryAttributesOfNonExistingOrganization") public void testDeleteDiscoveryAttributesUnauthorized() { - String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID + String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationIDs.get(0) + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .when() - .delete(endpointURL); + Response response = getResponseOfDeleteWithOAuth2(endpointURL, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - @Test(groups = "discoveryTests", dependsOnMethods = "testDeleteDiscoveryAttributesUnauthorized") + @Test(dependsOnMethods = "testDeleteDiscoveryAttributesUnauthorized") + public void testUpdateWithUnavailableDiscoveryAttributes() throws IOException { + + String firstEndpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationIDs.get(0) + + ORGANIZATION_DISCOVERY_API_PATH; + String secondEndpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationIDs.get(1) + + ORGANIZATION_DISCOVERY_API_PATH; + String requestBody = readResource("update-discovery-attributes-request-body.json"); + Response firstResponse = getResponseOfPutWithOAuth2(firstEndpointURL, requestBody, m2mToken); + validateHttpStatusCode(firstResponse, HttpStatus.SC_OK); + Response secondResponse = getResponseOfPutWithOAuth2(secondEndpointURL, requestBody, m2mToken); + validateErrorResponseWithoutTraceId(secondResponse, HttpStatus.SC_BAD_REQUEST, "ORG-60083"); + } + + @Test(dependsOnMethods = "testUpdateWithUnavailableDiscoveryAttributes") public void testUpdateDiscoveryAttributesOfNonExistingOrganization() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + invalidOrganizationID + ORGANIZATION_DISCOVERY_API_PATH; - String requestBody = readResource("update-discovery-config-request-body.json"); - Response response = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .put(endpointURL); - validateHttpStatusCode(response, HttpStatus.SC_NOT_FOUND); + String requestBody = readResource("update-discovery-attributes-request-body.json"); + Response response = getResponseOfPutWithOAuth2(endpointURL, requestBody, m2mToken); + validateErrorResponseWithoutTraceId(response, HttpStatus.SC_NOT_FOUND, "ORG-60015", + invalidOrganizationID); } - @Test(groups = "discoveryTests", dependsOnMethods = "testUpdateDiscoveryAttributesOfNonExistingOrganization") + @Test(dependsOnMethods = "testUpdateDiscoveryAttributesOfNonExistingOrganization") public void testUpdateDiscoveryAttributesUnauthorized() throws IOException { - String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID + String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationIDs.get(0) + ORGANIZATION_DISCOVERY_API_PATH; - String requestBody = readResource("update-discovery-config-request-body.json"); - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .put(endpointURL); + String requestBody = readResource("update-discovery-attributes-request-body.json"); + Response response = getResponseOfPutWithOAuth2(endpointURL, requestBody, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - @Test(groups = "discoveryTests", dependsOnMethods = "testUpdateDiscoveryAttributesUnauthorized") + @Test(dependsOnMethods = "testUpdateDiscoveryAttributesUnauthorized") public void testCheckDiscoveryAttributeExistsUnauthorized() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + "check-discovery"; - String requestBody = readResource("check-discovery-attributes-request-body.json"); - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .contentType(ContentType.JSON) - .body(requestBody) - .when() - .post(endpointURL); + String requestBody = readResource("check-discovery-attributes-available-request-body.json"); + Response response = getResponseOfPostWithOAuth2(endpointURL, requestBody, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - @Test(groups = "discoveryTests", dependsOnMethods = "testCheckDiscoveryAttributeExistsUnauthorized") - public void testGetDeletedDiscoveryAttributes() { - - deleteDiscoveryAttributes(); - String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID - + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(m2mToken) - .contentType(ContentType.JSON) - .when() - .get(endpointURL); - //Returns an empty "attributes": [] - validateHttpStatusCode(response, HttpStatus.SC_OK); - } - - @Test(dependsOnGroups = "discoveryTests", dependsOnMethods = "testGetDeletedDiscoveryAttributes") + @Test(dependsOnMethods = "testCheckDiscoveryAttributeExistsUnauthorized") public void testDeleteDiscoveryConfigUnauthorized() { String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(invalidM2MToken) - .accept(ContentType.JSON) - .when() - .delete(endpointURL); + Response response = getResponseOfDeleteWithOAuth2(endpointURL, invalidM2MToken); validateHttpStatusCode(response, HttpStatus.SC_UNAUTHORIZED); } - private void deleteDiscoveryAttributes() { - - String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID - + ORGANIZATION_DISCOVERY_API_PATH; - Response response = given().auth().preemptive().oauth2(m2mToken) - .accept(ContentType.JSON) - .when() - .delete(endpointURL); - validateHttpStatusCode(response, HttpStatus.SC_NO_CONTENT); - } - - private void deleteApplication(String applicationId) throws Exception { - - oAuth2RestClient.deleteApplication(applicationId); + @Test(dependsOnMethods = "testDeleteDiscoveryConfigUnauthorized") + public void deleteOrganizations() { + + for (String organizationID : organizationIDs) { + String organizationPath = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID; + Response responseOfDelete = getResponseOfDelete(organizationPath); + responseOfDelete.then() + .log() + .ifValidationFails() + .assertThat() + .statusCode(HttpStatus.SC_NO_CONTENT); + } } } diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementSuccessTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementSuccessTest.java index 688a691935..f90524fb78 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementSuccessTest.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementSuccessTest.java @@ -15,6 +15,7 @@ * specific language governing permissions and limitations * under the License. */ + package org.wso2.identity.integration.test.rest.api.server.organization.management.v1; import com.nimbusds.oauth2.sdk.AccessTokenResponse; @@ -77,6 +78,7 @@ import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.core.IsNull.notNullValue; import static org.testng.Assert.assertNotNull; import static org.wso2.identity.integration.test.restclients.RestBaseClient.CONTENT_TYPE_ATTRIBUTE; @@ -147,11 +149,20 @@ public static Object[][] restAPIUserConfigProvider() { }; } - @Test(groups = "selfOnboardingTests") + @DataProvider(name = "checkDiscoveryAttributes") + public Object[][] checkDiscoveryAttributeFilePaths() { + + return new Object[][]{ + {"check-discovery-attributes-available-request-body.json", true}, + {"check-discovery-attributes-unavailable-request-body.json", false} + }; + } + + @Test public void createApplicationForSelfOrganizationOnboardService() throws IOException, JSONException { String endpointURL = "applications"; - String body = readResource("create-organization-self-service-app-request.body.json"); + String body = readResource("create-organization-self-service-app-request-body.json"); Response response = given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) .contentType(ContentType.JSON) @@ -159,9 +170,8 @@ public void createApplicationForSelfOrganizationOnboardService() throws IOExcept response.then() .log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_CREATED); - Optional b2bSelfServiceApp = oAuth2RestClient.getAllApplications().getApplications().stream() - .filter(application -> application.getName().equals("b2b-self-service-app")) - .findAny(); + Optional b2bSelfServiceApp = oAuth2RestClient.getAllApplications().getApplications() + .stream().filter(application -> application.getName().equals("b2b-self-service-app")).findAny(); Assert.assertTrue(b2bSelfServiceApp.isPresent(), "B2B self service application is not created"); selfServiceAppId = b2bSelfServiceApp.get().getId(); @@ -171,11 +181,10 @@ public void createApplicationForSelfOrganizationOnboardService() throws IOExcept String apiName = apiNameIterator.next(); Object requiredScopes = jsonObject.get(apiName); - Response aPIResource = - given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential).when() - .queryParam("filter", "identifier eq " + apiName).get("api-resources"); - aPIResource.then().log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_OK); - String apiUUID = aPIResource.getBody().jsonPath().getString("apiResources[0].id"); + Response apiResource = given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) + .when().queryParam("filter", "identifier eq " + apiName).get("api-resources"); + apiResource.then().log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_OK); + String apiUUID = apiResource.getBody().jsonPath().getString("apiResources[0].id"); JSONObject authorizedAPIRequestBody = new JSONObject(); authorizedAPIRequestBody.put("id", apiUUID); @@ -190,10 +199,11 @@ public void createApplicationForSelfOrganizationOnboardService() throws IOExcept } } - @Test(groups = "selfOnboardingTests", dependsOnMethods = "createApplicationForSelfOrganizationOnboardService") + @Test(dependsOnMethods = "createApplicationForSelfOrganizationOnboardService") public void getM2MAccessToken() throws Exception { - OpenIDConnectConfiguration openIDConnectConfiguration = oAuth2RestClient.getOIDCInboundDetails(selfServiceAppId); + OpenIDConnectConfiguration openIDConnectConfiguration = oAuth2RestClient + .getOIDCInboundDetails(selfServiceAppId); selfServiceAppClientId = openIDConnectConfiguration.getClientId(); selfServiceAppClientSecret = openIDConnectConfiguration.getClientSecret(); AuthorizationGrant clientCredentialsGrant = new ClientCredentialsGrant(); @@ -202,7 +212,8 @@ public void getM2MAccessToken() throws Exception { ClientAuthentication clientAuth = new ClientSecretBasic(clientID, clientSecret); Scope scope = new Scope("SYSTEM"); - URI tokenEndpoint = new URI(getTenantQualifiedURL(OAuth2Constant.ACCESS_TOKEN_ENDPOINT, tenantInfo.getDomain())); + URI tokenEndpoint = new URI(getTenantQualifiedURL(OAuth2Constant.ACCESS_TOKEN_ENDPOINT, + tenantInfo.getDomain())); TokenRequest request = new TokenRequest(tokenEndpoint, clientAuth, clientCredentialsGrant, scope); HTTPResponse tokenHTTPResp = request.toHTTPRequest().send(); Assert.assertNotNull(tokenHTTPResp, "Access token http response is null."); @@ -213,35 +224,35 @@ public void getM2MAccessToken() throws Exception { Assert.assertNotNull(m2mToken, "The retrieved M2M Token is null in the token response."); Scope scopesInResponse = accessTokenResponse.getTokens().getAccessToken().getScope(); - Assert.assertTrue(scopesInResponse.contains("internal_organization_create"), "Requested scope is missing in the token response"); + Assert.assertTrue(scopesInResponse.contains("internal_organization_create"), + "Requested scope is missing in the token response"); } - @Test(groups = "selfOnboardingTests", dependsOnMethods = "getM2MAccessToken") + @Test(dependsOnMethods = "getM2MAccessToken") public void testSelfOnboardOrganization() throws IOException { - String body = readResource("add-organization-request-body.json"); + String body = readResource("add-greater-hospital-organization-request-body.json"); Response response = given().auth().preemptive().oauth2(m2mToken) .contentType(ContentType.JSON) .body(body) .when() .post(ORGANIZATION_MANAGEMENT_API_BASE_PATH); - response.then() .log().ifValidationFails() .assertThat() .statusCode(HttpStatus.SC_CREATED) .header(HttpHeaders.LOCATION, notNullValue()); - String location = response.getHeader(HttpHeaders.LOCATION); assertNotNull(location); organizationID = location.substring(location.lastIndexOf("/") + 1); assertNotNull(organizationID); } - @Test(groups = "organizationManagementTests", dependsOnGroups = "selfOnboardingTests") + @Test(dependsOnMethods = "testSelfOnboardOrganization") public void testGetOrganization() { - Response response = getResponseOfGet(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID); + Response response = getResponseOfGet( + ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID); validateHttpStatusCode(response, HttpStatus.SC_OK); Assert.assertNotNull(response.asString()); response.then() @@ -251,7 +262,7 @@ public void testGetOrganization() { .body("id", equalTo(organizationID)); } - @Test(groups = "organizationManagementTests", dependsOnMethods = "testGetOrganization") + @Test(dependsOnMethods = "testGetOrganization") public void switchM2MToken() throws IOException, ParseException, InterruptedException { ApplicationSharePOSTRequest applicationSharePOSTRequest = new ApplicationSharePOSTRequest(); @@ -269,8 +280,8 @@ public void switchM2MToken() throws IOException, ParseException, InterruptedExce urlParameters.add(new BasicNameValuePair("switching_organization", organizationID)); HttpPost httpPost = new HttpPost(getTenantQualifiedURL(OAuth2Constant.ACCESS_TOKEN_ENDPOINT, tenant)); - httpPost.setHeader("Authorization", "Basic " + - new String(Base64.encodeBase64((selfServiceAppClientId + ":" + selfServiceAppClientSecret).getBytes()))); + httpPost.setHeader("Authorization", "Basic " + new String(Base64.encodeBase64( + (selfServiceAppClientId + ":" + selfServiceAppClientSecret).getBytes()))); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); @@ -285,11 +296,12 @@ public void switchM2MToken() throws IOException, ParseException, InterruptedExce Assert.assertNotNull(switchedM2MToken); } - @Test(groups = "organizationManagementTests", dependsOnMethods = "switchM2MToken") + @Test(dependsOnMethods = "switchM2MToken") public void createUserInOrganization() throws IOException { String body = readResource("add-admin-user-in-organization-request-body.json"); - HttpPost request = new HttpPost(serverURL + TENANT_PATH + tenant + PATH_SEPARATOR + ORGANIZATION_PATH + SCIM2_USERS_ENDPOINT); + HttpPost request = new HttpPost( + serverURL + TENANT_PATH + tenant + PATH_SEPARATOR + ORGANIZATION_PATH + SCIM2_USERS_ENDPOINT); Header[] headerList = new Header[2]; headerList[0] = new BasicHeader("Authorization", "Bearer " + switchedM2MToken); headerList[1] = new BasicHeader(CONTENT_TYPE_ATTRIBUTE, "application/scim+json"); @@ -299,7 +311,7 @@ public void createUserInOrganization() throws IOException { Assert.assertEquals(response.getStatusLine().getStatusCode(), 201); } - @Test(groups = "organizationManagementTests", dependsOnMethods = "createUserInOrganization") + @Test(dependsOnMethods = "createUserInOrganization") public void addB2BApplication() throws Exception { ApplicationModel application = new ApplicationModel(); @@ -316,7 +328,7 @@ public void addB2BApplication() throws Exception { Assert.assertNotNull(b2bApplicationID); } - @Test(groups = "organizationManagementTests", dependsOnMethods = "addB2BApplication") + @Test(dependsOnMethods = "addB2BApplication") public void shareB2BApplication() throws JSONException { if (!SUPER_TENANT_DOMAIN.equals(tenant)) { @@ -329,7 +341,7 @@ public void shareB2BApplication() throws JSONException { getResponseOfPost(shareApplicationUrl, shareAppObject.toString()); } - @Test(groups = "organizationManagementTests", dependsOnMethods = "shareB2BApplication") + @Test(dependsOnMethods = "shareB2BApplication") public void unShareB2BApplication() throws JSONException { if (!SUPER_TENANT_DOMAIN.equals(tenant)) { @@ -342,7 +354,7 @@ public void unShareB2BApplication() throws JSONException { getResponseOfPost(shareApplicationUrl, shareAppObject.toString()); } - @Test(groups = "discoveryConfigTests", dependsOnGroups = "organizationManagementTests") + @Test(dependsOnMethods = "unShareB2BApplication") public void testAddDiscoveryConfig() throws IOException { String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; @@ -361,7 +373,7 @@ public void testAddDiscoveryConfig() throws IOException { .body("properties[0].value", equalTo("true")); } - @Test(groups = "discoveryConfigTests", dependsOnMethods = "testAddDiscoveryConfig") + @Test(dependsOnMethods = "testAddDiscoveryConfig") public void testGetDiscoveryConfig() { String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; @@ -378,7 +390,7 @@ public void testGetDiscoveryConfig() { .body("properties[0].value", equalTo("true")); } - @Test(groups = "discoveryTests", dependsOnGroups = "discoveryConfigTests") + @Test(dependsOnMethods = "testGetDiscoveryConfig") public void testAddDiscoveryAttributesToOrganization() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; @@ -395,7 +407,7 @@ public void testAddDiscoveryAttributesToOrganization() throws IOException { .statusCode(HttpStatus.SC_CREATED); } - @Test(groups = "discoveryTests", dependsOnMethods = "testAddDiscoveryAttributesToOrganization") + @Test(dependsOnMethods = "testAddDiscoveryAttributesToOrganization") public void testGetDiscoveryAttributesOfOrganizations() { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; @@ -414,7 +426,7 @@ public void testGetDiscoveryAttributesOfOrganizations() { .body("organizations[0].attributes[0].values[0]", equalTo("abc.com")); } - @Test(groups = "discoveryTests", dependsOnMethods = "testGetDiscoveryAttributesOfOrganizations") + @Test(dependsOnMethods = "testGetDiscoveryAttributesOfOrganizations") public void testGetDiscoveryAttributesOfOrganization() { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID @@ -431,12 +443,12 @@ public void testGetDiscoveryAttributesOfOrganization() { .body("attributes[0].values[0]", equalTo("abc.com")); } - @Test(groups = "discoveryTests", dependsOnMethods = "testGetDiscoveryAttributesOfOrganization") + @Test(dependsOnMethods = "testGetDiscoveryAttributesOfOrganization") public void testUpdateDiscoveryAttributesOfOrganization() throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID + ORGANIZATION_DISCOVERY_API_PATH; - String requestBody = readResource("update-discovery-config-request-body.json"); + String requestBody = readResource("update-discovery-attributes-request-body.json"); Response response = given().auth().preemptive().oauth2(m2mToken) .contentType(ContentType.JSON) .body(requestBody) @@ -446,14 +458,16 @@ public void testUpdateDiscoveryAttributesOfOrganization() throws IOException { .log().ifValidationFails() .assertThat() .statusCode(HttpStatus.SC_OK) - .body("attributes[0].values[0]", equalTo("xyz.com")); + .body("attributes[0].type", equalTo("emailDomain")) + .body("attributes[0].values", containsInAnyOrder("xyz.com", "example.com")); } - @Test(groups = "discoveryTests", dependsOnMethods = "testGetDiscoveryAttributesOfOrganization") - public void testCheckDiscoveryAttributeExists() throws IOException { + @Test(dependsOnMethods = "testUpdateDiscoveryAttributesOfOrganization", dataProvider = "checkDiscoveryAttributes") + public void testCheckDiscoveryAttributeExists(String requestBodyFileName, boolean expectedAvailability) + throws IOException { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + "check-discovery"; - String requestBody = readResource("check-discovery-attributes-request-body.json"); + String requestBody = readResource(requestBodyFileName); Response response = given().auth().preemptive().oauth2(m2mToken) .contentType(ContentType.JSON) .body(requestBody) @@ -463,10 +477,10 @@ public void testCheckDiscoveryAttributeExists() throws IOException { .log().ifValidationFails() .assertThat() .statusCode(HttpStatus.SC_OK) - .body("available", equalTo(true)); + .body("available", equalTo(expectedAvailability)); } - @Test(groups = "discoveryTests", dependsOnMethods = "testUpdateDiscoveryAttributesOfOrganization") + @Test(dependsOnMethods = "testCheckDiscoveryAttributeExists") public void testDeleteDiscoveryAttributesOfOrganization() { String endpointURL = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID @@ -481,7 +495,7 @@ public void testDeleteDiscoveryAttributesOfOrganization() { .statusCode(HttpStatus.SC_NO_CONTENT); } - @Test(dependsOnGroups = "discoveryTests") + @Test(dependsOnMethods = "testDeleteDiscoveryAttributesOfOrganization") public void testDeleteDiscoveryConfig() { String endpointURL = ORGANIZATION_CONFIGS_API_BASE_PATH + ORGANIZATION_DISCOVERY_API_PATH; diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/utils/OAuth2Util.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/utils/OAuth2Util.java new file mode 100644 index 0000000000..830749e3de --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/utils/OAuth2Util.java @@ -0,0 +1,141 @@ +/* + * 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.utils; + +import com.nimbusds.oauth2.sdk.AccessTokenResponse; +import com.nimbusds.oauth2.sdk.AuthorizationGrant; +import com.nimbusds.oauth2.sdk.ClientCredentialsGrant; +import com.nimbusds.oauth2.sdk.Scope; +import com.nimbusds.oauth2.sdk.TokenRequest; +import com.nimbusds.oauth2.sdk.TokenResponse; +import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; +import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic; +import com.nimbusds.oauth2.sdk.auth.Secret; +import com.nimbusds.oauth2.sdk.http.HTTPResponse; +import com.nimbusds.oauth2.sdk.id.ClientID; + +import org.json.JSONException; +import org.json.JSONObject; +import org.apache.http.client.HttpClient; +import org.apache.http.HttpStatus; +import org.testng.Assert; +import io.restassured.response.Response; +import static io.restassured.RestAssured.given; +import io.restassured.http.ContentType; +import org.wso2.identity.integration.test.rest.api.common.RESTTestBase; +import org.wso2.identity.integration.test.restclients.OAuth2RestClient; +import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.ApplicationListItem; +import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.OpenIDConnectConfiguration; + +import java.io.IOException; +import java.net.URI; +import java.util.Iterator; +import java.util.Optional; + +/** + * Utility class for creating OIDC applications and obtaining M2M access tokens via OAuth2. + */ +public final class OAuth2Util { + + public static String createOIDCApplication(OAuth2RestClient oAuth2RestClient, HttpClient client, + String apiAuthorizations, String authenticatingUserName, + String authenticatingCredential) throws IOException, JSONException { + + String endpointURL = "applications"; + String body = readResource("create-oidc-app-request-body.json"); + + Response response = given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) + .contentType(ContentType.JSON) + .body(body).when().post(endpointURL); + response.then() + .log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_CREATED); + + Optional application = oAuth2RestClient.getAllApplications().getApplications() + .stream().filter(app -> app.getName().equals("oidc-app")).findAny(); + Assert.assertTrue(application.isPresent(), "OIDC Application is not created"); + String applicationId = application.get().getId(); + + JSONObject jsonObject = new JSONObject(apiAuthorizations); + + for (Iterator apiNameIterator = jsonObject.keys(); apiNameIterator.hasNext(); ) { + String apiName = apiNameIterator.next(); + Object requiredScopes = jsonObject.get(apiName); + Response apiResource = + given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential).when() + .queryParam("filter", "identifier eq " + apiName).get("api-resources"); + apiResource.then().log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_OK); + String apiUUID = apiResource.getBody().jsonPath().getString("apiResources[0].id"); + + JSONObject authorizedAPIRequestBody = new JSONObject(); + authorizedAPIRequestBody.put("id", apiUUID); + authorizedAPIRequestBody.put("policyIdentifier", "RBAC"); + authorizedAPIRequestBody.put("scopes", requiredScopes); + + Response authorizedAPIResponse = + given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) + .contentType(ContentType.JSON).body(authorizedAPIRequestBody.toString()).when() + .post("applications/" + applicationId + "/authorized-apis"); + authorizedAPIResponse.then().log().ifValidationFails().assertThat().statusCode(HttpStatus.SC_OK); + } + return applicationId; + } + + public static String getM2MAccessToken(OAuth2RestClient oAuth2RestClient, String applicationId, URI tokenEndpoint) + throws Exception { + + OpenIDConnectConfiguration openIDConnectConfiguration = oAuth2RestClient.getOIDCInboundDetails(applicationId); + TokenRequest request = getTokenRequest(tokenEndpoint, openIDConnectConfiguration); + HTTPResponse tokenHTTPResp = request.toHTTPRequest().send(); + Assert.assertNotNull(tokenHTTPResp, "Access token http response is null."); + + TokenResponse tokenResponse = TokenResponse.parse(tokenHTTPResp); + AccessTokenResponse accessTokenResponse = tokenResponse.toSuccessResponse(); + String m2mToken = accessTokenResponse.getTokens().getAccessToken().getValue(); + Assert.assertNotNull(m2mToken, "The retrieved M2M Token is null in the token response."); + + Scope scopesInResponse = accessTokenResponse.getTokens().getAccessToken().getScope(); + Assert.assertTrue(scopesInResponse.contains("internal_organization_create"), + "Requested scope is missing in the token response"); + return m2mToken; + } + + private static TokenRequest getTokenRequest(URI tokenEndpoint, + OpenIDConnectConfiguration openIDConnectConfiguration) { + + String selfServiceAppClientId = openIDConnectConfiguration.getClientId(); + String selfServiceAppClientSecret = openIDConnectConfiguration.getClientSecret(); + AuthorizationGrant clientCredentialsGrant = new ClientCredentialsGrant(); + ClientID clientID = new ClientID(selfServiceAppClientId); + Secret clientSecret = new Secret(selfServiceAppClientSecret); + ClientAuthentication clientAuth = new ClientSecretBasic(clientID, clientSecret); + Scope scope = new Scope("SYSTEM"); + TokenRequest request = new TokenRequest(tokenEndpoint, clientAuth, clientCredentialsGrant, scope); + return request; + } + + public static void deleteApplication(OAuth2RestClient oAuth2RestClient, String applicationId) throws Exception { + + oAuth2RestClient.deleteApplication(applicationId); + } + + private static String readResource(String filename) throws IOException { + + return RESTTestBase.readResource(filename, org.wso2.identity.integration.test.utils.OAuth2Util.class); + } +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-organization-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-greater-hospital-organization-request-body.json similarity index 100% rename from modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-organization-request-body.json rename to modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-greater-hospital-organization-request-body.json diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-smaller-hospital-organization-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-smaller-hospital-organization-request-body.json new file mode 100644 index 0000000000..dd51eb9813 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-smaller-hospital-organization-request-body.json @@ -0,0 +1,14 @@ +{ + "name": "Smaller Hospital", + "description": "Hospital chain in South Asia", + "attributes": [ + { + "key": "Country", + "value": "Sri Lanka" + }, + { + "key": "Language", + "value": "Sinhala" + } + ] +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/check-discovery-attributes-available-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/check-discovery-attributes-available-request-body.json new file mode 100644 index 0000000000..601e274597 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/check-discovery-attributes-available-request-body.json @@ -0,0 +1,4 @@ +{ + "type": "emailDomain", + "value": "abc.com" +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/check-discovery-attributes-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/check-discovery-attributes-unavailable-request-body.json similarity index 100% rename from modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/check-discovery-attributes-request-body.json rename to modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/check-discovery-attributes-unavailable-request-body.json diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/create-organization-self-service-app-request.body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/create-organization-self-service-app-request-body.json similarity index 100% rename from modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/create-organization-self-service-app-request.body.json rename to modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/create-organization-self-service-app-request-body.json diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/update-discovery-config-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/update-discovery-attributes-request-body.json similarity index 69% rename from modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/update-discovery-config-request-body.json rename to modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/update-discovery-attributes-request-body.json index 5aac6c29e1..6553bcda7f 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/update-discovery-config-request-body.json +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/update-discovery-attributes-request-body.json @@ -3,7 +3,8 @@ { "type": "emailDomain", "values": [ - "xyz.com" + "xyz.com", + "example.com" ] } ] diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/utils/create-oidc-app-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/utils/create-oidc-app-request-body.json new file mode 100644 index 0000000000..4429e6748c --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/utils/create-oidc-app-request-body.json @@ -0,0 +1,12 @@ +{ + "name": "oidc-app", + "templateId": "custom-application-oidc", + "inboundProtocolConfiguration": { + "oidc": { + "grantTypes": [ + "client_credentials", + "organization_switch" + ] + } + } +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml b/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml index aae33d8d42..b02623ffa8 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml @@ -217,6 +217,7 @@ +