org.wso2.identity.integration.test.consent.SelfSignUpConsentTest.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.identity.integration.test.consent.SelfSignUpConsentTest.java

Source

/*
 * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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.consent;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.wink.client.ClientConfig;
import org.apache.wink.client.Resource;
import org.apache.wink.client.RestClient;
import org.apache.wink.client.handlers.BasicAuthSecurityHandler;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.wso2.carbon.identity.application.common.model.idp.xsd.FederatedAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.idp.xsd.IdentityProvider;
import org.wso2.carbon.identity.application.common.model.idp.xsd.IdentityProviderProperty;
import org.wso2.carbon.integration.common.admin.client.AuthenticatorClient;
import org.wso2.carbon.user.mgt.stub.UserAdminUserAdminException;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import org.wso2.identity.integration.common.clients.Idp.IdentityProviderMgtServiceClient;
import org.wso2.identity.integration.common.clients.UserManagementClient;
import org.wso2.identity.integration.common.utils.ISIntegrationTest;
import org.wso2.identity.integration.test.utils.DataExtractUtil;
import org.wso2.identity.integration.test.utils.OAuth2Constant;

import java.io.IOException;
import java.rmi.RemoteException;
import javax.ws.rs.core.MediaType;

/**
 * Self sign up tests - with consents.
 */
public class SelfSignUpConsentTest extends ISIntegrationTest {

    protected Log log = LogFactory.getLog(getClass());

    public static final String CONSNT_ENDPOINT_SUFFIX = "/api/identity/consent-mgt/v1.0/consents";
    public static final String USER_RECOVERY_ME_ENDPOINT = "/api/identity/user/v1.0/me";
    private static final String CALLBACK_ENDPOINT = "https://localhost:9443/carbon/callback";
    private static final String COUNTRY_WSO2_CLAIM = "http://wso2.org/claims/country";
    private static final String CALLBACK_QUERY_PARAM = "callback";
    private static final String USERNAME_QUERY_PARAM = "username";
    private static final String ADMIN = "admin";
    private static final String EBONY = "ebony";
    private static final String PASSWORD = "UsEr@123";
    private static final String ENABLE_SELF_REGISTRATION_PROP_KEY = "SelfRegistration.Enable";
    private static final String DISABLE_ACC_LOCK_ON_SELF_REG_PROP_KEY = "SelfRegistration.LockOnCreation";
    private static final String FINANCIAL_PURPOSE_NAME = "Financial Purpose";
    private static final String FINANCIAL = "Financial";
    private static final String ERROR_MESSAGE_SELF_REGISTRATION_DISABLED = "Self registration is disabled for tenant"
            + " - %s";
    private static final String ERROR_MESSAGE_INVALID_TENANT = "Invalid tenant domain - %s";
    private static final String ERROR_MESSAGE_USERNAME_TAKEN = "Username '%s' is already taken. Please pick a "
            + "different username";

    private String tenantAdminUserName;
    private String isServerBackendUrl;
    private String selfRegisterDoEndpoint;
    private String signupDoEndpoint;
    private String consentEndpoint;
    private String selfRegistrationMeEndpoint;
    private IdentityProvider superTenantResidentIDP;
    private IdentityProvider tenantResidentIDP;
    private IdentityProviderMgtServiceClient superTenantIDPMgtClient;
    private IdentityProviderMgtServiceClient tenantIDPMgtClient;
    private AuthenticatorClient logManager;
    private UserManagementClient tenantUserMgtClient;
    private String secondaryTenantDomain;
    private String financialPurposeId;

