diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/API.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/API.java index c150a1847205..64da343d671f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/API.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/API.java @@ -228,6 +228,8 @@ public void setSoapToRestSequences(List soapToRestSequences) private String audience; + private Set audiences; + public String getAudience() { return audience; } @@ -236,6 +238,23 @@ public void setAudience(String audience) { this.audience = audience; } + /** + * To get the audiences for jwt validation + * + * @return audiences of the API + */ + public Set getAudiences() { + return audiences; + } + + /** + * To set the audiences for jwt validation + * + */ + public void setAudiences(Set audiences) { + this.audiences = audiences; + } + public void setEnvironmentList(Set environmentList) { this.environmentList = environmentList; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/APIProduct.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/APIProduct.java index 12a1de214316..cb8b5e4b882a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/APIProduct.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/APIProduct.java @@ -132,6 +132,11 @@ public class APIProduct implements Serializable { * Used to set the workflow status in lifecycle state change workflow */ private String workflowStatus = null; + + /** + * Used to set the audiences values in jwt audience validation + */ + private Set audiences; private Boolean isDefaultVersion = true; private boolean isPublishedDefaultVersion = false; public APIProduct(){} @@ -222,6 +227,24 @@ public void setType(String type) { this.type = type; } } + + /** + * To get the audiences for jwt validation + * + * @return audiences of the API + */ + public Set getAudiences() { + return audiences; + } + + /** + * To set the audiences for jwt validation + * + */ + public void setAudiences(Set audiences) { + this.audiences = audiences; + } + public String getBusinessOwner() { return businessOwner; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java index e68aca00112d..580248fc5c8d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java @@ -63,11 +63,14 @@ import org.wso2.carbon.metrics.manager.Timer; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; @@ -94,6 +97,7 @@ public class APIAuthenticationHandler extends AbstractHandler implements Managed private SynapseEnvironment synapseEnvironment; private String authorizationHeader; + private Set audiences = new HashSet<>();; private String apiKeyHeader; private String apiSecurity; private String apiLevelPolicy; @@ -202,6 +206,26 @@ public void setAuthorizationHeader(String authorizationHeader) { this.authorizationHeader = authorizationHeader; } + /** + * To set the audiences for api. + * + * @param audiences the audiences of the API request. + */ + public void setAudiences(String audiences) { + if (!StringUtils.isEmpty(audiences)) { + this.audiences = new HashSet<>(Arrays.asList(audiences.split(","))); + } + } + + /** + * To get the audiences of an api. + * + * @return API level audiences for JWT validation. + */ + public Set getAudiences() { + return audiences; + } + /** * To get the Api Key Header. * @@ -343,7 +367,7 @@ protected void initializeAuthenticators() { } if (isOAuthProtected) { Authenticator authenticator = new OAuthAuthenticator(authorizationHeader, isOAuthBasicAuthMandatory, - removeOAuthHeadersFromOutMessage); + removeOAuthHeadersFromOutMessage, this.getAudiences()); authenticator.init(synapseEnvironment); authenticators.add(authenticator); } @@ -689,6 +713,7 @@ private void handleAuthFailure(MessageContext messageContext, APISecurityExcepti status = HttpStatus.SC_INTERNAL_SERVER_ERROR; } else if (e.getErrorCode() == APISecurityConstants.API_AUTH_INCORRECT_API_RESOURCE || e.getErrorCode() == APISecurityConstants.API_AUTH_FORBIDDEN || + e.getErrorCode() == APISecurityConstants.API_OAUTH_INVALID_AUDIENCES || e.getErrorCode() == APISecurityConstants.INVALID_SCOPE) { status = HttpStatus.SC_FORBIDDEN; } else { diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APISecurityConstants.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APISecurityConstants.java index 026d70ec5d29..05c1fdfa5691 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APISecurityConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APISecurityConstants.java @@ -70,6 +70,9 @@ public class APISecurityConstants { public static final int API_AUTH_MISSING_OPEN_API_DEF = 900911; public static final String API_AUTH_MISSING_OPEN_API_DEF_ERROR_MESSAGE = "Internal Server Error"; + public static final int API_OAUTH_INVALID_AUDIENCES = 900912; + public static final String API_OAUTH_INVALID_AUDIENCES_MESSAGE = "The access token does not allow you to access the requested resource"; + public static final int OAUTH_TEMPORARY_SERVER_ERROR = 900424; public static final String OAUTH_TEMPORARY_SERVER_ERROR_MESSAGE = "Temporary Server Error"; @@ -112,6 +115,9 @@ public static final String getAuthenticationFailureMessage(int errorCode) { case API_AUTH_INCORRECT_ACCESS_TOKEN_TYPE: errorMessage = API_AUTH_INCORRECT_ACCESS_TOKEN_TYPE_MESSAGE; break; + case API_OAUTH_INVALID_AUDIENCES: + errorMessage = API_OAUTH_INVALID_AUDIENCES_MESSAGE; + break; case API_BLOCKED: errorMessage = API_BLOCKED_MESSAGE; break; diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java index c4f61549e559..2d905812d2f7 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java @@ -68,6 +68,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import javax.cache.Cache; @@ -82,6 +83,7 @@ public class JWTValidator { private APIKeyValidator apiKeyValidator; private boolean jwtGenerationEnabled; private AbstractAPIMgtGatewayJWTGenerator apiMgtGatewayJWTGenerator; + private Set audiences; ExtendedJWTConfigurationDto jwtConfigurationDto; JWTValidationService jwtValidationService; private static volatile long ttl = -1L; @@ -132,6 +134,12 @@ protected JWTValidator(String apiLevelPolicy, boolean isGatewayTokenCacheEnabled this.jwtValidationService = jwtValidationService; } + public JWTValidator(APIKeyValidator apiKeyValidator, String tenantDomain, Set audiences) + throws APIManagementException { + this(apiKeyValidator, tenantDomain); + this.setAudiences(audiences); + } + /** * Authenticates the given request with a JWT token to see if an API consumer is allowed to access * a particular API or not. @@ -274,6 +282,7 @@ public AuthenticationContext authenticate(SignedJWTInfo signedJWTInfo, MessageCo } // Validate scopes validateScopes(apiContext, apiVersion, matchingResource, httpMethod, jwtValidationInfo, signedJWTInfo); + validateAudiences(signedJWTInfo); synCtx.setProperty(APIMgtGatewayConstants.SCOPES, jwtValidationInfo.getScopes().toString()); synCtx.setProperty(APIMgtGatewayConstants.JWT_CLAIMS, jwtValidationInfo.getClaims()); if (apiKeyValidationInfoDTO.isAuthorized()) { @@ -347,6 +356,35 @@ private long getTtl() { } } + public Set getAudiences() { + + return audiences; + } + + public void setAudiences(Set audiences) { + + this.audiences = audiences; + } + + private boolean validateAudiences(SignedJWTInfo signedJWTInfo) throws APISecurityException { + if (this.getAudiences() == null || this.getAudiences().isEmpty() || + this.getAudiences().contains(APIConstants.ALL_AUDIENCES)) { + return true; + } + List jwtAudienceClaim = signedJWTInfo.getJwtClaimsSet().getAudience(); + if (jwtAudienceClaim == null) { + throw new APISecurityException(APISecurityConstants.API_OAUTH_INVALID_AUDIENCES, + APISecurityConstants.API_OAUTH_INVALID_AUDIENCES_MESSAGE); + } + for (String aud : this.getAudiences()) { + if (jwtAudienceClaim.contains(aud)) { + return true; + } + } + throw new APISecurityException(APISecurityConstants.API_OAUTH_INVALID_AUDIENCES, + APISecurityConstants.API_OAUTH_INVALID_AUDIENCES_MESSAGE); + } + private String generateAndRetrieveJWTToken(String tokenSignature, JWTInfoDto jwtInfoDto) throws APISecurityException { diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/oauth/OAuthAuthenticator.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/oauth/OAuthAuthenticator.java index 1ae61fd325a3..794e59c9a3d0 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/oauth/OAuthAuthenticator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/oauth/OAuthAuthenticator.java @@ -18,6 +18,8 @@ import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import org.apache.axiom.om.OMElement; +import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; @@ -27,7 +29,9 @@ import org.apache.synapse.core.SynapseEnvironment; import org.apache.synapse.core.axis2.Axis2MessageContext; import org.apache.synapse.rest.RESTConstants; +import org.wso2.carbon.apimgt.api.APIConsumer; import org.wso2.carbon.apimgt.api.APIManagementException; +import org.wso2.carbon.apimgt.api.model.ApiTypeWrapper; import org.wso2.carbon.apimgt.common.gateway.constants.GraphQLConstants; import org.wso2.carbon.apimgt.common.gateway.dto.JWTConfigurationDto; import org.wso2.carbon.apimgt.gateway.APIMgtGatewayConstants; @@ -56,6 +60,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import javax.cache.Cache; /** @@ -83,11 +88,18 @@ public class OAuthAuthenticator implements Authenticator { private boolean removeDefaultAPIHeaderFromOutMessage = true; private String requestOrigin; private boolean isMandatory; + private Set audiences; private ThreadLocal remainingAuthHeader = new ThreadLocal(); public OAuthAuthenticator() { } + public OAuthAuthenticator(String authorizationHeader, boolean isMandatory, boolean removeOAuthHeader, + Set audiences) { + this(authorizationHeader, isMandatory, removeOAuthHeader); + this.setAudiences(audiences); + } + public OAuthAuthenticator(String authorizationHeader, boolean isMandatory, boolean removeOAuthHeader) { this.securityHeader = authorizationHeader; this.removeOAuthHeadersFromOutMessage = removeOAuthHeader; @@ -118,7 +130,7 @@ public AuthenticationResponse authenticate(MessageContext synCtx) throws APIMana } if (jwtValidator == null) { - this.jwtValidator = new JWTValidator(this.keyValidator, tenantDomain); + this.jwtValidator = new JWTValidator(this.keyValidator, tenantDomain, this.getAudiences()); } config = getApiManagerConfiguration(); @@ -471,6 +483,14 @@ private void setSecurityContextHeader(String securityContextHeader) { this.securityContextHeader = securityContextHeader; } + public void setAudiences(Set audiences) { + this.audiences = audiences; + } + + public Set getAudiences() { + return audiences; + } + private boolean isRemoveOAuthHeadersFromOutMessage() { String value = config.getFirstProperty(APIConstants.REMOVE_OAUTH_HEADERS_FROM_MESSAGE); if (value != null) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index 751505c534b0..e0080a0b8097 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -846,6 +846,8 @@ private Permissions() { public static final String JWT_AUDIENCES = "JWTAudiences"; public static final String JWT_AUDIENCE = "JWTAudience"; public static final String AUDIENCE = "Audience"; + public static final String AUDIENCES = "Audiences"; + public static final String ALL_AUDIENCES = "all"; public static final String BASEPATH = "Basepath"; public static final String URN_CHOREO = "urn:choreo:"; public static final String BASE_PATH = "http.base.path"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java index b02add88cf68..16b8317a0bb9 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java @@ -54,6 +54,7 @@ public final class APIConstants { public static final String API_OVERVIEW_VISIBLE_TENANTS = "overview_visibleTenants"; public static final String API_OVERVIEW_ENVIRONMENTS = "overview_environments"; public static final String API_OVERVIEW_AUDIENCE = "overview_audience"; + public static final String API_OVERVIEW_AUDIENCES = "overview_audiences"; public static final String API_PROVIDER = "Provider"; public static final String API_NAME = "Name"; public static final String API_VERSION_LABEL = "Version"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 9fc4d90ddfca..2ab28ea4ccc4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -15,6 +15,7 @@ */ package org.wso2.carbon.apimgt.persistence; +import com.google.gson.Gson; import org.apache.axiom.om.OMAttribute; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.util.AXIOMUtil; @@ -1003,6 +1004,10 @@ private PublisherAPISearchResult searchPaginatedPublisherAPIs(Registry userRegis apiInfo.setThumbnail(artifact.getAttribute(APIConstants.API_OVERVIEW_THUMBNAIL_URL)); apiInfo.setVersion(artifact.getAttribute(APIConstants.API_OVERVIEW_VERSION)); apiInfo.setAudience(artifact.getAttribute(APIConstants.API_OVERVIEW_AUDIENCE)); + String audiences = artifact.getAttribute(APIConstants.API_OVERVIEW_AUDIENCES); + if (StringUtils.isNotEmpty(audiences)) { + apiInfo.setAudiences(new Gson().fromJson(audiences, Set.class)); + } apiInfo.setCreatedTime(String.valueOf(apiResource.getCreatedTime().getTime())); apiInfo.setUpdatedTime(apiResource.getLastModified()); apiInfo.setUpdatedBy(apiResource.getLastUpdaterUserName()); @@ -3379,6 +3384,10 @@ public PublisherAPIProductSearchResult searchAPIProductsForPublisher(Organizatio info.setVersion(artifact.getAttribute(APIConstants.API_OVERVIEW_VERSION)); info.setApiSecurity(artifact.getAttribute(APIConstants.API_OVERVIEW_API_SECURITY)); info.setThumbnail(artifact.getAttribute(APIConstants.API_OVERVIEW_THUMBNAIL_URL)); + String audiences = artifact.getAttribute(APIConstants.API_OVERVIEW_AUDIENCES); + if (StringUtils.isNotEmpty(audiences)) { + info.setAudiences(new Gson().fromJson(audiences, Set.class)); + } info.setBusinessOwner(artifact.getAttribute(APIConstants.API_OVERVIEW_BUSS_OWNER)); info.setBusinessOwnerEmail(artifact.getAttribute(APIConstants.API_OVERVIEW_BUSS_OWNER_EMAIL)); info.setTechnicalOwner(artifact.getAttribute(APIConstants.API_OVERVIEW_TEC_OWNER)); diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPI.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPI.java index 0480be1104f3..03dfda3dc5cb 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPI.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPI.java @@ -95,6 +95,7 @@ public class PublisherAPI extends PublisherAPIInfo { private String versionTimestamp; private String audience; + private Set audiences; private String apiExternalProductionEndpoint; private String apiExternalSandboxEndpoint; private String redirectURL; @@ -109,6 +110,14 @@ public void setAudience(String audience) { this.audience = audience; } + public Set getAudiences() { + return audiences; + } + + public void setAudiences(Set audiences) { + this.audiences = audiences; + } + public List getSoapToRestSequences() { return soapToRestSequences; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIInfo.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIInfo.java index 19fffb092585..e6944f1c9e45 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIInfo.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIInfo.java @@ -20,6 +20,7 @@ import java.util.Date; import java.util.Map; +import java.util.Set; /** * A subset of org.wso2.carbon.apimgt.persistence.models.PublisherAPI. Minimal API information required only for @@ -38,6 +39,7 @@ public class PublisherAPIInfo { private String createdTime; private Date updatedTime; private String audience; + private Set audiences; private Map additionalProperties; private String description; private String gatewayVendor; @@ -57,6 +59,14 @@ public void setAudience(String audience) { this.audience = audience; } + public Set getAudiences() { + return audiences; + } + + public void setAudiences(Set audiences) { + this.audiences = audiences; + } + public String getApiName() { return apiName; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIProduct.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIProduct.java index b3abb97607c9..87128075b706 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIProduct.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIProduct.java @@ -65,7 +65,14 @@ public class PublisherAPIProduct extends PublisherAPIProductInfo { private String gatewayVendor; private String versionTimestamp; + private Set audiences; + public Set getAudiences() { + return audiences; + } + public void setAudiences(Set audiences) { + this.audiences = audiences; + } public String getDescription() { return description; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIProductInfo.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIProductInfo.java index cb139b2d6078..080b622b6f3c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIProductInfo.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/PublisherAPIProductInfo.java @@ -18,6 +18,8 @@ package org.wso2.carbon.apimgt.persistence.dto; +import java.util.Set; + /** * A subset of org.wso2.carbon.apimgt.persistence.models.PublisherAPIProduct. Minimal API information required only for * listing API Products in publisher which are stored in the @@ -38,6 +40,14 @@ public class PublisherAPIProductInfo { private String technicalOwner; private String technicalOwnerEmail; private Boolean isMonetizationEnabled; + private Set audiences; + + public Set getAudiences() { + return audiences; + } + public void setAudiences(Set audiences) { + this.audiences = audiences; + } public String getThumbnail() { return thumbnail; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java index 2abad846ff43..c3098860740b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java @@ -296,6 +296,8 @@ public static GenericArtifact createAPIArtifactContent(GenericArtifact artifact, artifact.setAttribute(APIConstants.ASYNC_API_TRANSPORT_PROTOCOLS, api.getAsyncTransportProtocols()); artifact.setAttribute(APIConstants.API_OVERVIEW_AUDIENCE, api.getAudience()); + //set audiences for jwt audience validation + artifact.setAttribute(APIConstants.API_OVERVIEW_AUDIENCES, new Gson().toJson(api.getAudiences())); } catch (GovernanceException e) { String msg = "Failed to create API for : " + api.getId().getApiName(); @@ -700,6 +702,10 @@ public static API getAPI(GovernanceArtifact artifact, Registry registry) String monetizationInfo = artifact.getAttribute(APIConstants.Monetization.API_MONETIZATION_PROPERTIES); api.setWsUriMapping(getWsUriMappingFromArtifact(artifact)); + String audiences = artifact.getAttribute(APIConstants.API_OVERVIEW_AUDIENCES); + if (StringUtils.isNotEmpty(audiences)) { + api.setAudiences(new Gson().fromJson(audiences, Set.class)); + } api.setAudience(artifact.getAttribute(APIConstants.API_OVERVIEW_AUDIENCE)); api.setVersionTimestamp(artifact.getAttribute(APIConstants.API_OVERVIEW_VERSION_COMPARABLE)); @@ -1473,6 +1479,7 @@ public static GenericArtifact createAPIProductArtifactContent(GenericArtifact ar artifact.setAttribute(APIConstants.API_OVERVIEW_THUMBNAIL_URL, apiProduct.getThumbnailUrl()); artifact.setAttribute( APIConstants.API_OVERVIEW_CACHE_TIMEOUT, Integer.toString(apiProduct.getCacheTimeout())); + artifact.setAttribute(APIConstants.API_OVERVIEW_AUDIENCES, new Gson().toJson(apiProduct.getAudiences())); StringBuilder policyBuilder = new StringBuilder(); for (Tier tier : apiProduct.getAvailableTiers()) { @@ -1603,6 +1610,10 @@ public static APIProduct getAPIProduct(GovernanceArtifact artifact, Registry reg apiProduct.setGatewayVendor(artifact.getAttribute(APIConstants.API_OVERVIEW_GATEWAY_VENDOR)); String tenantDomainName = MultitenantUtils.getTenantDomain(replaceEmailDomainBack(providerName)); apiProduct.setTenantDomain(tenantDomainName); + String audiences = artifact.getAttribute(APIConstants.API_OVERVIEW_AUDIENCES); + if (StringUtils.isNotEmpty(audiences)) { + apiProduct.setAudiences(new Gson().fromJson(audiences, Set.class)); + } int tenantId = ServiceReferenceHolder.getInstance().getRealmService().getTenantManager() .getTenantId(tenantDomainName); diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/test/java/org/wso2/carbon/apimgt/persistence/utils/PersistenceHelper.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/test/java/org/wso2/carbon/apimgt/persistence/utils/PersistenceHelper.java index eba72c2af75d..96b83def893f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/test/java/org/wso2/carbon/apimgt/persistence/utils/PersistenceHelper.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/test/java/org/wso2/carbon/apimgt/persistence/utils/PersistenceHelper.java @@ -113,6 +113,7 @@ public static GenericArtifact getSampleAPIArtifact() throws GovernanceException artifact.setAttribute("overview_status", "PUBLISHED"); artifact.setId("88e758b7-6924-4e9f-8882-431070b6492b"); artifact.setAttribute("overview_audience", "PUBLIC"); + artifact.setAttribute("overview_audiences", null); return artifact; } @@ -247,6 +248,7 @@ public static GenericArtifact getSampleAPIProductArtifact() throws GovernanceExc artifact.setAttribute("overview_enableStore","true"); artifact.setAttribute("overview_enableSchemaValidation","false"); artifact.setId("88e758b7-6924-4e9f-8882-431070b6492b"); + artifact.setAttribute("overview_audiences", null); return artifact; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIDTO.java index 752593d3a3e4..a4c9d314a950 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIDTO.java @@ -133,6 +133,7 @@ public static AudienceEnum fromValue(String v) { } } private AudienceEnum audience = null; + private List audiences = new ArrayList(); private List transport = new ArrayList(); @Scope(name = "apim:api_publish", description="", value ="") @Scope(name = "apim:api_manage", description="", value ="") @@ -670,6 +671,24 @@ public void setAudience(AudienceEnum audience) { this.audience = audience; } + /** + * The audiences of the API for jwt validation. Accepted values are any String values + **/ + public APIDTO audiences(List audiences) { + this.audiences = audiences; + return this; + } + + + @ApiModelProperty(value = "The audiences of the API for jwt validation. Accepted values are any String values") + @JsonProperty("audiences") + public List getAudiences() { + return audiences; + } + public void setAudiences(List audiences) { + this.audiences = audiences; + } + /** * Supported transports for the API (http and/or https). **/ @@ -1395,6 +1414,7 @@ public boolean equals(java.lang.Object o) { Objects.equals(enableSubscriberVerification, API.enableSubscriberVerification) && Objects.equals(type, API.type) && Objects.equals(audience, API.audience) && + Objects.equals(audiences, API.audiences) && Objects.equals(transport, API.transport) && Objects.equals(tags, API.tags) && Objects.equals(policies, API.policies) && @@ -1438,7 +1458,7 @@ public boolean equals(java.lang.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); } @Override @@ -1466,6 +1486,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/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIInfoDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIInfoDTO.java index 23431b512759..279a90ce2844 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIInfoDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIInfoDTO.java @@ -67,6 +67,7 @@ public static AudienceEnum fromValue(String v) { } } private AudienceEnum audience = null; + private List audiences = new ArrayList(); private String lifeCycleStatus = null; private String workflowStatus = null; private Boolean hasThumbnail = null; @@ -258,6 +259,24 @@ public void setAudience(AudienceEnum audience) { this.audience = audience; } + /** + * The audiences of the API for jwt validation. Accepted values are any String values + **/ + public APIInfoDTO audiences(List audiences) { + this.audiences = audiences; + return this; + } + + + @ApiModelProperty(value = "The audiences of the API for jwt validation. Accepted values are any String values") + @JsonProperty("audiences") + public List getAudiences() { + return audiences; + } + public void setAudiences(List audiences) { + this.audiences = audiences; + } + /** **/ public APIInfoDTO lifeCycleStatus(String lifeCycleStatus) { @@ -534,6 +553,7 @@ public boolean equals(java.lang.Object o) { Objects.equals(provider, apIInfo.provider) && Objects.equals(type, apIInfo.type) && Objects.equals(audience, apIInfo.audience) && + Objects.equals(audiences, apIInfo.audiences) && Objects.equals(lifeCycleStatus, apIInfo.lifeCycleStatus) && Objects.equals(workflowStatus, apIInfo.workflowStatus) && Objects.equals(hasThumbnail, apIInfo.hasThumbnail) && @@ -553,7 +573,7 @@ public boolean equals(java.lang.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, updatedBy, gatewayVendor, gatewayType, advertiseOnly, monetizedInfo, businessOwner, businessOwnerEmail, technicalOwner, technicalOwnerEmail); + return Objects.hash(id, name, description, context, additionalProperties, additionalPropertiesMap, version, provider, type, audience, audiences, lifeCycleStatus, workflowStatus, hasThumbnail, securityScheme, createdTime, updatedTime, updatedBy, gatewayVendor, gatewayType, advertiseOnly, monetizedInfo, businessOwner, businessOwnerEmail, technicalOwner, technicalOwnerEmail); } @Override @@ -571,6 +591,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/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIProductDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIProductDTO.java index 7c6ce8915944..bd5fcd20caf0 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIProductDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIProductDTO.java @@ -202,6 +202,7 @@ public static SubscriptionAvailabilityEnum fromValue(String v) { private List scopes = new ArrayList(); private List categories = new ArrayList(); private String workflowStatus = null; + private List audiences = new ArrayList(); /** * UUID of the api product @@ -962,6 +963,24 @@ public void setWorkflowStatus(String workflowStatus) { this.workflowStatus = workflowStatus; } + /** + * The audiences of the API for jwt validation. Accepted values are any String values + **/ + public APIProductDTO audiences(List audiences) { + this.audiences = audiences; + return this; + } + + + @ApiModelProperty(value = "The audiences of the API for jwt validation. Accepted values are any String values") + @JsonProperty("audiences") + public List getAudiences() { + return audiences; + } + public void setAudiences(List audiences) { + this.audiences = audiences; + } + @Override public boolean equals(java.lang.Object o) { @@ -1014,12 +1033,13 @@ public boolean equals(java.lang.Object o) { Objects.equals(apis, apIProduct.apis) && Objects.equals(scopes, apIProduct.scopes) && Objects.equals(categories, apIProduct.categories) && - Objects.equals(workflowStatus, apIProduct.workflowStatus); + Objects.equals(workflowStatus, apIProduct.workflowStatus) && + Objects.equals(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, lastUpdatedTime, lastUpdatedTimestamp, 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, lastUpdatedTime, lastUpdatedTimestamp, gatewayVendor, apis, scopes, categories, workflowStatus, audiences); } @Override @@ -1070,6 +1090,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/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIProductInfoDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIProductInfoDTO.java index e2c46f41ef95..ae77fb1424ad 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIProductInfoDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/APIProductInfoDTO.java @@ -32,6 +32,7 @@ public class APIProductInfoDTO { private String state = null; private List securityScheme = new ArrayList(); private String gatewayVendor = null; + private List audiences = new ArrayList(); private Boolean monetizedInfo = null; private String businessOwner = null; private String businessOwnerEmail = null; @@ -214,6 +215,24 @@ public void setGatewayVendor(String gatewayVendor) { this.gatewayVendor = gatewayVendor; } + /** + * The audiences of the API product for jwt validation. Accepted values are any String values + **/ + public APIProductInfoDTO audiences(List audiences) { + this.audiences = audiences; + return this; + } + + + @ApiModelProperty(value = "The audiences of the API product for jwt validation. Accepted values are any String values") + @JsonProperty("audiences") + public List getAudiences() { + return audiences; + } + public void setAudiences(List audiences) { + this.audiences = audiences; + } + /** **/ public APIProductInfoDTO monetizedInfo(Boolean monetizedInfo) { @@ -319,6 +338,7 @@ public boolean equals(java.lang.Object o) { Objects.equals(state, apIProductInfo.state) && Objects.equals(securityScheme, apIProductInfo.securityScheme) && Objects.equals(gatewayVendor, apIProductInfo.gatewayVendor) && + Objects.equals(audiences, apIProductInfo.audiences) && Objects.equals(monetizedInfo, apIProductInfo.monetizedInfo) && Objects.equals(businessOwner, apIProductInfo.businessOwner) && Objects.equals(businessOwnerEmail, apIProductInfo.businessOwnerEmail) && @@ -328,7 +348,7 @@ public boolean equals(java.lang.Object o) { @Override public int hashCode() { - return Objects.hash(id, name, context, description, provider, version, hasThumbnail, state, securityScheme, gatewayVendor, monetizedInfo, businessOwner, businessOwnerEmail, technicalOwner, technicalOwnerEmail); + return Objects.hash(id, name, context, description, provider, version, hasThumbnail, state, securityScheme, gatewayVendor, audiences, monetizedInfo, businessOwner, businessOwnerEmail, technicalOwner, technicalOwnerEmail); } @Override @@ -346,6 +366,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(" monetizedInfo: ").append(toIndentedString(monetizedInfo)).append("\n"); sb.append(" businessOwner: ").append(toIndentedString(businessOwner)).append("\n"); sb.append(" businessOwnerEmail: ").append(toIndentedString(businessOwnerEmail)).append("\n"); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java index a89467883bb1..2c48d8a977f5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java @@ -199,6 +199,14 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(API api, String tenan } String apiSecurity = api.getApiSecurity(); String apiLevelPolicy = api.getApiLevelPolicy(); + String audiences; + Set audienceList = api.getAudiences(); + if (audienceList != null) { + audiences = String.join(",", audienceList); + } else { + audiences = ""; + } + authProperties.put(APIConstants.AUDIENCES, audiences); authProperties.put(APIConstants.API_SECURITY, apiSecurity); authProperties.put(APIConstants.API_LEVEL_POLICY, apiLevelPolicy); if (clientCertificateObject != null) { @@ -386,6 +394,14 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(APIProduct apiProduct String apiLevelPolicy = apiProduct.getProductLevelPolicy(); authProperties.put(APIConstants.API_SECURITY, apiSecurity); authProperties.put(APIConstants.API_LEVEL_POLICY, apiLevelPolicy); + String audiences; + Set audienceList = apiProduct.getAudiences(); + if (audienceList != null) { + audiences = String.join(",", audienceList); + } else { + audiences = ""; + } + authProperties.put(APIConstants.AUDIENCES, audiences); if (clientCertificateObject != null) { authProperties.put(APIConstants.CERTIFICATE_INFORMATION, clientCertificateObject.toString()); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIMappingUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIMappingUtil.java index 27dde7db95c3..11379c0cadd1 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIMappingUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIMappingUtil.java @@ -441,6 +441,13 @@ public static API fromDTOtoAPI(APIDTO dto, String provider) throws APIManagement if (dto.getAudience() != null) { model.setAudience(dto.getAudience().toString()); } + if (dto.getAudiences() != null) { + List audiences = dto.getAudiences(); + if (audiences.isEmpty()) { + audiences.add(APIConstants.ALL_AUDIENCES); + } + model.setAudiences(new HashSet<>(audiences)); + } if (dto.getGatewayVendor() != null) { model.setGatewayVendor(dto.getGatewayVendor()); } @@ -675,6 +682,13 @@ public static APIInfoDTO fromAPIToInfoDTO(API api) { apiInfoDTO.setAudience(org.wso2.carbon.apimgt.rest.api.publisher.v1.dto.APIInfoDTO.AudienceEnum .valueOf(api.getAudience())); } + if (api.getAudiences() != null) { + Set audiences = api.getAudiences(); + if (audiences.contains(APIConstants.ALL_AUDIENCES) && audiences.size() > 1) { + audiences.remove(APIConstants.ALL_AUDIENCES); + } + apiInfoDTO.setAudiences(new ArrayList<>(audiences)); + } if (api.getCreatedTime() != null) { Date createdTime = new Date(Long.parseLong(api.getCreatedTime())); apiInfoDTO.setCreatedTime(String.valueOf(createdTime.getTime())); @@ -1393,6 +1407,14 @@ public static APIDTO fromAPItoDTO(API model, boolean preserveCredentials, dto.setAudience(AudienceEnum.valueOf(model.getAudience())); } + if (model.getAudiences() != null) { + Set audiences = model.getAudiences(); + if (audiences.contains(APIConstants.ALL_AUDIENCES) && audiences.size() > 1) { + audiences.remove(APIConstants.ALL_AUDIENCES); + } + dto.setAudiences(new ArrayList<>(model.getAudiences())); + } + String gatewayVendor = StringUtils.toRootLowerCase(model.getGatewayVendor()); dto.setGatewayVendor(gatewayVendor); dto.setGatewayType(model.getGatewayType()); @@ -2300,6 +2322,9 @@ public static APIProductListDTO fromAPIProductListtoDTO(List product if (apiProduct.getApiSecurity() != null) { productDto.setSecurityScheme(Arrays.asList(apiProduct.getApiSecurity().split(","))); } + if (apiProduct.getAudiences() != null) { + productDto.setAudiences(new ArrayList<>(apiProduct.getAudiences())); + } productDto.setBusinessOwner(apiProduct.getBusinessOwner()); productDto.setBusinessOwnerEmail(apiProduct.getBusinessOwnerEmail()); productDto.setTechnicalOwner(apiProduct.getTechnicalOwner()); @@ -2350,6 +2375,14 @@ public static APIProductDTO fromAPIProducttoDTO(APIProduct product) throws APIMa productDto.setRevisionedApiProductId(product.getRevisionedApiProductId()); productDto.setRevisionId(product.getRevisionId()); + if (product.getAudiences() != null) { + Set audiences = product.getAudiences(); + if (audiences.contains(APIConstants.ALL_AUDIENCES) && audiences.size() > 1) { + audiences.remove(APIConstants.ALL_AUDIENCES); + } + productDto.setAudiences(new ArrayList<>(product.getAudiences())); + } + if (APIConstants.ENABLED.equals(product.getResponseCache())) { productDto.setResponseCachingEnabled(Boolean.TRUE); } else { @@ -2612,6 +2645,14 @@ public static APIProduct fromDTOtoAPIProduct(APIProductDTO dto, String provider) product.setTechnicalOwnerEmail(dto.getBusinessInformation().getTechnicalOwnerEmail()); } + if (dto.getAudiences() != null) { + List audiences = dto.getAudiences(); + if (audiences.isEmpty()) { + audiences.add(APIConstants.ALL_AUDIENCES); + } + product.setAudiences(new HashSet<>(audiences)); + } + Set apiTiers = new HashSet<>(); List tiersFromDTO = dto.getPolicies(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml index 747da722370d..5fd5d9caf205 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml @@ -8843,6 +8843,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 @@ -9060,6 +9066,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: | @@ -9652,6 +9664,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" ] monetizedInfo: type: boolean example: true @@ -9925,6 +9943,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: