From abce9d0e7dd017887e2d9e1d6fe6aff7f608de54 Mon Sep 17 00:00:00 2001 From: BiyonFernando Date: Tue, 6 Aug 2024 10:48:26 +0530 Subject: [PATCH] Add integration test for audience validation --- .../clients/publisher/api/openapi.yaml | 52 +++++ .../clients/publisher/docs/APIDTO.md | 1 + .../clients/publisher/docs/APIInfoDTO.md | 1 + .../clients/publisher/docs/APIProductDTO.md | 1 + .../publisher/docs/APIProductInfoDTO.md | 1 + .../clients/publisher/api/v1/dto/APIDTO.java | 31 ++- .../publisher/api/v1/dto/APIInfoDTO.java | 31 ++- .../publisher/api/v1/dto/APIProductDTO.java | 33 ++- .../api/v1/dto/APIProductInfoDTO.java | 33 ++- .../src/main/resources/publisher-api.yaml | 24 +++ .../lifecycle/AudienceValidationTestCase.java | 195 ++++++++++++++++++ .../src/test/resources/testng.xml | 1 + 12 files changed, 398 insertions(+), 6 deletions(-) create mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/AudienceValidationTestCase.java diff --git a/modules/integration/tests-common/clients/publisher/api/openapi.yaml b/modules/integration/tests-common/clients/publisher/api/openapi.yaml index 2dfe0b6820..268be810a4 100644 --- a/modules/integration/tests-common/clients/publisher/api/openapi.yaml +++ b/modules/integration/tests-common/clients/publisher/api/openapi.yaml @@ -17166,6 +17166,9 @@ components: - securityScheme name: CalculatorAPI context: CalculatorAPI + audiences: + - '["aud1","aud2","aud3"]' + - '["aud1","aud2","aud3"]' createdTime: 2021-02-11 09:57:25 id: 01234567-0123-0123-0123-012345678901 additionalProperties: @@ -17196,6 +17199,9 @@ components: - securityScheme name: CalculatorAPI context: CalculatorAPI + audiences: + - '["aud1","aud2","aud3"]' + - '["aud1","aud2","aud3"]' createdTime: 2021-02-11 09:57:25 id: 01234567-0123-0123-0123-012345678901 additionalProperties: @@ -17276,6 +17282,9 @@ components: - securityScheme name: CalculatorAPI context: CalculatorAPI + audiences: + - '["aud1","aud2","aud3"]' + - '["aud1","aud2","aud3"]' createdTime: 2021-02-11 09:57:25 id: 01234567-0123-0123-0123-012345678901 additionalProperties: @@ -17331,6 +17340,13 @@ components: - SINGLE example: PUBLIC type: string + audiences: + description: The audiences of the API for jwt validation. Accepted values + are any String values + items: + example: '["aud1","aud2","aud3"]' + type: string + type: array lifeCycleStatus: example: CREATED type: string @@ -17557,6 +17573,9 @@ components: url: https://localhost:9443/am/sample/pizzashack/v1/api/ production_endpoints: url: https://localhost:9443/am/sample/pizzashack/v1/api/ + audiences: + - '["aud1","aud2","aud3"]' + - '["aud1","aud2","aud3"]' mediationPolicies: - name: json_to_xml_in_message type: in @@ -17717,6 +17736,13 @@ components: - SINGLE example: PUBLIC type: string + audiences: + description: The audiences of the API for jwt validation. Accepted values + are any String values + items: + example: '["aud1","aud2","aud3"]' + type: string + type: array transport: description: | Supported transports for the API (http and/or https). @@ -18292,6 +18318,9 @@ components: context: pizzaproduct description: This is a simple API for Pizza Shack online pizza delivery store + audiences: + - '["aud1","aud2","aud3"]' + - '["aud1","aud2","aud3"]' id: 01234567-0123-0123-0123-012345678901 state: state - hasThumbnail: true @@ -18303,6 +18332,9 @@ components: context: pizzaproduct description: This is a simple API for Pizza Shack online pizza delivery store + audiences: + - '["aud1","aud2","aud3"]' + - '["aud1","aud2","aud3"]' id: 01234567-0123-0123-0123-012345678901 state: state properties: @@ -18329,6 +18361,9 @@ components: name: PizzaShackAPIProduct context: pizzaproduct description: This is a simple API for Pizza Shack online pizza delivery store + audiences: + - '["aud1","aud2","aud3"]' + - '["aud1","aud2","aud3"]' id: 01234567-0123-0123-0123-012345678901 state: state properties: @@ -18373,6 +18408,13 @@ components: gatewayVendor: example: wso2 type: string + audiences: + description: The audiences of the API product for jwt validation. Accepted + values are any String values + items: + example: '["aud1","aud2","aud3"]' + type: string + type: array title: API Info object with basic API details. type: object APIProduct: @@ -18407,6 +18449,9 @@ components: provider: admin context: pizzaproduct createdTime: createdTime + audiences: + - '["aud1","aud2","aud3"]' + - '["aud1","aud2","aud3"]' lastUpdatedTime: lastUpdatedTime id: 01234567-0123-0123-0123-012345678901 state: CREATED @@ -18703,6 +18748,13 @@ components: workflowStatus: example: APPROVED type: string + audiences: + description: The audiences of the API for jwt validation. Accepted values + are any String values + items: + example: '["aud1","aud2","aud3"]' + type: string + type: array required: - name title: API Product object diff --git a/modules/integration/tests-common/clients/publisher/docs/APIDTO.md b/modules/integration/tests-common/clients/publisher/docs/APIDTO.md index 076922e1ee..90a9a3f066 100644 --- a/modules/integration/tests-common/clients/publisher/docs/APIDTO.md +++ b/modules/integration/tests-common/clients/publisher/docs/APIDTO.md @@ -26,6 +26,7 @@ Name | Type | Description | Notes **enableSubscriberVerification** | **Boolean** | | [optional] **type** | [**TypeEnum**](#TypeEnum) | The api creation type to be used. Accepted values are HTTP, WS, SOAPTOREST, GRAPHQL, WEBSUB, SSE, WEBHOOK, ASYNC | [optional] **audience** | [**AudienceEnum**](#AudienceEnum) | The audience of the API. Accepted values are PUBLIC, SINGLE | [optional] +**audiences** | **List<String>** | The audiences of the API for jwt validation. Accepted values are any String values | [optional] **transport** | **List<String>** | Supported transports for the API (http and/or https). | [optional] **tags** | **List<String>** | | [optional] **policies** | **List<String>** | | [optional] diff --git a/modules/integration/tests-common/clients/publisher/docs/APIInfoDTO.md b/modules/integration/tests-common/clients/publisher/docs/APIInfoDTO.md index df6156c42e..e6f4157270 100644 --- a/modules/integration/tests-common/clients/publisher/docs/APIInfoDTO.md +++ b/modules/integration/tests-common/clients/publisher/docs/APIInfoDTO.md @@ -16,6 +16,7 @@ Name | Type | Description | Notes **provider** | **String** | If the provider value is not given, the user invoking the API will be used as the provider. | [optional] **type** | **String** | | [optional] **audience** | [**AudienceEnum**](#AudienceEnum) | The audience of the API. Accepted values are PUBLIC, SINGLE | [optional] +**audiences** | **List<String>** | The audiences of the API for jwt validation. Accepted values are any String values | [optional] **lifeCycleStatus** | **String** | | [optional] **workflowStatus** | **String** | | [optional] **hasThumbnail** | **Boolean** | | [optional] diff --git a/modules/integration/tests-common/clients/publisher/docs/APIProductDTO.md b/modules/integration/tests-common/clients/publisher/docs/APIProductDTO.md index 29695adb4b..f87ff8c81b 100644 --- a/modules/integration/tests-common/clients/publisher/docs/APIProductDTO.md +++ b/modules/integration/tests-common/clients/publisher/docs/APIProductDTO.md @@ -49,6 +49,7 @@ Name | Type | Description | Notes **scopes** | [**List<APIScopeDTO>**](APIScopeDTO.md) | | [optional] **categories** | **List<String>** | API categories | [optional] **workflowStatus** | **String** | | [optional] +**audiences** | **List<String>** | The audiences of the API for jwt validation. Accepted values are any String values | [optional] diff --git a/modules/integration/tests-common/clients/publisher/docs/APIProductInfoDTO.md b/modules/integration/tests-common/clients/publisher/docs/APIProductInfoDTO.md index 8094eee4ce..10ab26d65a 100644 --- a/modules/integration/tests-common/clients/publisher/docs/APIProductInfoDTO.md +++ b/modules/integration/tests-common/clients/publisher/docs/APIProductInfoDTO.md @@ -15,6 +15,7 @@ Name | Type | Description | Notes **state** | **String** | State of the API product. Only published api products are visible on the Developer Portal | [optional] **securityScheme** | **List<String>** | Types of API security, the current API secured with. It can be either OAuth2 or mutual SSL or both. If it is not set OAuth2 will be set as the security for the current API. | [optional] **gatewayVendor** | **String** | | [optional] +**audiences** | **List<String>** | The audiences of the API product for jwt validation. Accepted values are any String values | [optional] diff --git a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIDTO.java b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIDTO.java index 6047437d7f..3bec30ba1b 100644 --- a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIDTO.java +++ b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIDTO.java @@ -236,6 +236,10 @@ public AudienceEnum read(final JsonReader jsonReader) throws IOException { @SerializedName(SERIALIZED_NAME_AUDIENCE) private AudienceEnum audience; + public static final String SERIALIZED_NAME_AUDIENCES = "audiences"; + @SerializedName(SERIALIZED_NAME_AUDIENCES) + private List audiences = null; + public static final String SERIALIZED_NAME_TRANSPORT = "transport"; @SerializedName(SERIALIZED_NAME_TRANSPORT) private List transport = null; @@ -1044,6 +1048,29 @@ public void setAudience(AudienceEnum audience) { } + public APIDTO audiences(List audiences) { + + this.audiences = audiences; + return this; + } + + /** + * The audiences of the API for jwt validation. Accepted values are any String values + * @return audiences + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "The audiences of the API for jwt validation. Accepted values are any String values") + + public List getAudiences() { + return audiences; + } + + + public void setAudiences(List audiences) { + this.audiences = audiences; + } + + public APIDTO transport(List transport) { this.transport = transport; @@ -1970,6 +1997,7 @@ public boolean equals(Object o) { Objects.equals(this.enableSubscriberVerification, API.enableSubscriberVerification) && Objects.equals(this.type, API.type) && Objects.equals(this.audience, API.audience) && + Objects.equals(this.audiences, API.audiences) && Objects.equals(this.transport, API.transport) && Objects.equals(this.tags, API.tags) && Objects.equals(this.policies, API.policies) && @@ -2013,7 +2041,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(id, name, description, context, version, provider, lifeCycleStatus, wsdlInfo, wsdlUrl, responseCachingEnabled, cacheTimeout, hasThumbnail, isDefaultVersion, isRevision, revisionedApiId, revisionId, enableSchemaValidation, enableSubscriberVerification, type, audience, transport, tags, policies, apiThrottlingPolicy, authorizationHeader, apiKeyHeader, securityScheme, maxTps, visibility, visibleRoles, visibleTenants, mediationPolicies, apiPolicies, subscriptionAvailability, subscriptionAvailableTenants, additionalProperties, additionalPropertiesMap, monetization, accessControl, accessControlRoles, businessInformation, corsConfiguration, websubSubscriptionConfiguration, workflowStatus, createdTime, lastUpdatedTimestamp, lastUpdatedTime, endpointConfig, endpointImplementationType, scopes, operations, threatProtectionPolicies, categories, keyManagers, serviceInfo, advertiseInfo, gatewayVendor, gatewayType, asyncTransportProtocols); + return Objects.hash(id, name, description, context, version, provider, lifeCycleStatus, wsdlInfo, wsdlUrl, responseCachingEnabled, cacheTimeout, hasThumbnail, isDefaultVersion, isRevision, revisionedApiId, revisionId, enableSchemaValidation, enableSubscriberVerification, type, audience, audiences, transport, tags, policies, apiThrottlingPolicy, authorizationHeader, apiKeyHeader, securityScheme, maxTps, visibility, visibleRoles, visibleTenants, mediationPolicies, apiPolicies, subscriptionAvailability, subscriptionAvailableTenants, additionalProperties, additionalPropertiesMap, monetization, accessControl, accessControlRoles, businessInformation, corsConfiguration, websubSubscriptionConfiguration, workflowStatus, createdTime, lastUpdatedTimestamp, lastUpdatedTime, endpointConfig, endpointImplementationType, scopes, operations, threatProtectionPolicies, categories, keyManagers, serviceInfo, advertiseInfo, gatewayVendor, gatewayType, asyncTransportProtocols); } @@ -2041,6 +2069,7 @@ public String toString() { sb.append(" enableSubscriberVerification: ").append(toIndentedString(enableSubscriberVerification)).append("\n"); sb.append(" type: ").append(toIndentedString(type)).append("\n"); sb.append(" audience: ").append(toIndentedString(audience)).append("\n"); + sb.append(" audiences: ").append(toIndentedString(audiences)).append("\n"); sb.append(" transport: ").append(toIndentedString(transport)).append("\n"); sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); sb.append(" policies: ").append(toIndentedString(policies)).append("\n"); diff --git a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIInfoDTO.java b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIInfoDTO.java index 489cbc665d..9f18f75838 100644 --- a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIInfoDTO.java +++ b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIInfoDTO.java @@ -122,6 +122,10 @@ public AudienceEnum read(final JsonReader jsonReader) throws IOException { @SerializedName(SERIALIZED_NAME_AUDIENCE) private AudienceEnum audience; + public static final String SERIALIZED_NAME_AUDIENCES = "audiences"; + @SerializedName(SERIALIZED_NAME_AUDIENCES) + private List audiences = null; + public static final String SERIALIZED_NAME_LIFE_CYCLE_STATUS = "lifeCycleStatus"; @SerializedName(SERIALIZED_NAME_LIFE_CYCLE_STATUS) private String lifeCycleStatus; @@ -385,6 +389,29 @@ public void setAudience(AudienceEnum audience) { } + public APIInfoDTO audiences(List audiences) { + + this.audiences = audiences; + return this; + } + + /** + * The audiences of the API for jwt validation. Accepted values are any String values + * @return audiences + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "The audiences of the API for jwt validation. Accepted values are any String values") + + public List getAudiences() { + return audiences; + } + + + public void setAudiences(List audiences) { + this.audiences = audiences; + } + + public APIInfoDTO lifeCycleStatus(String lifeCycleStatus) { this.lifeCycleStatus = lifeCycleStatus; @@ -588,6 +615,7 @@ public boolean equals(Object o) { Objects.equals(this.provider, apIInfo.provider) && Objects.equals(this.type, apIInfo.type) && Objects.equals(this.audience, apIInfo.audience) && + Objects.equals(this.audiences, apIInfo.audiences) && Objects.equals(this.lifeCycleStatus, apIInfo.lifeCycleStatus) && Objects.equals(this.workflowStatus, apIInfo.workflowStatus) && Objects.equals(this.hasThumbnail, apIInfo.hasThumbnail) && @@ -600,7 +628,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(id, name, description, context, additionalProperties, additionalPropertiesMap, version, provider, type, audience, lifeCycleStatus, workflowStatus, hasThumbnail, securityScheme, createdTime, updatedTime, gatewayVendor, advertiseOnly); + return Objects.hash(id, name, description, context, additionalProperties, additionalPropertiesMap, version, provider, type, audience, audiences, lifeCycleStatus, workflowStatus, hasThumbnail, securityScheme, createdTime, updatedTime, gatewayVendor, advertiseOnly); } @@ -618,6 +646,7 @@ public String toString() { sb.append(" provider: ").append(toIndentedString(provider)).append("\n"); sb.append(" type: ").append(toIndentedString(type)).append("\n"); sb.append(" audience: ").append(toIndentedString(audience)).append("\n"); + sb.append(" audiences: ").append(toIndentedString(audiences)).append("\n"); sb.append(" lifeCycleStatus: ").append(toIndentedString(lifeCycleStatus)).append("\n"); sb.append(" workflowStatus: ").append(toIndentedString(workflowStatus)).append("\n"); sb.append(" hasThumbnail: ").append(toIndentedString(hasThumbnail)).append("\n"); diff --git a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIProductDTO.java b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIProductDTO.java index 7e6ade971e..835fefc619 100644 --- a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIProductDTO.java +++ b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIProductDTO.java @@ -404,6 +404,10 @@ public SubscriptionAvailabilityEnum read(final JsonReader jsonReader) throws IOE @SerializedName(SERIALIZED_NAME_WORKFLOW_STATUS) private String workflowStatus; + public static final String SERIALIZED_NAME_AUDIENCES = "audiences"; + @SerializedName(SERIALIZED_NAME_AUDIENCES) + private List audiences = null; + public APIProductDTO id(String id) { @@ -1393,6 +1397,29 @@ public void setWorkflowStatus(String workflowStatus) { } + public APIProductDTO audiences(List audiences) { + + this.audiences = audiences; + return this; + } + + /** + * The audiences of the API for jwt validation. Accepted values are any String values + * @return audiences + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "The audiences of the API for jwt validation. Accepted values are any String values") + + public List getAudiences() { + return audiences; + } + + + public void setAudiences(List audiences) { + this.audiences = audiences; + } + + @Override public boolean equals(Object o) { if (this == o) { @@ -1444,12 +1471,13 @@ public boolean equals(Object o) { Objects.equals(this.apis, apIProduct.apis) && Objects.equals(this.scopes, apIProduct.scopes) && Objects.equals(this.categories, apIProduct.categories) && - Objects.equals(this.workflowStatus, apIProduct.workflowStatus); + Objects.equals(this.workflowStatus, apIProduct.workflowStatus) && + Objects.equals(this.audiences, apIProduct.audiences); } @Override public int hashCode() { - return Objects.hash(id, name, context, version, description, provider, hasThumbnail, state, enableSchemaValidation, isDefaultVersion, isRevision, revisionedApiProductId, revisionId, responseCachingEnabled, cacheTimeout, visibility, visibleRoles, visibleTenants, accessControl, accessControlRoles, apiType, transport, tags, policies, apiThrottlingPolicy, authorizationHeader, apiKeyHeader, securityScheme, subscriptionAvailability, subscriptionAvailableTenants, additionalProperties, additionalPropertiesMap, monetization, businessInformation, corsConfiguration, createdTime, lastUpdatedTimestamp, lastUpdatedTime, gatewayVendor, apis, scopes, categories, workflowStatus); + return Objects.hash(id, name, context, version, description, provider, hasThumbnail, state, enableSchemaValidation, isDefaultVersion, isRevision, revisionedApiProductId, revisionId, responseCachingEnabled, cacheTimeout, visibility, visibleRoles, visibleTenants, accessControl, accessControlRoles, apiType, transport, tags, policies, apiThrottlingPolicy, authorizationHeader, apiKeyHeader, securityScheme, subscriptionAvailability, subscriptionAvailableTenants, additionalProperties, additionalPropertiesMap, monetization, businessInformation, corsConfiguration, createdTime, lastUpdatedTimestamp, lastUpdatedTime, gatewayVendor, apis, scopes, categories, workflowStatus, audiences); } @@ -1500,6 +1528,7 @@ public String toString() { sb.append(" scopes: ").append(toIndentedString(scopes)).append("\n"); sb.append(" categories: ").append(toIndentedString(categories)).append("\n"); sb.append(" workflowStatus: ").append(toIndentedString(workflowStatus)).append("\n"); + sb.append(" audiences: ").append(toIndentedString(audiences)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIProductInfoDTO.java b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIProductInfoDTO.java index 5ed0a9fb89..6c8ac3acbf 100644 --- a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIProductInfoDTO.java +++ b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/dto/APIProductInfoDTO.java @@ -67,6 +67,10 @@ public class APIProductInfoDTO { @SerializedName(SERIALIZED_NAME_GATEWAY_VENDOR) private String gatewayVendor; + public static final String SERIALIZED_NAME_AUDIENCES = "audiences"; + @SerializedName(SERIALIZED_NAME_AUDIENCES) + private List audiences = null; + public APIProductInfoDTO id(String id) { @@ -275,6 +279,29 @@ public void setGatewayVendor(String gatewayVendor) { } + public APIProductInfoDTO audiences(List audiences) { + + this.audiences = audiences; + return this; + } + + /** + * The audiences of the API product for jwt validation. Accepted values are any String values + * @return audiences + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "The audiences of the API product for jwt validation. Accepted values are any String values") + + public List getAudiences() { + return audiences; + } + + + public void setAudiences(List audiences) { + this.audiences = audiences; + } + + @Override public boolean equals(Object o) { if (this == o) { @@ -292,12 +319,13 @@ public boolean equals(Object o) { Objects.equals(this.hasThumbnail, apIProductInfo.hasThumbnail) && Objects.equals(this.state, apIProductInfo.state) && Objects.equals(this.securityScheme, apIProductInfo.securityScheme) && - Objects.equals(this.gatewayVendor, apIProductInfo.gatewayVendor); + Objects.equals(this.gatewayVendor, apIProductInfo.gatewayVendor) && + Objects.equals(this.audiences, apIProductInfo.audiences); } @Override public int hashCode() { - return Objects.hash(id, name, context, description, provider, hasThumbnail, state, securityScheme, gatewayVendor); + return Objects.hash(id, name, context, description, provider, hasThumbnail, state, securityScheme, gatewayVendor, audiences); } @@ -314,6 +342,7 @@ public String toString() { sb.append(" state: ").append(toIndentedString(state)).append("\n"); sb.append(" securityScheme: ").append(toIndentedString(securityScheme)).append("\n"); sb.append(" gatewayVendor: ").append(toIndentedString(gatewayVendor)).append("\n"); + sb.append(" audiences: ").append(toIndentedString(audiences)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/modules/integration/tests-common/clients/publisher/src/main/resources/publisher-api.yaml b/modules/integration/tests-common/clients/publisher/src/main/resources/publisher-api.yaml index 0946d3cb45..dd8ab18773 100644 --- a/modules/integration/tests-common/clients/publisher/src/main/resources/publisher-api.yaml +++ b/modules/integration/tests-common/clients/publisher/src/main/resources/publisher-api.yaml @@ -9209,6 +9209,12 @@ components: enum: - PUBLIC - SINGLE + audiences: + type: array + description: The audiences of the API for jwt validation. Accepted values are any String values + items: + type: string + example: [ "aud1","aud2","aud3" ] lifeCycleStatus: type: string example: CREATED @@ -9403,6 +9409,12 @@ components: enum: - PUBLIC - SINGLE + audiences: + type: array + description: The audiences of the API for jwt validation. Accepted values are any String values + items: + type: string + example: [ "aud1","aud2","aud3" ] transport: type: array description: | @@ -9973,6 +9985,12 @@ components: gatewayVendor: type: string example: wso2 + audiences: + type: array + description: The audiences of the API product for jwt validation. Accepted values are any String values + items: + type: string + example: [ "aud1","aud2","aud3" ] APIProduct: title: API Product object required: @@ -10231,6 +10249,12 @@ components: workflowStatus: type: string example: APPROVED + audiences: + type: array + description: The audiences of the API for jwt validation. Accepted values are any String values + items: + type: string + example: [ "aud1","aud2","aud3" ] ProductAPI: title: ProductAPI required: diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/AudienceValidationTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/AudienceValidationTestCase.java new file mode 100644 index 0000000000..3ea82588fa --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/AudienceValidationTestCase.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2015, 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.am.integration.tests.api.lifecycle; + +import com.google.gson.Gson; +import org.apache.commons.httpclient.HttpStatus; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.wso2.am.integration.clients.publisher.api.v1.dto.APIDTO; +import org.wso2.am.integration.clients.publisher.api.v1.dto.APIOperationsDTO; +import org.wso2.am.integration.clients.store.api.v1.dto.ApplicationDTO; +import org.wso2.am.integration.clients.store.api.v1.dto.ApplicationKeyDTO; +import org.wso2.am.integration.clients.store.api.v1.dto.ApplicationKeyGenerateRequestDTO; +import org.wso2.am.integration.test.utils.base.APIMIntegrationConstants; +import org.wso2.am.integration.test.utils.bean.APIRequest; +import org.wso2.am.integration.test.utils.http.HTTPSClientUtils; +import org.wso2.am.integration.tests.restapi.RESTAPITestConstants; +import org.wso2.carbon.apimgt.api.model.APIIdentifier; +import org.wso2.carbon.automation.test.utils.http.client.HttpResponse; + +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import static org.testng.Assert.*; + +/** + * Change the Auth type of the Resource and invoke the APi + */ +public class AudienceValidationTestCase extends APIManagerLifecycleBaseTest { + + private final String API_NAME = "AudienceValidationTest"; + private final String API_CONTEXT = "AudienceValidationTest"; + private final String API_END_POINT_POSTFIX_URL = "jaxrs_basic/services/customers/customerservice/"; + private final String API_DESCRIPTION = "This is test API create by API manager integration test"; + private final String API_VERSION_1_0_0 = "1.0.0"; + private final String RESPONSE_GET = "123John"; + private final String AUTH_VALIDATION_ERROR_CODE = "900914"; + private final String API_GET_ENDPOINT_METHOD = "customers/123"; + private String APPLICATION_NAME = "AudienceValidationTest"; + private String apiId; + private String applicationId; + private String apiEndPointUrl; + private String providerName; + private String consumerKey, consumerSecret; + private HashMap requestHeadersGet; + private ArrayList grantTypes = new ArrayList<>(); + private APIIdentifier apiIdentifier; + + + @BeforeClass(alwaysRun = true) + public void initialize() throws Exception { + super.init(); + apiEndPointUrl = backEndServerUrl.getWebAppURLHttp()+ API_END_POINT_POSTFIX_URL; + providerName = user.getUserName(); + requestHeadersGet = new HashMap<>(); + requestHeadersGet.put("accept", "text/xml"); + //Create publish and subscribe a API + apiIdentifier = new APIIdentifier(providerName, API_NAME, API_VERSION_1_0_0); + + //Create application + HttpResponse applicationResponse = restAPIStore.createApplication(APPLICATION_NAME, + "Test Application", APIMIntegrationConstants.APPLICATION_TIER.DEFAULT_APP_POLICY_FIFTY_REQ_PER_MIN, + ApplicationDTO.TokenTypeEnum.JWT); + assertEquals(applicationResponse.getResponseCode(), HttpStatus.SC_OK, "Response code is not as expected"); + + applicationId = applicationResponse.getData(); + + List apiOperationsDTOS = new ArrayList<>(); + APIOperationsDTO apiOperationsDTO = new APIOperationsDTO(); + apiOperationsDTO.setVerb(RESTAPITestConstants.GET_METHOD); + apiOperationsDTO.setTarget("/*"); + apiOperationsDTOS.add(apiOperationsDTO); + + APIRequest apiRequest = new APIRequest(API_NAME, API_CONTEXT, new URL(apiEndPointUrl)); + + apiRequest.setVersion(API_VERSION_1_0_0); + apiRequest.setProvider(providerName); + apiRequest.setTiersCollection(APIMIntegrationConstants.API_TIER.UNLIMITED); + apiRequest.setTier(APIMIntegrationConstants.API_TIER.UNLIMITED); + apiRequest.setOperationsDTOS(apiOperationsDTOS); + apiRequest.setDescription(API_DESCRIPTION); + + apiId = createPublishAndSubscribeToAPIUsingRest(apiRequest, restAPIPublisher, restAPIStore, applicationId, + APIMIntegrationConstants.API_TIER.UNLIMITED); + waitForAPIDeploymentSync(apiRequest.getProvider(), apiRequest.getName(), apiRequest.getVersion(), + APIMIntegrationConstants.IS_API_EXISTS); + grantTypes.add(APIMIntegrationConstants.GRANT_TYPE.CLIENT_CREDENTIAL); + + } + + + @Test(groups = {"wso2.am"}, description = "Invoke a resource with auth type Application And Application User") + public void testInvokeApiWithoutAudienceValidation() throws Exception { + //generate keys for the subscription + ApplicationKeyDTO applicationKeyDTO = restAPIStore + .generateKeys(applicationId, "3600", "", ApplicationKeyGenerateRequestDTO.KeyTypeEnum.PRODUCTION, + null, grantTypes); + + consumerKey = applicationKeyDTO.getConsumerKey(); + consumerSecret = applicationKeyDTO.getConsumerSecret(); + assertNotNull(consumerKey, "Consumer Key not found"); + assertNotNull(consumerSecret, "Consumer Secret not found "); + + assertNotNull(applicationKeyDTO.getToken().getAccessToken()); + requestHeadersGet.put("Authorization", "Bearer " + applicationKeyDTO.getToken().getAccessToken()); + + //Send GET request + waitForAPIDeploymentSync(user.getUserName(), API_NAME, API_VERSION_1_0_0, APIMIntegrationConstants.IS_API_EXISTS); + HttpResponse httpResponseGet = + HTTPSClientUtils.doGet(getAPIInvocationURLHttp(API_CONTEXT, API_VERSION_1_0_0) + "/" + API_GET_ENDPOINT_METHOD, + requestHeadersGet); + assertEquals(httpResponseGet.getResponseCode(), HTTP_RESPONSE_CODE_OK, "Invocation fails for GET request for " + + "audience validation test when audience validation disabled"); + assertTrue(httpResponseGet.getData().contains(RESPONSE_GET), "Response Data not match for GET request for" + + " audience validation test. Expected value :\"" + RESPONSE_GET + "\" not contains" + + " in response data:\"" + httpResponseGet.getData() + "\""); + + + } + + + @Test(groups = {"wso2.am"}, description = "Invoke a resource with auth type Application", + dependsOnMethods = "testInvokeApiWithoutAudienceValidation") + public void testInvokeApiWithAudienceValidation() throws Exception { + HttpResponse getAPIResponse = restAPIPublisher.getAPI(apiId); + APIDTO apidto = new Gson().fromJson(getAPIResponse.getData(), APIDTO.class); + + List audiences = new ArrayList(); + audiences.add("Hello"); + apidto.setAudiences(audiences); + + restAPIPublisher.updateAPI(apidto); + + createAPIRevisionAndDeployUsingRest(apiId, restAPIPublisher); + waitForAPIDeployment(); + + + HttpResponse httpResponseGet = + HTTPSClientUtils.doGet(getAPIInvocationURLHttp(API_CONTEXT, API_VERSION_1_0_0) + "/" + API_GET_ENDPOINT_METHOD, + requestHeadersGet); + + assertEquals(httpResponseGet.getResponseCode(), HTTP_RESPONSE_CODE_FORBIDDEN, "Invocation fails to forbid " + + "token with invalid audience"); + assertTrue(httpResponseGet.getData().contains(AUTH_VALIDATION_ERROR_CODE), "Response do not contains expected" + + " error code :\"" + AUTH_VALIDATION_ERROR_CODE + "\". The response received : \"" + httpResponseGet.getData() + "\""); + + + audiences.add(consumerKey); + apidto.setAudiences(audiences); + + restAPIPublisher.updateAPI(apidto); + + createAPIRevisionAndDeployUsingRest(apiId, restAPIPublisher); + waitForAPIDeployment(); + + + httpResponseGet = HTTPSClientUtils.doGet(getAPIInvocationURLHttp(API_CONTEXT, API_VERSION_1_0_0) + "/" + API_GET_ENDPOINT_METHOD, + requestHeadersGet); + + assertEquals(httpResponseGet.getResponseCode(), HTTP_RESPONSE_CODE_OK, "Invocation fails for GET request for " + + "audience validation test when audience validation enabled and valid audience is passed"); + assertTrue(httpResponseGet.getData().contains(RESPONSE_GET), "Response Data not match for GET request for" + + " audience validation test. Expected value :\"" + RESPONSE_GET + "\" not contains" + + " in response data:\"" + httpResponseGet.getData() + "\""); + } + + + @AfterClass(alwaysRun = true) + public void cleanUpArtifacts() throws Exception { + restAPIStore.deleteApplication(applicationId); + undeployAndDeleteAPIRevisionsUsingRest(apiId, restAPIPublisher); + restAPIPublisher.deleteAPI(apiId); + super.cleanUp(); + } + +} 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 131a22a071..d39de60ea7 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 @@ -96,6 +96,7 @@ +