From 1933980b71e20f8c59c6754e17ff1e19e0adb1d0 Mon Sep 17 00:00:00 2001 From: sadilchamishka Date: Sat, 2 Dec 2023 16:18:26 +0530 Subject: [PATCH 1/6] Add initial organization management tests --- .../v2/OrganizationManagementBaseTest.java | 72 ++++ .../v2/OrganizationManagementFailureTest.java | 152 ++++++++ .../v2/OrganizationManagementSuccessTest.java | 122 ++++++ .../v2/model/OrganizationUpdateRequest.java | 143 +++++++ .../v2/add-organization-request-body.json | 3 + .../src/test/resources/testng.xml | 359 +----------------- pom.xml | 2 +- 7 files changed, 494 insertions(+), 359 deletions(-) create mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java create mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementFailureTest.java create mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java create mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/model/OrganizationUpdateRequest.java create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/add-organization-request-body.json diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java new file mode 100644 index 00000000000..4be5d5f3628 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023, 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.organization.management.v2; + +import io.restassured.RestAssured; +import org.apache.commons.lang.StringUtils; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.wso2.identity.integration.test.rest.api.server.common.RESTAPIServerTestBase; + +import java.io.IOException; + +/** + * Base test class for the OIDC Scope Management REST APIs. + */ +public class OrganizationManagementBaseTest extends RESTAPIServerTestBase { + + private static final String API_DEFINITION_NAME = "org.wso2.carbon.identity.organization.management.yaml"; + static final String API_VERSION = "v1"; + + static final String ORGANIZATION_MANAGEMENT_API_BASE_PATH = "/organizations"; + static final String PATH_SEPARATOR = "/"; + + protected static String swaggerDefinition; + + static { + String API_PACKAGE_NAME = "org.wso2.carbon.identity.api.server.organization.management.v1"; + + try { + swaggerDefinition = getAPISwaggerDefinition(API_PACKAGE_NAME, API_DEFINITION_NAME); + } catch (IOException e) { + Assert.fail(String.format("Unable to read the swagger definition %s from %s", API_DEFINITION_NAME, + API_PACKAGE_NAME), e); + } + } + + @AfterClass(alwaysRun = true) + public void testConclude() throws Exception { + + super.conclude(); + } + + @BeforeMethod(alwaysRun = true) + public void testInit() { + + RestAssured.basePath = basePath; + } + + @AfterMethod(alwaysRun = true) + public void testFinish() { + + RestAssured.basePath = StringUtils.EMPTY; + } + +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementFailureTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementFailureTest.java new file mode 100644 index 00000000000..1885ef0b774 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementFailureTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2023, 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.organization.management.v2; + +import io.restassured.RestAssured; +import io.restassured.response.Response; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpStatus; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; +import org.wso2.carbon.automation.engine.context.TestUserMode; + +import java.io.IOException; +import java.util.HashMap; + +import static org.hamcrest.core.IsNull.notNullValue; +import static org.testng.Assert.assertNotNull; + +/** + * Tests for failure cases of the OIDC Scope Management REST APIs. + */ +public class OrganizationManagementFailureTest extends OrganizationManagementBaseTest { + + String scopeId; + + @Factory(dataProvider = "restAPIUserConfigProvider") + public OrganizationManagementFailureTest(TestUserMode userMode) throws Exception { + + super.init(userMode); + this.context = isServer; + this.authenticatingUserName = context.getContextTenant().getTenantAdmin().getUserName(); + this.authenticatingCredential = context.getContextTenant().getTenantAdmin().getPassword(); + this.tenant = context.getContextTenant().getDomain(); + } + + @BeforeClass(alwaysRun = true) + public void init() throws IOException { + + super.testInit(API_VERSION, swaggerDefinition, tenant); + } + + @AfterClass(alwaysRun = true) + public void testConclude() { + + super.conclude(); + } + + @BeforeMethod(alwaysRun = true) + public void testInit() { + + RestAssured.basePath = basePath; + } + + @AfterMethod(alwaysRun = true) + public void testFinish() { + + RestAssured.basePath = StringUtils.EMPTY; + } + + @DataProvider(name = "restAPIUserConfigProvider") + public static Object[][] restAPIUserConfigProvider() { + + return new Object[][]{ + {TestUserMode.SUPER_TENANT_ADMIN}, + {TestUserMode.TENANT_ADMIN} + }; + } + + @Test + public void testAddOIDCScope() throws IOException { + + Response response = getResponseOfJSONPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, + readResource("add-scope-request-body1.json"), new HashMap<>()); + response.then() + .log().ifValidationFails() + .assertThat() + .statusCode(HttpStatus.SC_CREATED) + .header(HttpHeaders.LOCATION, notNullValue()); + + String location = response.getHeader(HttpHeaders.LOCATION); + assertNotNull(location); + scopeId = location.substring(location.lastIndexOf("/") + 1); + assertNotNull(scopeId); + } + + @Test(dependsOnMethods = "testAddOIDCScope") + public void testAddExistingOIDCScope() throws IOException { + + Response response = getResponseOfJSONPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, + readResource("add-scope-request-body1.json"), new HashMap<>()); + validateHttpStatusCode(response, HttpStatus.SC_CONFLICT); + } + + @Test(dependsOnMethods = "testAddExistingOIDCScope") + public void testAddInvalidOIDCScope() throws IOException { + + Response response = getResponseOfJSONPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, + readResource("add-invalid-scope-request-body1.json"), new HashMap<>()); + validateHttpStatusCode(response, HttpStatus.SC_BAD_REQUEST); + } + + @Test(dependsOnMethods = "testAddInvalidOIDCScope") + public void testDeleteOIDCScope() { + + // Delete an existing scope by id. + Response response = getResponseOfDelete(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + scopeId); + validateHttpStatusCode(response, HttpStatus.SC_NO_CONTENT); + + // Try to delete the same scope again. DELETE should be idempotent. + Response responseOfDeleteFailure = + getResponseOfDelete(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + scopeId); + validateHttpStatusCode(responseOfDeleteFailure, HttpStatus.SC_NO_CONTENT); + } + + @Test(dependsOnMethods = "testDeleteOIDCScope") + public void testGetDeletedOIDCScope() { + + Response responseAfterDelete = getResponseOfGet( + ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + scopeId); + validateHttpStatusCode(responseAfterDelete, HttpStatus.SC_NOT_FOUND); + } + + @Test(dependsOnMethods = "testGetDeletedOIDCScope") + public void testUpdateNotExistingOIDCScope() throws IOException { + + Response response = getResponseOfPut(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + scopeId, + readResource("update-scope-request-body1.json")); + validateHttpStatusCode(response, HttpStatus.SC_NOT_FOUND); + } + +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java new file mode 100644 index 00000000000..a98787fb751 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023, 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.organization.management.v2; + +import io.restassured.RestAssured; +import io.restassured.response.Response; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpStatus; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; +import org.wso2.carbon.automation.engine.context.TestUserMode; + +import java.io.IOException; +import java.util.HashMap; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.testng.Assert.assertNotNull; + +/** + * Tests for successful cases of the Organization Management REST APIs. + */ +public class OrganizationManagementSuccessTest extends OrganizationManagementBaseTest { + + private String organizationId; + + @Factory(dataProvider = "restAPIUserConfigProvider") + public OrganizationManagementSuccessTest(TestUserMode userMode) throws Exception { + + super.init(userMode); + this.context = isServer; + this.authenticatingUserName = context.getContextTenant().getTenantAdmin().getUserName(); + this.authenticatingCredential = context.getContextTenant().getTenantAdmin().getPassword(); + this.tenant = context.getContextTenant().getDomain(); + } + + @BeforeClass(alwaysRun = true) + public void init() throws IOException { + + super.testInit(API_VERSION, swaggerDefinition, tenant); + } + + @AfterClass(alwaysRun = true) + public void testConclude() { + + super.conclude(); + } + + @BeforeMethod(alwaysRun = true) + public void testInit() { + + RestAssured.basePath = basePath; + } + + @AfterMethod(alwaysRun = true) + public void testFinish() { + + RestAssured.basePath = StringUtils.EMPTY; + } + + @DataProvider(name = "restAPIUserConfigProvider") + public static Object[][] restAPIUserConfigProvider() { + + return new Object[][]{ + {TestUserMode.SUPER_TENANT_ADMIN}, + {TestUserMode.TENANT_ADMIN} + }; + } + + @Test + public void testAddOrganization() throws IOException { + + String body = readResource("add-organization-request-body.json"); + Response response = getResponseOfJSONPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, + body, new HashMap<>()); + 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(dependsOnMethods = "testAddOrganization") + public void testGetOrganization() { + + Response response = getResponseOfGet(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationId); + validateHttpStatusCode(response, HttpStatus.SC_OK); + Assert.assertNotNull(response.asString()); + response.then() + .log().ifValidationFails() + .assertThat() + .statusCode(HttpStatus.SC_OK) + .body("id", equalTo(organizationId)); + } +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/model/OrganizationUpdateRequest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/model/OrganizationUpdateRequest.java new file mode 100644 index 00000000000..e09e8b696e4 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/model/OrganizationUpdateRequest.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2023, 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.organization.management.v2.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class OrganizationUpdateRequest { + private String displayName; + private String description; + private List claims = null; + + /** + * + **/ + public OrganizationUpdateRequest displayName(String displayName) { + + this.displayName = displayName; + return this; + } + + @ApiModelProperty(example = "scopeOne") + @JsonProperty("displayName") + @Valid + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + /** + * + **/ + public OrganizationUpdateRequest description(String description) { + + this.description = description; + return this; + } + + @ApiModelProperty(example = "Sample updated scope one") + @JsonProperty("description") + @Valid + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + /** + * + **/ + public OrganizationUpdateRequest claims(List claims) { + + this.claims = claims; + return this; + } + + @ApiModelProperty(example = "Sample updated scope one") + @JsonProperty("claims") + @Valid + public List getClaims() { + return claims; + } + + public void setClaims(List claims) { + this.claims = claims; + } + + public OrganizationUpdateRequest addClaims(String claim) { + if (this.claims == null) { + this.claims = new ArrayList<>(); + } + this.claims.add(claim); + return this; + } + + @Override + public boolean equals(Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OrganizationUpdateRequest scope = (OrganizationUpdateRequest) o; + return Objects.equals(this.displayName, scope.displayName) && + Objects.equals(this.description, scope.description) && + Objects.equals(this.claims, scope.claims); + } + + @Override + public int hashCode() { + return Objects.hash(displayName, description, claims); + } + + @Override + public String toString() { + + return "class ScopeUpdateRequest {\n" + + " displayName: " + toIndentedString(displayName) + "\n" + + " description: " + toIndentedString(description) + "\n" + + " claims: " + toIndentedString(claims) + "\n" + + "}"; + } + + /** + * 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(); + } +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/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/v2/add-organization-request-body.json new file mode 100644 index 00000000000..469477887f5 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/add-organization-request-body.json @@ -0,0 +1,3 @@ +{ + "name": "EasyMeet" +} 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 4e041e3a590..cef3f65afb0 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 @@ -11,366 +11,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index 69b552f59f2..03d2376260d 100755 --- a/pom.xml +++ b/pom.xml @@ -2405,7 +2405,7 @@ 2.0.13 1.3.28 - 1.2.134 + 1.2.135 5.5.9 5.5.7 From 901ac6af7a7846824cedd54a9518651432b13b0a Mon Sep 17 00:00:00 2001 From: sadilchamishka Date: Sat, 2 Dec 2023 18:25:07 +0530 Subject: [PATCH 2/6] Self organization management integration tests --- .../v2/OrganizationManagementBaseTest.java | 2 + .../v2/OrganizationManagementSuccessTest.java | 100 +++++++++++++++++- ...elf-organization-onboard-request-body.json | 9 ++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/enable-self-organization-onboard-request-body.json diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java index 4be5d5f3628..5d8d36a4ac5 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java @@ -24,6 +24,7 @@ import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.wso2.identity.integration.test.rest.api.server.common.RESTAPIServerTestBase; +import org.wso2.identity.integration.test.restclients.OAuth2RestClient; import java.io.IOException; @@ -39,6 +40,7 @@ public class OrganizationManagementBaseTest extends RESTAPIServerTestBase { static final String PATH_SEPARATOR = "/"; protected static String swaggerDefinition; + protected OAuth2RestClient oAuth2RestClient; static { String API_PACKAGE_NAME = "org.wso2.carbon.identity.api.server.organization.management.v1"; diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java index a98787fb751..d38c07da8cc 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java @@ -17,7 +17,18 @@ */ package org.wso2.identity.integration.test.rest.api.server.organization.management.v2; +import com.nimbusds.oauth2.sdk.AccessTokenResponse; +import com.nimbusds.oauth2.sdk.AuthorizationGrant; +import com.nimbusds.oauth2.sdk.ResourceOwnerPasswordCredentialsGrant; +import com.nimbusds.oauth2.sdk.Scope; +import com.nimbusds.oauth2.sdk.TokenRequest; +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.RestAssured; +import io.restassured.http.ContentType; import io.restassured.response.Response; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpHeaders; @@ -31,13 +42,29 @@ 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.ApplicationModel; +import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.ApplicationPatchModel; +import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.AssociatedRolesConfig; +import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.InboundProtocols; +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 java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; +import java.util.Optional; +import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.core.IsNull.notNullValue; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; /** * Tests for successful cases of the Organization Management REST APIs. @@ -45,6 +72,8 @@ public class OrganizationManagementSuccessTest extends OrganizationManagementBaseTest { private String organizationId; + private String selfServiceAppId; + private String applicationId; @Factory(dataProvider = "restAPIUserConfigProvider") public OrganizationManagementSuccessTest(TestUserMode userMode) throws Exception { @@ -57,9 +86,11 @@ public OrganizationManagementSuccessTest(TestUserMode userMode) throws Exception } @BeforeClass(alwaysRun = true) - public void init() throws IOException { + public void init() throws Exception { super.testInit(API_VERSION, swaggerDefinition, tenant); + oAuth2RestClient = new OAuth2RestClient(serverURL, tenantInfo); + //applicationId = addApplication(); } @AfterClass(alwaysRun = true) @@ -119,4 +150,71 @@ public void testGetOrganization() { .statusCode(HttpStatus.SC_OK) .body("id", equalTo(organizationId)); } + + @Test + public void enableSelfOrganizationOnboardService() throws IOException { + + String endpointURL = "self-service/preferences"; + String body = readResource("enable-self-organization-onboard-request-body.json"); + + Response response = given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) + .contentType(ContentType.JSON) + .body(body) + .when() + .patch(endpointURL); + response.then() + .log().ifValidationFails() + .assertThat() + .statusCode(HttpStatus.SC_OK); + + Optional b2bSelfServiceApp = oAuth2RestClient.getAllApplications().getApplications().stream() + .filter(application -> application.getName().equals("B2B-Self-Service-Mgt-Application")) + .findAny(); + Assert.assertTrue(b2bSelfServiceApp.isPresent(), "B2B self organization onboard feature is not enabled properly"); + selfServiceAppId = b2bSelfServiceApp.get().getId(); + } + + @Test(dependsOnMethods = "enableSelfOrganizationOnboardService") + public void createUser() throws Exception { + + OpenIDConnectConfiguration openIDConnectConfiguration = oAuth2RestClient.getOIDCInboundDetails(selfServiceAppId); + String consumerKey = openIDConnectConfiguration.getClientId(); + ClientID clientID = new ClientID(consumerKey); + String consumerSecret = openIDConnectConfiguration.getClientSecret(); + Secret clientSecret = new Secret(consumerSecret); + Assert.assertNotNull(clientID); + Assert.assertNotNull(clientSecret); + } + + private void associateRoles(String applicationId) throws Exception { + + AssociatedRolesConfig associatedRolesConfig = new AssociatedRolesConfig().allowedAudience( + AssociatedRolesConfig.AllowedAudienceEnum.ORGANIZATION); + String audienceType = AssociatedRolesConfig.AllowedAudienceEnum.ORGANIZATION.toString().toLowerCase(); + List roles = oAuth2RestClient.getRoles("admin", audienceType, null); + String adminRoleId = null; + if (roles.size() == 1) { + adminRoleId = roles.get(0); + } + ApplicationPatchModel applicationPatch = new ApplicationPatchModel(); + applicationPatch.associatedRoles(associatedRolesConfig); + associatedRolesConfig.addRolesItem( + new org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.Role().id( + adminRoleId)); + oAuth2RestClient.updateApplication(applicationId, applicationPatch); + } + + private String addApplication() throws Exception { + + ApplicationModel application = new ApplicationModel(); + List grantTypes = new ArrayList<>(); + Collections.addAll(grantTypes, "password", "organization_switch"); + OpenIDConnectConfiguration oidcConfig = new OpenIDConnectConfiguration(); + oidcConfig.setGrantTypes(grantTypes); + InboundProtocols inboundProtocolsConfig = new InboundProtocols(); + inboundProtocolsConfig.setOidc(oidcConfig); + application.setInboundProtocolConfiguration(inboundProtocolsConfig); + application.setName("org-mgt-token-app"); + return oAuth2RestClient.createApplication(application); + } } diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/enable-self-organization-onboard-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/enable-self-organization-onboard-request-body.json new file mode 100644 index 00000000000..ff2365fba1a --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/enable-self-organization-onboard-request-body.json @@ -0,0 +1,9 @@ +{ + "operation": "UPDATE", + "properties": [ + { + "name": "Organization.SelfService.Enable", + "value": "true" + } + ] +} \ No newline at end of file From a571de9e0c0fbe88a2dad59b943acdc811dce462 Mon Sep 17 00:00:00 2001 From: sadilchamishka Date: Sun, 3 Dec 2023 01:28:26 +0530 Subject: [PATCH 3/6] Application sharing and organization switch grant integration tests --- .../v1/OrganizationManagementBaseTest.java | 141 +----- .../v1/OrganizationManagementFailureTest.java | 86 ---- .../v1/OrganizationManagementSuccessTest.java | 428 +++++++++--------- .../v1/OrganizationManagementTestData.java | 157 ------- .../organization/management/v1/Utils.java | 38 -- .../v1/model/OrganizationLevel.java | 24 - .../v2/OrganizationManagementBaseTest.java | 74 --- .../v2/OrganizationManagementFailureTest.java | 152 ------- .../v2/OrganizationManagementSuccessTest.java | 220 --------- .../v2/model/OrganizationUpdateRequest.java | 143 ------ .../test/restclients/RestBaseClient.java | 1 + ...min-user-in-organization-request-body.json | 14 + .../v1/add-organization-request-body.json | 14 + .../v1/disable-organization-request-body.json | 7 + ...elf-organization-onboard-request-body.json | 0 .../v2/add-organization-request-body.json | 3 - .../src/test/resources/testng.xml | 2 +- 17 files changed, 275 insertions(+), 1229 deletions(-) delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementFailureTest.java delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementTestData.java delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/Utils.java delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/model/OrganizationLevel.java delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementFailureTest.java delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/model/OrganizationUpdateRequest.java create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-admin-user-in-organization-request-body.json create mode 100644 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 create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/disable-organization-request-body.json rename modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/{v2 => v1}/enable-self-organization-onboard-request-body.json (100%) delete mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/add-organization-request-body.json 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 d8e98b4c2d5..5b7286551b3 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,87 +15,43 @@ * 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; -import io.restassured.response.Response; import org.apache.commons.lang.StringUtils; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpStatus; import org.testng.Assert; -import org.testng.ISuite; -import org.testng.ITestContext; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; -import org.testng.annotations.DataProvider; -import org.wso2.carbon.automation.engine.context.TestUserMode; -import org.wso2.identity.integration.test.rest.api.server.common.B2BRESTAPIServerTestBase; -import org.wso2.identity.integration.test.rest.api.server.organization.management.v1.model.OrganizationLevel; -import org.wso2.identity.integration.test.utils.CarbonUtils; +import org.wso2.identity.integration.test.rest.api.server.common.RESTAPIServerTestBase; +import org.wso2.identity.integration.test.restclients.OAuth2RestClient; import java.io.IOException; -import java.util.Set; - -import static org.hamcrest.core.IsNull.notNullValue; -import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.Utils.assertNotBlank; -import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.Utils.extractOrganizationIdFromLocationHeader; /** - * Base test class for Organization Management REST APIs. + * Base test class for the OIDC Scope Management REST APIs. */ -public class OrganizationManagementBaseTest extends B2BRESTAPIServerTestBase { +public class OrganizationManagementBaseTest extends RESTAPIServerTestBase { + public static final String SUPER_ORGANIZATION_ID = "10084a8d-113f-4211-a0d5-efe36b082211"; + public static final String SUPER_TENANT_DOMAIN = "carbon.super"; private static final String API_DEFINITION_NAME = "org.wso2.carbon.identity.organization.management.yaml"; static final String API_VERSION = "v1"; - public final OrganizationLevel organizationLevel; - static final String SUPER_ORGANIZATION_NAME = "Super"; - static final String ORGANIZATION_NAME = "name"; - static final String ORGANIZATION_PARENT_ID = "parentId"; - static final String SUPER_ORGANIZATION_ID = "10084a8d-113f-4211-a0d5-efe36b082211"; - protected String subOrganizationId; - protected static final String ORGANIZATION_MANAGEMENT_API_BASE_PATH = "/organizations"; + + static final String ORGANIZATION_MANAGEMENT_API_BASE_PATH = "/organizations"; + static final String PATH_SEPARATOR = "/"; + protected static String swaggerDefinition; - static boolean isLegacyRuntimeEnabled; + protected OAuth2RestClient oAuth2RestClient; static { - String apiPackageName = "org.wso2.carbon.identity.api.server.organization.management.v1"; + String API_PACKAGE_NAME = "org.wso2.carbon.identity.api.server.organization.management.v1"; + try { - swaggerDefinition = getAPISwaggerDefinition(apiPackageName, API_DEFINITION_NAME); + swaggerDefinition = getAPISwaggerDefinition(API_PACKAGE_NAME, API_DEFINITION_NAME); } catch (IOException e) { Assert.fail(String.format("Unable to read the swagger definition %s from %s", API_DEFINITION_NAME, - apiPackageName), e); - } - } - - public OrganizationManagementBaseTest(TestUserMode userMode, OrganizationLevel organizationLevel) throws Exception { - - this.organizationLevel = organizationLevel; - super.init(userMode); - this.context = isServer; - this.authenticatingUserName = context.getContextTenant().getTenantAdmin().getUserName(); - this.authenticatingCredential = context.getContextTenant().getTenantAdmin().getPassword(); - } - - @BeforeClass(alwaysRun = true) - public void init(ITestContext context) throws Exception { - - ISuite suite = context.getSuite(); - isLegacyRuntimeEnabled = CarbonUtils.isLegacyAuthzRuntimeEnabled(); - String orgId = (String) suite.getAttribute("createdOrgId"); - if (orgId == null) { - orgId = SUPER_ORGANIZATION_ID; - } - this.subOrganizationId = orgId; - if (OrganizationLevel.SUPER_ORGANIZATION.equals(this.organizationLevel)) { - super.testInitWithoutTenantQualifiedPath(API_VERSION, swaggerDefinition); - } else { - this.tenant = subOrganizationId; - String tenantDomain = tenantInfo.getDomain(); - this.authenticatingUserName = "admin@" + tenantDomain; - super.testInit(API_VERSION, swaggerDefinition, tenantDomain); + API_PACKAGE_NAME), e); } } @@ -106,78 +62,15 @@ public void testConclude() throws Exception { } @BeforeMethod(alwaysRun = true) - public void testInit(ITestContext context) throws Exception { + public void testInit() { RestAssured.basePath = basePath; - ISuite suite = context.getSuite(); - String orgId = (String) suite.getAttribute("createdOrgId"); - - if (orgId == null) { - orgId = createBaseOrg(); - suite.setAttribute("createdOrgId", orgId); - } } @AfterMethod(alwaysRun = true) - public void testFinish() throws Exception{ + public void testFinish() { RestAssured.basePath = StringUtils.EMPTY; } - @DataProvider(name = "restAPIUserConfigProvider") - public static Object[][] restAPIUserConfigProvider() { - - return new Object[][]{ - {TestUserMode.SUPER_TENANT_ADMIN, OrganizationLevel.SUPER_ORGANIZATION}, - {TestUserMode.SUPER_TENANT_ADMIN, OrganizationLevel.SUB_ORGANIZATION} - }; - } - - @DataProvider(name = "initRESTAPIUserConfigProvider") - public static Object[][] initRESTAPIUserConfigProvider() { - - return new Object[][]{ - {TestUserMode.SUPER_TENANT_ADMIN, OrganizationLevel.SUPER_ORGANIZATION}, - }; - } - - protected void cleanUpOrganizations(Set orgsToCleanUp) { - - orgsToCleanUp.forEach(orgId -> { - String organizationPath = ORGANIZATION_MANAGEMENT_API_BASE_PATH + "/" + orgId; - Response responseOfDelete = getResponseOfDelete(organizationPath); - responseOfDelete.then() - .log() - .ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_NO_CONTENT); - }); - } - - private String createBaseOrg() { - - String body = "{\n" + - " \"name\": \"ABC Builders\",\n" + - " \"description\": \"Building constructions\",\n" + - " \"type\": \"TENANT\",\n" + - " \"parentId\": \"10084a8d-113f-4211-a0d5-efe36b082211\",\n" + - " \"attributes\": [\n" + - " {\n" + - " \"key\": \"Country\",\n" + - " \"value\": \"Sri Lanka\"\n" + - " }\n" + - " ]\n" + - "}"; - Response responseOfPost = getResponseOfPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, body); - responseOfPost.then() - .log().ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_CREATED) - .header(HttpHeaders.LOCATION, notNullValue()); - - String location = responseOfPost.getHeader(HttpHeaders.LOCATION); - String createdOrgId = extractOrganizationIdFromLocationHeader(location); - assertNotBlank(createdOrgId); - return createdOrgId; - } } 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 deleted file mode 100644 index 34f4aba949e..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementFailureTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2023, 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.organization.management.v1; - -import io.restassured.response.Response; -import org.apache.commons.lang.StringUtils; -import org.apache.http.HttpStatus; -import org.json.JSONObject; -import org.testng.annotations.AfterMethod; -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.organization.management.v1.model.OrganizationLevel; - -/** - * Tests for negative paths of the Organization Management REST API. - */ -public class OrganizationManagementFailureTest extends OrganizationManagementBaseTest { - - @Factory(dataProvider = "restAPIUserConfigProvider") - public OrganizationManagementFailureTest(TestUserMode userMode, OrganizationLevel organizationLevel) - throws Exception { - - super(userMode, organizationLevel); - } - - @AfterMethod(alwaysRun = true) - @Override - public void testFinish() throws Exception { - - super.testFinish(); - } - - @Test - public void testCreateOrganizationWithoutRequiredField() throws Exception { - - JSONObject organizationObject = new JSONObject(); - String parentId; - - if (OrganizationLevel.SUPER_ORGANIZATION.equals(this.organizationLevel)) { - parentId = SUPER_ORGANIZATION_NAME; - } else { - parentId = subOrganizationId; - } - organizationObject.put("parentId", parentId); - String payload = organizationObject.toString(); - - Response response = getResponseOfPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, payload); - validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "UE-10000"); - } - - @Test - public void testCreateOrganizationWithABlankName() throws Exception { - - JSONObject organizationObject = new JSONObject(); - String parentId; - - if (OrganizationLevel.SUPER_ORGANIZATION.equals(this.organizationLevel)) { - parentId = SUPER_ORGANIZATION_NAME; - } else { - parentId = subOrganizationId; - } - organizationObject.put(ORGANIZATION_NAME, StringUtils.EMPTY); - organizationObject.put(ORGANIZATION_PARENT_ID, parentId); - String payload = organizationObject.toString(); - - Response response = getResponseOfPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, payload); - validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "ORG-60002", ORGANIZATION_NAME); - } -} 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 f7aa23b8cb9..143f4db7ab8 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,22 +15,25 @@ * 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.ResourceOwnerPasswordCredentialsGrant; +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.RestAssured; import io.restassured.http.ContentType; import io.restassured.response.Response; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; +import org.apache.http.Header; import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -38,262 +41,209 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.json.JSONException; -import org.json.JSONObject; import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; import org.testng.Assert; import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +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.api.resource.v1.model.APIResourceListItem; -import org.wso2.identity.integration.test.rest.api.server.api.resource.v1.model.ScopeGetModel; +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.ApplicationModel; import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.ApplicationPatchModel; import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.AssociatedRolesConfig; -import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.AuthorizedAPICreationModel; import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.InboundProtocols; import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.OpenIDConnectConfiguration; -import org.wso2.identity.integration.test.rest.api.server.organization.management.v1.model.OrganizationLevel; import org.wso2.identity.integration.test.restclients.OAuth2RestClient; import org.wso2.identity.integration.test.utils.OAuth2Constant; +import java.io.IOException; import java.net.URI; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Set; +import java.util.Optional; import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.core.IsNull.notNullValue; -import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.OrganizationManagementTestData.APPLICATION_PAYLOAD; -import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.Utils.assertNotBlank; -import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.Utils.extractOrganizationIdFromLocationHeader; +import static org.testng.Assert.assertNotNull; +import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.OrganizationManagementBaseTest.SUPER_ORGANIZATION_ID; +import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.OrganizationManagementBaseTest.SUPER_TENANT_DOMAIN; +import static org.wso2.identity.integration.test.restclients.RestBaseClient.CONTENT_TYPE_ATTRIBUTE; +import static org.wso2.identity.integration.test.restclients.RestBaseClient.ORGANIZATION_PATH; +import static org.wso2.identity.integration.test.restclients.RestBaseClient.TENANT_PATH; +import static org.wso2.identity.integration.test.restclients.RestBaseClient.USER_AGENT_ATTRIBUTE; +import static org.wso2.identity.integration.test.scim2.SCIM2BaseTestCase.SCIM2_USERS_ENDPOINT; /** - * Tests for happy paths of the Organization Management REST API. + * Tests for successful cases of the Organization Management REST APIs. */ public class OrganizationManagementSuccessTest extends OrganizationManagementBaseTest { - private Set createdOrgs = new HashSet<>(); - private String createdOrganizationId; - private String createdOrganizationName; - private String consumerKey; - private String consumerSecret; - private String orgSwitchedToken; - private String applicationId; - private static final String SYSTEM_SCOPE = "SYSTEM"; + private String organizationID; + private String selfServiceAppId; + private String selfServiceAppClientId; + private String selfServiceAppClientSecret; + private String m2mToken; + private String switchedM2MToken; + private String b2bApplicationID; + private HttpClient client; @Factory(dataProvider = "restAPIUserConfigProvider") - public OrganizationManagementSuccessTest(TestUserMode userMode, OrganizationLevel organizationLevel) - throws Exception { + public OrganizationManagementSuccessTest(TestUserMode userMode) throws Exception { - super(userMode, organizationLevel); + super.init(userMode); + this.context = isServer; + this.authenticatingUserName = context.getContextTenant().getTenantAdmin().getUserName(); + this.authenticatingCredential = context.getContextTenant().getTenantAdmin().getPassword(); + this.tenant = context.getContextTenant().getDomain(); } @BeforeClass(alwaysRun = true) - private void testInit() throws Exception { + public void init() throws Exception { + super.testInit(API_VERSION, swaggerDefinition, tenant); oAuth2RestClient = new OAuth2RestClient(serverURL, tenantInfo); - if (organizationLevel == OrganizationLevel.SUB_ORGANIZATION) { - applicationId = addApplication(); - } + client = HttpClientBuilder.create().build(); } @AfterClass(alwaysRun = true) - @Override - public void testFinish() throws Exception { + public void testConclude() throws Exception { - cleanUpOrganizations(createdOrgs); - if (organizationLevel == OrganizationLevel.SUB_ORGANIZATION) { - deleteApplication(applicationId); - } + super.conclude(); + deleteApplication(selfServiceAppId); + deleteApplication(b2bApplicationID); oAuth2RestClient.closeHttpClient(); - super.testFinish(); } - @Test - public void createOrganization() throws Exception { - - JSONObject organizationObject = new JSONObject(); - String org; - String parentId; - - Response responseOfPost; - if (OrganizationLevel.SUPER_ORGANIZATION.equals(this.organizationLevel)) { - org = "Level1Org"; - parentId = SUPER_ORGANIZATION_ID; - organizationObject.put(ORGANIZATION_NAME, org); - organizationObject.put(ORGANIZATION_PARENT_ID, parentId); - responseOfPost = getResponseOfPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, - organizationObject.toString()); - } else { - org = "Level2Org"; - parentId = subOrganizationId; - shareApplication(applicationId); - - if (!isLegacyRuntimeEnabled) { - authorizeSystemOrgApi(applicationId, Arrays.asList("/o/api/server/v1/organizations", - "/o/api/server/v1/identity-governance", "/o/api/server/v1/applications")); - associateRoles(applicationId); - } - String passwordGrantToken = getPasswordGrantToken(applicationId); - HttpClient client = HttpClientBuilder.create().build(); - orgSwitchedToken = getSwitchToken(parentId, passwordGrantToken, client); - - organizationObject.put(ORGANIZATION_NAME, org); - organizationObject.put(ORGANIZATION_PARENT_ID, parentId); - responseOfPost = given().auth().preemptive().oauth2(orgSwitchedToken) - .contentType(ContentType.JSON) - .header(HttpHeaders.ACCEPT, ContentType.JSON) - .body(organizationObject.toString()) - .log().ifValidationFails() - .log().ifValidationFails() - .when() - .log().ifValidationFails() - .post(ORGANIZATION_MANAGEMENT_API_BASE_PATH); - } - - responseOfPost.then() - .log().ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_CREATED) - .header(HttpHeaders.LOCATION, notNullValue()); + @BeforeMethod(alwaysRun = true) + public void testInit() { - String location = responseOfPost.getHeader(HttpHeaders.LOCATION); - String createdOrgId = extractOrganizationIdFromLocationHeader(location); - createdOrgs.add(createdOrgId); - createdOrganizationId = createdOrgId; - createdOrganizationName = org; - - assertNotBlank(createdOrgId); - if (organizationLevel == OrganizationLevel.SUB_ORGANIZATION) { - // Check whether password recovery is enabled in the created sub-organization. - /*given() - .auth().preemptive().oauth2(orgSwitchedToken) - .contentType(ContentType.JSON) - .header(HttpHeaders.ACCEPT, ContentType.JSON) - .log().ifValidationFails() - .when() - .get("/identity-governance/QWNjb3VudCBNYW5hZ2VtZW50/connectors/YWNjb3VudC1yZWNvdmVyeQ") - .then() - .log().ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_OK) - .body("properties.find { it.name == 'Recovery.Notification.Password.Enable' }.value", - equalTo("true")) - .body("properties.find { it.name == 'Recovery.NotifySuccess' }.value", equalTo("true"));*/ - - // Check whether application creation is disabled in the sub-organization. - Response response = given() - .auth().preemptive().oauth2(orgSwitchedToken) - .contentType(ContentType.JSON) - .header(HttpHeaders.ACCEPT, ContentType.JSON) - .body(APPLICATION_PAYLOAD) - .log().ifValidationFails() - .when() - .post("/applications"); - - response.then() - .log().ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_FORBIDDEN); - } + RestAssured.basePath = basePath; } - @Test(dependsOnMethods = {"createOrganization"}) - public void testGetOrganizationById() throws Exception { + @AfterMethod(alwaysRun = true) + public void testFinish() { - getResponseOfGet(ORGANIZATION_MANAGEMENT_API_BASE_PATH + "/" + createdOrganizationId) - .then() - .log().ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_OK) - .body(ORGANIZATION_NAME, equalTo(createdOrganizationName)); + RestAssured.basePath = StringUtils.EMPTY; } - private void authorizeSystemOrgApi(String applicationId, List apiIdentifiers) { - - apiIdentifiers.forEach(apiIdentifier -> { - try { - List filteredAPIResource = - oAuth2RestClient.getAPIResourcesWithFiltering("type+eq+SYSTEM_ORG+and+identifier+eq+" - + apiIdentifier); - if (filteredAPIResource == null || filteredAPIResource.isEmpty()) { - return; - } - String apiId = filteredAPIResource.get(0).getId(); - List apiResourceScopes = oAuth2RestClient.getAPIResourceScopes(apiId); - AuthorizedAPICreationModel authorizedAPICreationModel = new AuthorizedAPICreationModel(); - authorizedAPICreationModel.setId(apiId); - authorizedAPICreationModel.setPolicyIdentifier("RBAC"); - apiResourceScopes.forEach(scope -> { - authorizedAPICreationModel.addScopesItem(scope.getName()); - }); - oAuth2RestClient.addAPIAuthorizationToApplication(applicationId, authorizedAPICreationModel); - } catch (Exception e) { - throw new RuntimeException("Error while authorizing system API " + apiIdentifier + " to application " - + applicationId, e); - } - }); + @DataProvider(name = "restAPIUserConfigProvider") + public static Object[][] restAPIUserConfigProvider() { + + return new Object[][]{ + {TestUserMode.SUPER_TENANT_ADMIN}, + {TestUserMode.TENANT_ADMIN} + }; } - private String addApplication() throws Exception { + @Test + public void enableSelfOrganizationOnboardService() throws IOException { - ApplicationModel application = new ApplicationModel(); - List grantTypes = new ArrayList<>(); - Collections.addAll(grantTypes, "password", "organization_switch"); - OpenIDConnectConfiguration oidcConfig = new OpenIDConnectConfiguration(); - oidcConfig.setGrantTypes(grantTypes); - InboundProtocols inboundProtocolsConfig = new InboundProtocols(); - inboundProtocolsConfig.setOidc(oidcConfig); - application.setInboundProtocolConfiguration(inboundProtocolsConfig); - application.setName("org-mgt-token-app"); - return oAuth2RestClient.createApplication(application); + String endpointURL = "self-service/preferences"; + String body = readResource("enable-self-organization-onboard-request-body.json"); + + Response response = given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) + .contentType(ContentType.JSON) + .body(body) + .when() + .patch(endpointURL); + response.then() + .log().ifValidationFails() + .assertThat() + .statusCode(HttpStatus.SC_OK); + + Optional b2bSelfServiceApp = oAuth2RestClient.getAllApplications().getApplications().stream() + .filter(application -> application.getName().equals("B2B-Self-Service-Mgt-Application")) + .findAny(); + Assert.assertTrue(b2bSelfServiceApp.isPresent(), "B2B self organization onboard feature is not enabled properly"); + selfServiceAppId = b2bSelfServiceApp.get().getId(); } - private String getPasswordGrantToken(String appId) throws Exception { + @Test(dependsOnMethods = "enableSelfOrganizationOnboardService") + public void getM2MAccessToken() throws Exception { - OpenIDConnectConfiguration openIDConnectConfiguration = oAuth2RestClient.getOIDCInboundDetails(appId); - Secret password = new Secret(tenantInfo.getContextUser().getPassword()); - AuthorizationGrant passwordGrant = new ResourceOwnerPasswordCredentialsGrant( - tenantInfo.getContextUser().getUserName(), password); - consumerKey = openIDConnectConfiguration.getClientId(); - ClientID clientID = new ClientID(consumerKey); - consumerSecret = openIDConnectConfiguration.getClientSecret(); - Secret clientSecret = new Secret(consumerSecret); + 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); - URI tokenEndpoint = new URI(getTenantQualifiedURL( - OAuth2Constant.ACCESS_TOKEN_ENDPOINT, tenantInfo.getDomain())); - Scope systemScope = new Scope(SYSTEM_SCOPE); - TokenRequest request = new TokenRequest(tokenEndpoint, clientAuth, passwordGrant, systemScope); + Scope scope = new Scope("SYSTEM"); + 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."); - AccessTokenResponse tokenResponse = AccessTokenResponse.parse(tokenHTTPResp); - Assert.assertNotNull(tokenResponse, "Access token response is null."); - return tokenResponse.getTokens().getAccessToken().getValue(); + + 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"); + } + + @Test(dependsOnMethods = "getM2MAccessToken") + public void testSelfOnboardOrganization() throws IOException { + + 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); + + 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); } - private String getSwitchToken(String organizationId, String token, HttpClient client) throws Exception { + @Test(dependsOnMethods = "testSelfOnboardOrganization") + public void testGetOrganization() { + + Response response = getResponseOfGet(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID); + validateHttpStatusCode(response, HttpStatus.SC_OK); + Assert.assertNotNull(response.asString()); + response.then() + .log().ifValidationFails() + .assertThat() + .statusCode(HttpStatus.SC_OK) + .body("id", equalTo(organizationID)); + } + + @Test(dependsOnMethods = "testSelfOnboardOrganization") + public void switchM2MToken() throws IOException, ParseException { List urlParameters = new ArrayList<>(); - urlParameters.add(new BasicNameValuePair(OAuth2Constant.GRANT_TYPE_NAME, - "organization_switch")); - urlParameters.add(new BasicNameValuePair("token", token)); + urlParameters.add(new BasicNameValuePair(OAuth2Constant.GRANT_TYPE_NAME, "organization_switch_cc")); + urlParameters.add(new BasicNameValuePair("token", m2mToken)); urlParameters.add(new BasicNameValuePair("scope", "SYSTEM")); - urlParameters.add(new BasicNameValuePair("switching_organization", organizationId)); + urlParameters.add(new BasicNameValuePair("switching_organization", organizationID)); - HttpPost httpPost = new HttpPost(OAuth2Constant.ACCESS_TOKEN_ENDPOINT); + HttpPost httpPost = new HttpPost(getTenantQualifiedURL(OAuth2Constant.ACCESS_TOKEN_ENDPOINT, tenant)); httpPost.setHeader("Authorization", "Basic " + - new String(Base64.encodeBase64((consumerKey + ":" + consumerSecret).getBytes()))); + new String(Base64.encodeBase64((selfServiceAppClientId + ":" + selfServiceAppClientSecret).getBytes()))); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); @@ -302,43 +252,107 @@ private String getSwitchToken(String organizationId, String token, HttpClient cl EntityUtils.consume(response.getEntity()); JSONParser parser = new JSONParser(); org.json.simple.JSONObject json = (org.json.simple.JSONObject) parser.parse(responseString); - if (json == null) { - throw new Exception("Error occurred while getting the response."); - } Assert.assertNotNull(json.get(OAuth2Constant.ACCESS_TOKEN), "Access token is null."); - return (String) json.get(OAuth2Constant.ACCESS_TOKEN); + switchedM2MToken = (String) json.get(OAuth2Constant.ACCESS_TOKEN); + Assert.assertNotNull(switchedM2MToken); } - private void shareApplication(String applicationId) throws JSONException { + @Test(dependsOnMethods = "switchM2MToken") + public void createOnBoardUserInOrganization() 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); + Header[] headerList = new Header[3]; + headerList[0] = new BasicHeader(USER_AGENT_ATTRIBUTE, OAuth2Constant.USER_AGENT); + headerList[1] = new BasicHeader("Authorization", "Bearer " + switchedM2MToken); + headerList[2] = new BasicHeader(CONTENT_TYPE_ATTRIBUTE, "application/scim+json"); + request.setHeaders(headerList); + request.setEntity(new StringEntity(body)); + HttpResponse response = client.execute(request); + Assert.assertEquals(response.getStatusLine().getStatusCode(), 201); + } - String shareApplicationUrl = "/api/server/v1" + ORGANIZATION_MANAGEMENT_API_BASE_PATH + - "/" + SUPER_ORGANIZATION_ID + "/applications/" + applicationId + "/share"; - JSONObject shareAppObject = new JSONObject(); - shareAppObject.put("shareWithAllChildren", true); - getResponseOfPost(shareApplicationUrl, shareAppObject.toString()); + @Test(dependsOnMethods = "createOnBoardUserInOrganization") + public void addB2BApplication() throws Exception { + + ApplicationModel application = new ApplicationModel(); + List grantTypes = new ArrayList<>(); + Collections.addAll(grantTypes, "authorization_code"); + OpenIDConnectConfiguration oidcConfig = new OpenIDConnectConfiguration(); + oidcConfig.setGrantTypes(grantTypes); + oidcConfig.setCallbackURLs(Collections.singletonList(OAuth2Constant.CALLBACK_URL)); + InboundProtocols inboundProtocolsConfig = new InboundProtocols(); + inboundProtocolsConfig.setOidc(oidcConfig); + application.setInboundProtocolConfiguration(inboundProtocolsConfig); + application.setName("Guardio-Business-App"); + b2bApplicationID = oAuth2RestClient.createApplication(application); + Assert.assertNotNull(b2bApplicationID); } - private void associateRoles(String applicationId) throws Exception { + @Test(dependsOnMethods = "addB2BApplication") + public void associateOrganizationRoleToB2BApp() throws Exception { AssociatedRolesConfig associatedRolesConfig = new AssociatedRolesConfig().allowedAudience( AssociatedRolesConfig.AllowedAudienceEnum.ORGANIZATION); - String adminRoleId = getRoleV2ResourceId( - AssociatedRolesConfig.AllowedAudienceEnum.ORGANIZATION.toString().toLowerCase()); + String audienceType = AssociatedRolesConfig.AllowedAudienceEnum.ORGANIZATION.toString().toLowerCase(); + List roles = oAuth2RestClient.getRoles("admin", audienceType, null); + String adminRoleId = null; + if (roles.size() == 1) { + adminRoleId = roles.get(0); + } ApplicationPatchModel applicationPatch = new ApplicationPatchModel(); applicationPatch.associatedRoles(associatedRolesConfig); associatedRolesConfig.addRolesItem( new org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.Role().id( adminRoleId)); - oAuth2RestClient.updateApplication(applicationId, applicationPatch); + oAuth2RestClient.updateApplication(b2bApplicationID, applicationPatch); } - private String getRoleV2ResourceId(String audienceType) throws Exception { + @Test(dependsOnMethods = "addB2BApplication") + public void shareB2BApplication() throws JSONException { - List roles = oAuth2RestClient.getRoles("admin", audienceType, null); - if (roles.size() == 1) { - return roles.get(0); + if (!SUPER_TENANT_DOMAIN.equals(tenant)) { + return; + } + String shareApplicationUrl = ORGANIZATION_MANAGEMENT_API_BASE_PATH + + "/" + SUPER_ORGANIZATION_ID + "/applications/" + b2bApplicationID + "/share"; + org.json.JSONObject shareAppObject = new org.json.JSONObject(); + shareAppObject.put("shareWithAllChildren", true); + getResponseOfPost(shareApplicationUrl, shareAppObject.toString()); + } + + @Test(dependsOnMethods = "shareB2BApplication") + public void unShareB2BApplication() throws JSONException { + + if (!SUPER_TENANT_DOMAIN.equals(tenant)) { + return; } - return null; + String shareApplicationUrl = ORGANIZATION_MANAGEMENT_API_BASE_PATH + + "/" + SUPER_ORGANIZATION_ID + "/applications/" + b2bApplicationID + "/share"; + org.json.JSONObject shareAppObject = new org.json.JSONObject(); + shareAppObject.put("shareWithAllChildren", false); + getResponseOfPost(shareApplicationUrl, shareAppObject.toString()); + } + + @Test(dependsOnMethods = "unShareB2BApplication") + public void testDisablingOrganization() throws IOException { + + String endpoint = ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationID; + String body = readResource("disable-organization-request-body.json"); + Response response = getResponseOfPatch(endpoint, body); + validateHttpStatusCode(response, HttpStatus.SC_OK); + } + + @Test(dependsOnMethods = "testDisablingOrganization") + public void testDeleteOrganization() { + + String organizationPath = ORGANIZATION_MANAGEMENT_API_BASE_PATH + "/" + organizationID; + Response responseOfDelete = getResponseOfDelete(organizationPath); + responseOfDelete.then() + .log() + .ifValidationFails() + .assertThat() + .statusCode(HttpStatus.SC_NO_CONTENT); } private void deleteApplication(String applicationId) throws Exception { diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementTestData.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementTestData.java deleted file mode 100644 index 1ae0212a2be..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementTestData.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2023, 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.organization.management.v1; - -/** - * Contains test data for organization management REST API tests. - */ -public class OrganizationManagementTestData { - - public static final String APPLICATION_PAYLOAD = "{" + - "\"name\": \"pickup-dispatch\"," + - "\"description\": \"This is the configuration for Pickup-dispatch application.\"," + - "\"imageUrl\": \"https://example.com/logo/my-logo.png\"," + - "\"accessUrl\": \"https://example.com/login\"," + - "\"templateId\": \"b9c5e11e-fc78-484b-9bec-015d247561b8\"," + - "\"isManagementApp\": false," + - "\"claimConfiguration\": {" + - " \"dialect\": \"LOCAL\"," + - " \"claimMappings\": [" + - " {" + - " \"applicationClaim\": \"firstname\"," + - " \"localClaim\": {" + - " \"uri\": \"http://wso2.org/claims/username\"" + - " }" + - " }" + - " ]," + - " \"requestedClaims\": [" + - " {" + - " \"claim\": {" + - " \"uri\": \"http://wso2.org/claims/username\"" + - " }," + - " \"mandatory\": false" + - " }" + - " ]," + - " \"subject\": {" + - " \"claim\": {" + - " \"uri\": \"http://wso2.org/claims/username\"" + - " }," + - " \"includeUserDomain\": false," + - " \"includeTenantDomain\": false," + - " \"useMappedLocalSubject\": false" + - " }," + - " \"role\": {" + - " \"mappings\": [" + - " {" + - " \"localRole\": \"admin\"," + - " \"applicationRole\": \"Administrator\"" + - " }" + - " ]," + - " \"includeUserDomain\": true," + - " \"claim\": {" + - " \"uri\": \"http://wso2.org/claims/username\"" + - " }" + - " }" + - "}," + - "\"inboundProtocolConfiguration\": {" + - " \"oidc\": {" + - " \"clientId\": \"rMfbPgCi5oWljNhv8c4Pugfuo8Aa\"," + - " \"clientSecret\": \"MkHGGiTdAPfTyUKfXLdyOwelMywt\"," + - " \"grantTypes\": [" + - " \"authorization_code\"," + - " \"password\"" + - " ]," + - " \"callbackURLs\": [" + - " \"regexp=(https://app.example.com/callback1|https://app.example.com/callback2)\"" + - " ]," + - " \"allowedOrigins\": [" + - " \"https://app.example.com\"" + - " ]," + - " \"publicClient\": false," + - " \"pkce\": {" + - " \"mandatory\": false," + - " \"supportPlainTransformAlgorithm\": true" + - " }," + - " \"accessToken\": {" + - " \"type\": \"JWT\"," + - " \"userAccessTokenExpiryInSeconds\": 3600," + - " \"applicationAccessTokenExpiryInSeconds\": 3600," + - " \"bindingType\": \"cookie\"," + - " \"revokeTokensWhenIDPSessionTerminated\": true," + - " \"validateTokenBinding\": true" + - " }," + - " \"refreshToken\": {" + - " \"expiryInSeconds\": 86400," + - " \"renewRefreshToken\": true" + - " }," + - " \"idToken\": {" + - " \"expiryInSeconds\": 3600," + - " \"audience\": [" + - " \"http://idp.xyz.com\"," + - " \"http://idp.abc.com\"" + - " ]," + - " \"encryption\": {" + - " \"enabled\": false," + - " \"algorithm\": \"RSA-OAEP\"," + - " \"method\": \"A128CBC+HS256\"" + - " }" + - " }," + - " \"logout\": {" + - " \"backChannelLogoutUrl\": \"https://app.example.com/backchannel/callback\"," + - " \"frontChannelLogoutUrl\": \"https://app.example.com/frontchannel/callback\"" + - " }," + - " \"validateRequestObjectSignature\": false," + - " \"scopeValidators\": [" + - " \"Role based scope validator\"" + - " ]" + - " }" + - "}," + - "\"authenticationSequence\": {" + - " \"type\": \"DEFAULT\"," + - " \"steps\": [" + - " {" + - " \"id\": 1," + - " \"options\": [" + - " {" + - " \"idp\": \"LOCAL\"," + - " \"authenticator\": \"basic\"" + - " }" + - " ]" + - " }" + - " ]," + - " \"script\": \"string\"," + - " \"subjectStepId\": 1," + - " \"attributeStepId\": 1" + - "}," + - "\"advancedConfigurations\": {" + - " \"saas\": false," + - " \"discoverableByEndUsers\": false," + - " \"certificate\": {" + - " \"type\": \"string\"," + - " \"value\": \"string\"" + - " }," + - " \"skipLoginConsent\": false," + - " \"skipLogoutConsent\": false," + - " \"useExternalConsentPage\": false," + - " \"returnAuthenticatedIdpList\": false," + - " \"enableAuthorization\": true" + - "}" + - "}"; -} - diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/Utils.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/Utils.java deleted file mode 100644 index 21cf0f76900..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/Utils.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2023, 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.organization.management.v1; - -import org.apache.commons.lang.StringUtils; -import org.testng.Assert; - -/** - * Common utility functions used in organization management REST API tests. - */ -public class Utils { - - public static String extractOrganizationIdFromLocationHeader(String locationHeaderValue) { - - return StringUtils.substringAfterLast(locationHeaderValue, "/"); - } - - public static void assertNotBlank(String value) { - - Assert.assertTrue(StringUtils.isNotBlank(value)); - } -} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/model/OrganizationLevel.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/model/OrganizationLevel.java deleted file mode 100644 index 52fa3423c04..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/model/OrganizationLevel.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2023, 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.organization.management.v1.model; - -public enum OrganizationLevel { - SUPER_ORGANIZATION, - SUB_ORGANIZATION -} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java deleted file mode 100644 index 5d8d36a4ac5..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementBaseTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2023, 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.organization.management.v2; - -import io.restassured.RestAssured; -import org.apache.commons.lang.StringUtils; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.wso2.identity.integration.test.rest.api.server.common.RESTAPIServerTestBase; -import org.wso2.identity.integration.test.restclients.OAuth2RestClient; - -import java.io.IOException; - -/** - * Base test class for the OIDC Scope Management REST APIs. - */ -public class OrganizationManagementBaseTest extends RESTAPIServerTestBase { - - private static final String API_DEFINITION_NAME = "org.wso2.carbon.identity.organization.management.yaml"; - static final String API_VERSION = "v1"; - - static final String ORGANIZATION_MANAGEMENT_API_BASE_PATH = "/organizations"; - static final String PATH_SEPARATOR = "/"; - - protected static String swaggerDefinition; - protected OAuth2RestClient oAuth2RestClient; - - static { - String API_PACKAGE_NAME = "org.wso2.carbon.identity.api.server.organization.management.v1"; - - try { - swaggerDefinition = getAPISwaggerDefinition(API_PACKAGE_NAME, API_DEFINITION_NAME); - } catch (IOException e) { - Assert.fail(String.format("Unable to read the swagger definition %s from %s", API_DEFINITION_NAME, - API_PACKAGE_NAME), e); - } - } - - @AfterClass(alwaysRun = true) - public void testConclude() throws Exception { - - super.conclude(); - } - - @BeforeMethod(alwaysRun = true) - public void testInit() { - - RestAssured.basePath = basePath; - } - - @AfterMethod(alwaysRun = true) - public void testFinish() { - - RestAssured.basePath = StringUtils.EMPTY; - } - -} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementFailureTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementFailureTest.java deleted file mode 100644 index 1885ef0b774..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementFailureTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2023, 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.organization.management.v2; - -import io.restassured.RestAssured; -import io.restassured.response.Response; -import org.apache.commons.lang.StringUtils; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpStatus; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Factory; -import org.testng.annotations.Test; -import org.wso2.carbon.automation.engine.context.TestUserMode; - -import java.io.IOException; -import java.util.HashMap; - -import static org.hamcrest.core.IsNull.notNullValue; -import static org.testng.Assert.assertNotNull; - -/** - * Tests for failure cases of the OIDC Scope Management REST APIs. - */ -public class OrganizationManagementFailureTest extends OrganizationManagementBaseTest { - - String scopeId; - - @Factory(dataProvider = "restAPIUserConfigProvider") - public OrganizationManagementFailureTest(TestUserMode userMode) throws Exception { - - super.init(userMode); - this.context = isServer; - this.authenticatingUserName = context.getContextTenant().getTenantAdmin().getUserName(); - this.authenticatingCredential = context.getContextTenant().getTenantAdmin().getPassword(); - this.tenant = context.getContextTenant().getDomain(); - } - - @BeforeClass(alwaysRun = true) - public void init() throws IOException { - - super.testInit(API_VERSION, swaggerDefinition, tenant); - } - - @AfterClass(alwaysRun = true) - public void testConclude() { - - super.conclude(); - } - - @BeforeMethod(alwaysRun = true) - public void testInit() { - - RestAssured.basePath = basePath; - } - - @AfterMethod(alwaysRun = true) - public void testFinish() { - - RestAssured.basePath = StringUtils.EMPTY; - } - - @DataProvider(name = "restAPIUserConfigProvider") - public static Object[][] restAPIUserConfigProvider() { - - return new Object[][]{ - {TestUserMode.SUPER_TENANT_ADMIN}, - {TestUserMode.TENANT_ADMIN} - }; - } - - @Test - public void testAddOIDCScope() throws IOException { - - Response response = getResponseOfJSONPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, - readResource("add-scope-request-body1.json"), new HashMap<>()); - response.then() - .log().ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_CREATED) - .header(HttpHeaders.LOCATION, notNullValue()); - - String location = response.getHeader(HttpHeaders.LOCATION); - assertNotNull(location); - scopeId = location.substring(location.lastIndexOf("/") + 1); - assertNotNull(scopeId); - } - - @Test(dependsOnMethods = "testAddOIDCScope") - public void testAddExistingOIDCScope() throws IOException { - - Response response = getResponseOfJSONPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, - readResource("add-scope-request-body1.json"), new HashMap<>()); - validateHttpStatusCode(response, HttpStatus.SC_CONFLICT); - } - - @Test(dependsOnMethods = "testAddExistingOIDCScope") - public void testAddInvalidOIDCScope() throws IOException { - - Response response = getResponseOfJSONPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, - readResource("add-invalid-scope-request-body1.json"), new HashMap<>()); - validateHttpStatusCode(response, HttpStatus.SC_BAD_REQUEST); - } - - @Test(dependsOnMethods = "testAddInvalidOIDCScope") - public void testDeleteOIDCScope() { - - // Delete an existing scope by id. - Response response = getResponseOfDelete(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + scopeId); - validateHttpStatusCode(response, HttpStatus.SC_NO_CONTENT); - - // Try to delete the same scope again. DELETE should be idempotent. - Response responseOfDeleteFailure = - getResponseOfDelete(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + scopeId); - validateHttpStatusCode(responseOfDeleteFailure, HttpStatus.SC_NO_CONTENT); - } - - @Test(dependsOnMethods = "testDeleteOIDCScope") - public void testGetDeletedOIDCScope() { - - Response responseAfterDelete = getResponseOfGet( - ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + scopeId); - validateHttpStatusCode(responseAfterDelete, HttpStatus.SC_NOT_FOUND); - } - - @Test(dependsOnMethods = "testGetDeletedOIDCScope") - public void testUpdateNotExistingOIDCScope() throws IOException { - - Response response = getResponseOfPut(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + scopeId, - readResource("update-scope-request-body1.json")); - validateHttpStatusCode(response, HttpStatus.SC_NOT_FOUND); - } - -} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java deleted file mode 100644 index d38c07da8cc..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/OrganizationManagementSuccessTest.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2023, 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.organization.management.v2; - -import com.nimbusds.oauth2.sdk.AccessTokenResponse; -import com.nimbusds.oauth2.sdk.AuthorizationGrant; -import com.nimbusds.oauth2.sdk.ResourceOwnerPasswordCredentialsGrant; -import com.nimbusds.oauth2.sdk.Scope; -import com.nimbusds.oauth2.sdk.TokenRequest; -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.RestAssured; -import io.restassured.http.ContentType; -import io.restassured.response.Response; -import org.apache.commons.lang.StringUtils; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpStatus; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -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.ApplicationModel; -import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.ApplicationPatchModel; -import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.AssociatedRolesConfig; -import org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.InboundProtocols; -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 java.io.IOException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Optional; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.core.IsNull.notNullValue; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; - -/** - * Tests for successful cases of the Organization Management REST APIs. - */ -public class OrganizationManagementSuccessTest extends OrganizationManagementBaseTest { - - private String organizationId; - private String selfServiceAppId; - private String applicationId; - - @Factory(dataProvider = "restAPIUserConfigProvider") - public OrganizationManagementSuccessTest(TestUserMode userMode) throws Exception { - - super.init(userMode); - this.context = isServer; - this.authenticatingUserName = context.getContextTenant().getTenantAdmin().getUserName(); - this.authenticatingCredential = context.getContextTenant().getTenantAdmin().getPassword(); - this.tenant = context.getContextTenant().getDomain(); - } - - @BeforeClass(alwaysRun = true) - public void init() throws Exception { - - super.testInit(API_VERSION, swaggerDefinition, tenant); - oAuth2RestClient = new OAuth2RestClient(serverURL, tenantInfo); - //applicationId = addApplication(); - } - - @AfterClass(alwaysRun = true) - public void testConclude() { - - super.conclude(); - } - - @BeforeMethod(alwaysRun = true) - public void testInit() { - - RestAssured.basePath = basePath; - } - - @AfterMethod(alwaysRun = true) - public void testFinish() { - - RestAssured.basePath = StringUtils.EMPTY; - } - - @DataProvider(name = "restAPIUserConfigProvider") - public static Object[][] restAPIUserConfigProvider() { - - return new Object[][]{ - {TestUserMode.SUPER_TENANT_ADMIN}, - {TestUserMode.TENANT_ADMIN} - }; - } - - @Test - public void testAddOrganization() throws IOException { - - String body = readResource("add-organization-request-body.json"); - Response response = getResponseOfJSONPost(ORGANIZATION_MANAGEMENT_API_BASE_PATH, - body, new HashMap<>()); - 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(dependsOnMethods = "testAddOrganization") - public void testGetOrganization() { - - Response response = getResponseOfGet(ORGANIZATION_MANAGEMENT_API_BASE_PATH + PATH_SEPARATOR + organizationId); - validateHttpStatusCode(response, HttpStatus.SC_OK); - Assert.assertNotNull(response.asString()); - response.then() - .log().ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_OK) - .body("id", equalTo(organizationId)); - } - - @Test - public void enableSelfOrganizationOnboardService() throws IOException { - - String endpointURL = "self-service/preferences"; - String body = readResource("enable-self-organization-onboard-request-body.json"); - - Response response = given().auth().preemptive().basic(authenticatingUserName, authenticatingCredential) - .contentType(ContentType.JSON) - .body(body) - .when() - .patch(endpointURL); - response.then() - .log().ifValidationFails() - .assertThat() - .statusCode(HttpStatus.SC_OK); - - Optional b2bSelfServiceApp = oAuth2RestClient.getAllApplications().getApplications().stream() - .filter(application -> application.getName().equals("B2B-Self-Service-Mgt-Application")) - .findAny(); - Assert.assertTrue(b2bSelfServiceApp.isPresent(), "B2B self organization onboard feature is not enabled properly"); - selfServiceAppId = b2bSelfServiceApp.get().getId(); - } - - @Test(dependsOnMethods = "enableSelfOrganizationOnboardService") - public void createUser() throws Exception { - - OpenIDConnectConfiguration openIDConnectConfiguration = oAuth2RestClient.getOIDCInboundDetails(selfServiceAppId); - String consumerKey = openIDConnectConfiguration.getClientId(); - ClientID clientID = new ClientID(consumerKey); - String consumerSecret = openIDConnectConfiguration.getClientSecret(); - Secret clientSecret = new Secret(consumerSecret); - Assert.assertNotNull(clientID); - Assert.assertNotNull(clientSecret); - } - - private void associateRoles(String applicationId) throws Exception { - - AssociatedRolesConfig associatedRolesConfig = new AssociatedRolesConfig().allowedAudience( - AssociatedRolesConfig.AllowedAudienceEnum.ORGANIZATION); - String audienceType = AssociatedRolesConfig.AllowedAudienceEnum.ORGANIZATION.toString().toLowerCase(); - List roles = oAuth2RestClient.getRoles("admin", audienceType, null); - String adminRoleId = null; - if (roles.size() == 1) { - adminRoleId = roles.get(0); - } - ApplicationPatchModel applicationPatch = new ApplicationPatchModel(); - applicationPatch.associatedRoles(associatedRolesConfig); - associatedRolesConfig.addRolesItem( - new org.wso2.identity.integration.test.rest.api.server.application.management.v1.model.Role().id( - adminRoleId)); - oAuth2RestClient.updateApplication(applicationId, applicationPatch); - } - - private String addApplication() throws Exception { - - ApplicationModel application = new ApplicationModel(); - List grantTypes = new ArrayList<>(); - Collections.addAll(grantTypes, "password", "organization_switch"); - OpenIDConnectConfiguration oidcConfig = new OpenIDConnectConfiguration(); - oidcConfig.setGrantTypes(grantTypes); - InboundProtocols inboundProtocolsConfig = new InboundProtocols(); - inboundProtocolsConfig.setOidc(oidcConfig); - application.setInboundProtocolConfiguration(inboundProtocolsConfig); - application.setName("org-mgt-token-app"); - return oAuth2RestClient.createApplication(application); - } -} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/model/OrganizationUpdateRequest.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/model/OrganizationUpdateRequest.java deleted file mode 100644 index e09e8b696e4..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/model/OrganizationUpdateRequest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2023, 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.organization.management.v2.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; - -import javax.validation.Valid; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class OrganizationUpdateRequest { - private String displayName; - private String description; - private List claims = null; - - /** - * - **/ - public OrganizationUpdateRequest displayName(String displayName) { - - this.displayName = displayName; - return this; - } - - @ApiModelProperty(example = "scopeOne") - @JsonProperty("displayName") - @Valid - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - /** - * - **/ - public OrganizationUpdateRequest description(String description) { - - this.description = description; - return this; - } - - @ApiModelProperty(example = "Sample updated scope one") - @JsonProperty("description") - @Valid - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - /** - * - **/ - public OrganizationUpdateRequest claims(List claims) { - - this.claims = claims; - return this; - } - - @ApiModelProperty(example = "Sample updated scope one") - @JsonProperty("claims") - @Valid - public List getClaims() { - return claims; - } - - public void setClaims(List claims) { - this.claims = claims; - } - - public OrganizationUpdateRequest addClaims(String claim) { - if (this.claims == null) { - this.claims = new ArrayList<>(); - } - this.claims.add(claim); - return this; - } - - @Override - public boolean equals(Object o) { - - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - OrganizationUpdateRequest scope = (OrganizationUpdateRequest) o; - return Objects.equals(this.displayName, scope.displayName) && - Objects.equals(this.description, scope.description) && - Objects.equals(this.claims, scope.claims); - } - - @Override - public int hashCode() { - return Objects.hash(displayName, description, claims); - } - - @Override - public String toString() { - - return "class ScopeUpdateRequest {\n" + - " displayName: " + toIndentedString(displayName) + "\n" + - " description: " + toIndentedString(description) + "\n" + - " claims: " + toIndentedString(claims) + "\n" + - "}"; - } - - /** - * 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(); - } -} diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/restclients/RestBaseClient.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/restclients/RestBaseClient.java index a17afe1b654..476a46e047a 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/restclients/RestBaseClient.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/restclients/RestBaseClient.java @@ -43,6 +43,7 @@ public class RestBaseClient { public static final String AUTHORIZATION_ATTRIBUTE = "Authorization"; public static final String USER_AGENT_ATTRIBUTE = "User-Agent"; public static final String TENANT_PATH = "t/"; + public static final String ORGANIZATION_PATH = "o/"; public static final String PATH_SEPARATOR = "/"; public static final String OIDC = "oidc"; public static final String SAML = "saml"; diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-admin-user-in-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-admin-user-in-organization-request-body.json new file mode 100644 index 00000000000..549864486bb --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-admin-user-in-organization-request-body.json @@ -0,0 +1,14 @@ +{ + "emails": [ + { + "primary": true, + "value": "orgAdmin@gmail.com" + } + ], + "name": { + "familyName": "one", + "givenName": "boit" + }, + "password": "Kumar@2023", + "userName": "orgAdmin@gmail.com" +} \ No newline at end of file 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-organization-request-body.json new file mode 100644 index 00000000000..5024710990e --- /dev/null +++ b/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 @@ -0,0 +1,14 @@ +{ + "name": "Greater Hospital", + "description": "this is a construction company duplicate not shared", + "attributes": [ + { + "key": "Country", + "value": "Sri Lanka" + }, + { + "key": "Language", + "value": "Sinhala" + } + ] +} \ No newline at end of file diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/disable-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/disable-organization-request-body.json new file mode 100644 index 00000000000..26331042b68 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/disable-organization-request-body.json @@ -0,0 +1,7 @@ +[ + { + "operation": "REPLACE", + "path": "/status", + "value": "DISABLED" + } +] \ No newline at end of file diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/enable-self-organization-onboard-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/enable-self-organization-onboard-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/v2/enable-self-organization-onboard-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/enable-self-organization-onboard-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/v2/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/v2/add-organization-request-body.json deleted file mode 100644 index 469477887f5..00000000000 --- a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v2/add-organization-request-body.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "EasyMeet" -} 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 cef3f65afb0..31aa7dcf6ff 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 @@ -13,7 +13,7 @@ - + From b9682410b36c407a04c464f2417c419e3ffa4b45 Mon Sep 17 00:00:00 2001 From: sadilchamishka Date: Sun, 3 Dec 2023 01:42:23 +0530 Subject: [PATCH 4/6] Add b2b organization management integration tests --- .../src/test/resources/testng.xml | 350 ++++++++++++++++++ 1 file changed, 350 insertions(+) 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 31aa7dcf6ff..c8343bc1304 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 @@ -11,9 +11,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b5272d3860322b8f1094203e8db711cd08ce9959 Mon Sep 17 00:00:00 2001 From: sadilchamishka Date: Sun, 3 Dec 2023 01:48:36 +0530 Subject: [PATCH 5/6] Integration test refactorings --- .../management/v1/OrganizationManagementBaseTest.java | 3 +-- .../v1/add-admin-user-in-organization-request-body.json | 2 +- .../management/v1/add-organization-request-body.json | 2 +- .../management/v1/disable-organization-request-body.json | 2 +- .../v1/enable-self-organization-onboard-request-body.json | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) 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 5b7286551b3..7fe2d1ce94a 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 @@ -29,7 +29,7 @@ import java.io.IOException; /** - * Base test class for the OIDC Scope Management REST APIs. + * Base test class for the Organization Management REST APIs. */ public class OrganizationManagementBaseTest extends RESTAPIServerTestBase { @@ -72,5 +72,4 @@ public void testFinish() { RestAssured.basePath = StringUtils.EMPTY; } - } diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-admin-user-in-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-admin-user-in-organization-request-body.json index 549864486bb..7970e57b9bd 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/add-admin-user-in-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-admin-user-in-organization-request-body.json @@ -11,4 +11,4 @@ }, "password": "Kumar@2023", "userName": "orgAdmin@gmail.com" -} \ No newline at end of file +} 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-organization-request-body.json index 5024710990e..8fc1a55f698 100644 --- 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-organization-request-body.json @@ -11,4 +11,4 @@ "value": "Sinhala" } ] -} \ No newline at end of file +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/disable-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/disable-organization-request-body.json index 26331042b68..1fe88b57ad8 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/disable-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/disable-organization-request-body.json @@ -4,4 +4,4 @@ "path": "/status", "value": "DISABLED" } -] \ No newline at end of file +] diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/enable-self-organization-onboard-request-body.json b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/enable-self-organization-onboard-request-body.json index ff2365fba1a..60c0bf3f200 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/enable-self-organization-onboard-request-body.json +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/enable-self-organization-onboard-request-body.json @@ -6,4 +6,4 @@ "value": "true" } ] -} \ No newline at end of file +} From 58a99f27bb71ed44eebf9af982e8a143246d0935 Mon Sep 17 00:00:00 2001 From: sadilchamishka Date: Sun, 3 Dec 2023 16:06:46 +0530 Subject: [PATCH 6/6] Address review comments --- .../v1/OrganizationManagementSuccessTest.java | 15 ++++++--------- .../v1/add-organization-request-body.json | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) 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 143f4db7ab8..55843cb7bc9 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 @@ -78,12 +78,9 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.core.IsNull.notNullValue; import static org.testng.Assert.assertNotNull; -import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.OrganizationManagementBaseTest.SUPER_ORGANIZATION_ID; -import static org.wso2.identity.integration.test.rest.api.server.organization.management.v1.OrganizationManagementBaseTest.SUPER_TENANT_DOMAIN; import static org.wso2.identity.integration.test.restclients.RestBaseClient.CONTENT_TYPE_ATTRIBUTE; import static org.wso2.identity.integration.test.restclients.RestBaseClient.ORGANIZATION_PATH; import static org.wso2.identity.integration.test.restclients.RestBaseClient.TENANT_PATH; -import static org.wso2.identity.integration.test.restclients.RestBaseClient.USER_AGENT_ATTRIBUTE; import static org.wso2.identity.integration.test.scim2.SCIM2BaseTestCase.SCIM2_USERS_ENDPOINT; /** @@ -252,27 +249,27 @@ public void switchM2MToken() throws IOException, ParseException { EntityUtils.consume(response.getEntity()); JSONParser parser = new JSONParser(); org.json.simple.JSONObject json = (org.json.simple.JSONObject) parser.parse(responseString); + Assert.assertNotNull(json, "Access token response is null."); Assert.assertNotNull(json.get(OAuth2Constant.ACCESS_TOKEN), "Access token is null."); switchedM2MToken = (String) json.get(OAuth2Constant.ACCESS_TOKEN); Assert.assertNotNull(switchedM2MToken); } @Test(dependsOnMethods = "switchM2MToken") - public void createOnBoardUserInOrganization() throws IOException { + 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); - Header[] headerList = new Header[3]; - headerList[0] = new BasicHeader(USER_AGENT_ATTRIBUTE, OAuth2Constant.USER_AGENT); - headerList[1] = new BasicHeader("Authorization", "Bearer " + switchedM2MToken); - headerList[2] = new BasicHeader(CONTENT_TYPE_ATTRIBUTE, "application/scim+json"); + Header[] headerList = new Header[2]; + headerList[0] = new BasicHeader("Authorization", "Bearer " + switchedM2MToken); + headerList[1] = new BasicHeader(CONTENT_TYPE_ATTRIBUTE, "application/scim+json"); request.setHeaders(headerList); request.setEntity(new StringEntity(body)); HttpResponse response = client.execute(request); Assert.assertEquals(response.getStatusLine().getStatusCode(), 201); } - @Test(dependsOnMethods = "createOnBoardUserInOrganization") + @Test(dependsOnMethods = "createUserInOrganization") public void addB2BApplication() throws Exception { ApplicationModel application = new ApplicationModel(); 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-organization-request-body.json index 8fc1a55f698..5d868f78970 100644 --- 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-organization-request-body.json @@ -1,6 +1,6 @@ { "name": "Greater Hospital", - "description": "this is a construction company duplicate not shared", + "description": "Hospital chain in South Asia", "attributes": [ { "key": "Country",