    @BeforeClass(alwaysRun = true)
    public void testInit() throws Exception {

        super.init();
        secondaryTenantDomain = isServer.getTenantList().get(1);
        tenantAdminUserName = ADMIN + "@" + secondaryTenantDomain;
        this.logManager = new AuthenticatorClient(backendURL);
        String tenantCookie = this.logManager.login(ADMIN + "@" + secondaryTenantDomain, ADMIN,
                isServer.getInstance().getHosts().get("default"));

        superTenantIDPMgtClient = new IdentityProviderMgtServiceClient(sessionCookie, backendURL);
        tenantIDPMgtClient = new IdentityProviderMgtServiceClient(tenantCookie, backendURL);
        tenantUserMgtClient = new UserManagementClient(backendURL, tenantCookie);
        isServerBackendUrl = isServer.getContextUrls().getWebAppURLHttps();
        consentEndpoint = isServerBackendUrl + "/t/" + secondaryTenantDomain + CONSNT_ENDPOINT_SUFFIX;
        selfRegisterDoEndpoint = isServerBackendUrl + "/accountrecoveryendpoint/register.do";
        signupDoEndpoint = isServerBackendUrl + "/accountrecoveryendpoint/signup.do";
        selfRegistrationMeEndpoint = isServerBackendUrl + "/t/" + secondaryTenantDomain + USER_RECOVERY_ME_ENDPOINT;
        superTenantResidentIDP = superTenantIDPMgtClient.getResidentIdP();
        tenantResidentIDP = tenantIDPMgtClient.getResidentIdP();

    }

    @AfterClass(alwaysRun = true)
    public void atEnd() throws RemoteException, UserAdminUserAdminException {

        tenantUserMgtClient.deleteUser(EBONY);
    }

    @AfterMethod
    public void resetResidentIDP() throws Exception {

        updateResidentIDPProperty(superTenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "false", true);
        updateResidentIDPProperty(tenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "false", false);
        updateResidentIDPProperty(tenantResidentIDP, DISABLE_ACC_LOCK_ON_SELF_REG_PROP_KEY, "true", false);
    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Testing self sign-up page without purposes enter "
            + "username")

    public void testInitialSelfSignUpPage() throws IOException {

        HttpClient client = HttpClientBuilder.create().build();
        String selfRegisterEndpoint = selfRegisterDoEndpoint + "?" + CALLBACK_QUERY_PARAM + "=" + CALLBACK_ENDPOINT;
        HttpResponse httpResponse = sendGetRequest(client, selfRegisterEndpoint);
        String content = DataExtractUtil.getContentData(httpResponse);
        Assert.assertNotNull(content);
        Assert.assertTrue(content.contains("Enter your username"),
                "Page for entering username is not prompted while" + " self registering");
        Assert.assertTrue(content.contains(CALLBACK_ENDPOINT),
                "Callback endpoint is not available in self " + "registration username input page.");
    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Test without enabling self registration")
    public void testWithoutEnablingSelfRegistration() throws Exception {

        String content = doCallSignUpDo(ADMIN);
        Assert.assertNotNull(content);
        Assert.assertTrue(content
                .contains("Self registration is disabled for tenant - " + isServer.getSuperTenant().getDomain()));
    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Test for an invalid tenant")
    public void testForAnInvalidTenant() throws Exception {

        String content = doCallSignUpDo("john@googleinvalid.com");
        Assert.assertNotNull(content);
        Assert.assertTrue(content.contains(String.format(ERROR_MESSAGE_INVALID_TENANT, "googleinvalid.com")));
    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Test after enabling self registration but for an "
            + "already taken username")
    public void testAfterEnablingSelfRegistrationInvalidUser() throws Exception {

        updateResidentIDPProperty(superTenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "true", true);

        String content = doCallSignUpDo(ADMIN);
        Assert.assertTrue(content.contains(String.format(ERROR_MESSAGE_USERNAME_TAKEN, ADMIN)));
    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Test after enabling self registration, but for a "
            + "different tenant user")
    public void testForCrossTenantWithoutEnabling() throws Exception {

        updateResidentIDPProperty(superTenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "true", true);

        String content = doCallSignUpDo("john@" + secondaryTenantDomain);
        Assert.assertTrue(
                content.contains(String.format(ERROR_MESSAGE_SELF_REGISTRATION_DISABLED, secondaryTenantDomain)));
    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Test for a valid user")
    public void testForValidUsername() throws Exception {

        updateResidentIDPProperty(superTenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "true", true);

        String content = doCallSignUpDo("smith");
        Assert.assertTrue(content.contains("Password"));
        Assert.assertTrue(content.contains("Confirm password"));

    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Test whether purposes are shown in self registration "
            + "page, without configuring purposes")
    public void testPurposesWithoutConfiguredPurposes() throws Exception {

        updateResidentIDPProperty(tenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "true", false);

        String content = doCallSignUpDo("smith@" + secondaryTenantDomain);
        Assert.assertTrue(content.contains("Password"));
        Assert.assertTrue(content.contains("Confirm password"));
        Assert.assertTrue(!content.contains(FINANCIAL_PURPOSE_NAME));
    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Test whether purposes are shown on self registration "
            + "page", dependsOnMethods = "testPurposesWithoutConfiguredPurposes")
    public void testWithPurposes() throws Exception {

        updateResidentIDPProperty(tenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "true", false);

        addCategoryCountry();
        addFinancialPurpose();
        addFinancialPurposeCategory();
        String content = doCallSignUpDo("smith@" + secondaryTenantDomain);
        Assert.assertTrue(content.contains("Password"));
        Assert.assertTrue(content.contains("Confirm password"));
        Assert.assertTrue(content.contains(FINANCIAL_PURPOSE_NAME));
    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Self sign up with a valid user with proper consents", dependsOnMethods = "testWithPurposes")
    public void selfSignUpWithConsents() throws Exception {

        updateResidentIDPProperty(tenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "true", false);
        updateResidentIDPProperty(tenantResidentIDP, DISABLE_ACC_LOCK_ON_SELF_REG_PROP_KEY, "false", false);
        selfRegister(EBONY, PASSWORD, EBONY, EBONY + "@gmail.com", "Jackson", "+9433909388");
        String content = doCallSignUpDo(EBONY + "@" + secondaryTenantDomain);
        Assert.assertTrue(
                content.contains(String.format(ERROR_MESSAGE_USERNAME_TAKEN, EBONY + "@" + secondaryTenantDomain)));

    }

    @Test(alwaysRun = true, groups = "wso2.is", description = "Test for a valid user", dependsOnMethods = "selfSignUpWithConsents")
    public void getPurposes() throws Exception {

        updateResidentIDPProperty(tenantResidentIDP, ENABLE_SELF_REGISTRATION_PROP_KEY, "true", false);
        updateResidentIDPProperty(tenantResidentIDP, DISABLE_ACC_LOCK_ON_SELF_REG_PROP_KEY, "false", false);
        String consents = getConsents(EBONY + "@" + secondaryTenantDomain, PASSWORD);
        log.info("Consents for user " + EBONY + " :" + consents);
        Assert.assertNotNull(consents);
        JSONArray purposesJson = new JSONArray(consents);
        String receiptID = ((JSONObject) purposesJson.get(0)).getString("consentReceiptID");
        String receipt = getConsent(EBONY + "@" + secondaryTenantDomain, PASSWORD, receiptID);
        JSONObject receiptJson = new JSONObject(receipt);
        Assert.assertEquals(receiptJson.getString("collectionMethod"), "Web Form - Self Registration");

    }

    private void updateResidentIDP(IdentityProvider residentIdentityProvider, boolean isSuperTenant)
            throws Exception {

        FederatedAuthenticatorConfig[] federatedAuthenticatorConfigs = residentIdentityProvider
                .getFederatedAuthenticatorConfigs();
        for (FederatedAuthenticatorConfig authenticatorConfig : federatedAuthenticatorConfigs) {
            if (!authenticatorConfig.getName().equalsIgnoreCase("samlsso")) {
                federatedAuthenticatorConfigs = (FederatedAuthenticatorConfig[]) ArrayUtils
                        .removeElement(federatedAuthenticatorConfigs, authenticatorConfig);
            }
        }
        residentIdentityProvider.setFederatedAuthenticatorConfigs(federatedAuthenticatorConfigs);
        if (isSuperTenant) {
            superTenantIDPMgtClient.updateResidentIdP(residentIdentityProvider);
        } else {
            tenantIDPMgtClient.updateResidentIdP(residentIdentityProvider);
        }
    }

    private void updateResidentIDPProperty(IdentityProvider residentIdp, String propertyKey, String value,
            boolean isSuperTenant) throws Exception {

        IdentityProviderProperty[] idpProperties = residentIdp.getIdpProperties();
        for (IdentityProviderProperty providerProperty : idpProperties) {
            if (propertyKey.equalsIgnoreCase(providerProperty.getName())) {
                providerProperty.setValue(value);
            }
        }
        updateResidentIDP(residentIdp, isSuperTenant);
    }

    private String doCallSignUpDo(String username) throws IOException {

        HttpClient client = HttpClientBuilder.create().build();
        String selfRegisterEndpoint = signupDoEndpoint + "?" + USERNAME_QUERY_PARAM + "=" + username;
        HttpResponse httpResponse = sendGetRequest(client, selfRegisterEndpoint);
        return DataExtractUtil.getContentData(httpResponse);
    }

    public void addCategoryCountry() {

        String name = COUNTRY_WSO2_CLAIM;
        String description = "Country";
        addPIICategory(name, description);

    }

    public void addFinancialPurposeCategory() throws JSONException {

        String name = FINANCIAL;
        String description = FINANCIAL_PURPOSE_NAME;
        addPurposeCategory(name, description);
    }

    private void addPIICategory(String name, String description) {

        ClientConfig clientConfig = new ClientConfig();
        BasicAuthSecurityHandler basicAuth = new BasicAuthSecurityHandler();
        basicAuth.setUserName(tenantAdminUserName);
        basicAuth.setPassword(ADMIN);
        clientConfig.handlers(basicAuth);

        RestClient restClient = new RestClient(clientConfig);
        Resource piiCatResource = restClient.resource(consentEndpoint + "/" + "pii-categories");

        String addPIICatString = "{\"piiCategory\": " + "\"" + name + "\"" + ", \"description\": " + "\""
                + description + "\" , \"sensitive\": \"" + true + "\"}";

        piiCatResource.contentType(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON)
                .post(String.class, addPIICatString);
    }

    private String addPurposeCategory(String name, String description) throws JSONException {

        ClientConfig clientConfig = new ClientConfig();
        BasicAuthSecurityHandler basicAuth = new BasicAuthSecurityHandler();
        basicAuth.setUserName(tenantAdminUserName);
        basicAuth.setPassword(ADMIN);
        clientConfig.handlers(basicAuth);

        RestClient restClient = new RestClient(clientConfig);
        Resource piiCatResource = restClient.resource(consentEndpoint + "/" + "purpose-categories");

        String addPurposeCatString = "{\"purposeCategory\": " + "\"" + name + "\"" + ", \"description\": " + "\""
                + description + "\"}";

        String content = piiCatResource.contentType(MediaType.APPLICATION_JSON_TYPE)
                .accept(MediaType.APPLICATION_JSON).post(String.class, addPurposeCatString);
        JSONObject purpose = new JSONObject(content);
        return purpose.getString("purposeCategoryId");
    }

    public void addFinancialPurpose() throws JSONException {

        String name = FINANCIAL_PURPOSE_NAME;
        String description = FINANCIAL_PURPOSE_NAME;
        financialPurposeId = addPurpose(name, description);

    }

    private String addPurpose(String name, String description) throws JSONException {

        ClientConfig clientConfig = new ClientConfig();
        BasicAuthSecurityHandler basicAuth = new BasicAuthSecurityHandler();
        basicAuth.setUserName(tenantAdminUserName);
        basicAuth.setPassword(ADMIN);
        clientConfig.handlers(basicAuth);

        RestClient restClient = new RestClient(clientConfig);
        Resource piiCatResource = restClient.resource(consentEndpoint + "/" + "purposes");

        String addPurposeString = "{\"purpose\": " + "\"" + name + "\"" + ", \"description\": " + "\"" + description
                + "\" , \"piiCategories\": [" + 1 + "]}";

        String response = piiCatResource.contentType(MediaType.APPLICATION_JSON_TYPE)
                .accept(MediaType.APPLICATION_JSON).post(String.class, addPurposeString);
        JSONObject purpose = new JSONObject(response);
        return purpose.getString("purposeId");
    }

    private HttpResponse sendGetRequest(HttpClient client, String locationURL) throws IOException {

        HttpGet getRequest = new HttpGet(locationURL);
        getRequest.setHeader("User-Agent", OAuth2Constant.USER_AGENT);
        HttpResponse response = client.execute(getRequest);

        return response;
    }

    private void selfRegister(String username, String password, String givenName, String emailAddress,
            String lastName, String mobile) {

        String consent = getConsentReqBody(financialPurposeId, 1, username);

        String selfRegisterReqBody = "{\"user\": {\"username\": \"" + username + "\",\"realm\": \"\", "
                + "\"password\": \"" + password + "\",\"claims\": "
                + "[{\"uri\": \"http://wso2.org/claims/givenname\",\"value\": \"" + givenName + "\" },"
                + "{\"uri\": \"http://wso2.org/claims/emailaddress\",\"value\": \"" + emailAddress + "\"},"
                + "{\"uri\": \"http://wso2.org/claims/lastname\",\"value\": \"" + lastName + "\"},"
                + "{\"uri\": \"http://wso2.org/claims/mobile\",\"value\": \"" + mobile + "\"} ] },"
                + "\"properties\": [{\"key\": \"consent\", \"value\": \"" + consent + "\"}]}";

        ClientConfig clientConfig = new ClientConfig();
        BasicAuthSecurityHandler basicAuth = new BasicAuthSecurityHandler();
        basicAuth.setUserName(tenantAdminUserName);
        basicAuth.setPassword(ADMIN);
        clientConfig.handlers(basicAuth);

        RestClient restClient = new RestClient(clientConfig);
        Resource user = restClient.resource(selfRegistrationMeEndpoint);

        user.contentType(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON).post(String.class,
                selfRegisterReqBody);

    }

    private String getConsentReqBody(String purposeId, int piiCategoryId, String username) {

        return "{\\\"jurisdiction\\\":\\\"someJurisdiction\\\",\\\"collectionMethod\\\":\\\"Web Form - Self "
                + "Registration\\\"," + "\\\"language\\\":\\\"en\\\",\\\"piiPrincipalId\\\":\\\"" + username
                + "\\\",\\\"services\\\":"
                + "[{\\\"tenantDomain\\\":\\\"wso2.com\\\",\\\"serviceDisplayName\\\":\\\"Resident IDP\\\","
                + "\\\"serviceDescription\\\":\\\"Resident IDP\\\",\\\"purposes\\\":[{\\\"purposeId\\\":"
                + purposeId + "," + "\\\"purposeCategoryId\\\":[1],"
                + "\\\"consentType\\\":\\\"EXPLICIT\\\",\\\"piiCategory\\\":[{\\\"piiCategoryId\\\":"
                + piiCategoryId + ","
                + "\\\"validity\\\":\\\"DATE_UNTIL:INDEFINITE\\\"}],\\\"primaryPurpose\\\":true,"
                + "\\\"termination\\\":\\\"DATE_UNTIL:INDEFINITE\\\",\\\"thirdPartyDisclosure\\\":false}],\\\"tenantId\\\":1}],"
                + "\\\"policyURL\\\":\\\"somePolicyUrl\\\",\\\"tenantId\\\":1,\\\"properties\\\":{}}";
    }

    private String getConsents(String username, String password) {

        ClientConfig clientConfig = new ClientConfig();
        BasicAuthSecurityHandler basicAuth = new BasicAuthSecurityHandler();
        basicAuth.setUserName(username);
        basicAuth.setPassword(password);
        clientConfig.handlers(basicAuth);

        RestClient restClient = new RestClient(clientConfig);
        Resource user = restClient
                .resource(consentEndpoint + "?piiPrincipalId=" + MultitenantUtils.getTenantAwareUsername(username));

        String response = user.contentType(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON)
                .get(String.class);
        return response;
    }

    private String getConsent(String username, String password, String receiptId) {

        log.info("Retrieving consent for username " + username + ". reciptId : " + receiptId);
        ClientConfig clientConfig = new ClientConfig();
        BasicAuthSecurityHandler basicAuth = new BasicAuthSecurityHandler();
        basicAuth.setUserName(username);
        basicAuth.setPassword(password);
        clientConfig.handlers(basicAuth);

        RestClient restClient = new RestClient(clientConfig);
        Resource user = restClient.resource(consentEndpoint + "/receipts/" + receiptId);
        log.info("Calling to receipt endpoint :" + consentEndpoint + "/receipts/" + receiptId);

        String response = user.contentType(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON)
                .get(String.class);
        return response;
    }
}