From 40a5b00f80200fa894f56246e922922f0830e4a1 Mon Sep 17 00:00:00 2001 From: Rajitha Kumara Date: Wed, 23 Oct 2024 18:06:02 +0530 Subject: [PATCH] Add improvements to api application registation logic --- ...ApiApplicationRegistrationServiceImpl.java | 107 +-- .../api/common/GsonMessageBodyHandler.java | 96 ++ .../src/main/webapp/WEB-INF/cxf-servlet.xml | 4 +- .../src/main/webapp/WEB-INF/web.xml | 20 +- .../pom.xml | 13 +- .../APIManagementProviderService.java | 54 +- .../APIManagementProviderServiceImpl.java | 537 +++++------- .../extension/bean/ApiApplicationProfile.java | 68 ++ .../bean/IdnAuthenticationProfile.java | 58 ++ .../application/extension/bean/Token.java | 68 ++ .../extension/bean/TokenCreationProfile.java | 104 +++ .../extension/dto/ApiApplicationKey.java | 32 +- .../exception/IdnAuthenticationException.java | 26 + ...ApplicationManagerExtensionDataHolder.java | 13 + ...ationManagerExtensionServiceComponent.java | 31 + .../rest/api/ConsumerRESTAPIServices.java | 39 +- .../rest/api/ConsumerRESTAPIServicesImpl.java | 508 +++-------- .../rest/api/IOAuthClientService.java | 51 ++ .../extension/rest/api/OAuthClient.java | 471 ++++++++++ .../rest/api/PublisherRESTAPIServices.java | 78 +- .../api/PublisherRESTAPIServicesImpl.java | 829 ++++-------------- .../rest/api/bean/APIMConsumer/APIInfo.java | 15 + .../api/bean/APIMConsumer/Subscription.java | 16 + .../rest/api/bean/OAuthClientResponse.java | 44 + .../rest/api/constants/Constants.java | 2 + .../api/exceptions/OAuthClientException.java | 30 + .../internal/APIManagerServiceComponent.java | 6 + .../internal/APIManagerServiceDataHolder.java | 15 +- .../extension/service/KeyMgtServiceImpl.java | 2 +- .../publisher/APIPublisherServiceImpl.java | 166 +--- .../publisher/APIPublisherStartupHandler.java | 34 + components/apimgt-extensions/pom.xml | 4 +- .../application/mgt/core/util/OAuthUtils.java | 28 +- .../impl/DeviceManagementServiceImpl.java | 101 +-- .../core/internal/TenantCreateObserver.java | 54 +- .../api/_API_Application_Registration_.xml | 19 - features/apimgt-extensions/pom.xml | 2 +- 37 files changed, 1996 insertions(+), 1749 deletions(-) create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/api/common/GsonMessageBodyHandler.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/ApiApplicationProfile.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/IdnAuthenticationProfile.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/Token.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/TokenCreationProfile.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/exception/IdnAuthenticationException.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/IOAuthClientService.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/OAuthClient.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/OAuthClientResponse.java create mode 100644 components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/exceptions/OAuthClientException.java diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java index 2dd6e523f0..0e9ee26123 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java @@ -21,9 +21,13 @@ package io.entgra.device.mgt.core.apimgt.application.extension.api; import io.entgra.device.mgt.core.apimgt.application.extension.APIManagementProviderService; import io.entgra.device.mgt.core.apimgt.application.extension.api.util.APIUtil; import io.entgra.device.mgt.core.apimgt.application.extension.api.util.RegistrationProfile; -import io.entgra.device.mgt.core.apimgt.application.extension.constants.ApiApplicationConstants; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.ApiApplicationProfile; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.IdnAuthenticationProfile; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; +import io.entgra.device.mgt.core.apimgt.application.extension.exception.IdnAuthenticationException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -37,6 +41,7 @@ import javax.ws.rs.Path; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.util.Arrays; +import java.util.HashSet; public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegistrationService { @@ -57,15 +62,27 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi String msg = "Invalid tenant domain : " + tenantDomain; return Response.status(Response.Status.NOT_ACCEPTABLE).entity(msg).build(); } + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() .getRealmConfiguration().getAdminUserName(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username); + String password = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminPassword(); + + IdnAuthenticationProfile idnAuthenticationProfile = new IdnAuthenticationProfile(); + idnAuthenticationProfile.setUsername(username); + idnAuthenticationProfile.setPassword(password); + + ApiApplicationProfile apiApplicationProfile = new ApiApplicationProfile(); + apiApplicationProfile.setApplicationName(applicationName); + apiApplicationProfile.setTags(APIUtil.getDefaultTags()); + apiApplicationProfile.setGrantTypes(""); + + APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); - ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( - applicationName, APIUtil.getDefaultTags(), - ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, false, - ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD, PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminPassword(), null, null, null, false); + ApiApplicationKey apiApplicationKey = + apiManagementProviderService.registerApiApplication(idnAuthenticationProfile, + apiApplicationProfile); return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build(); } catch (APIManagerException e) { String msg = "Error occurred while registering an application '" + applicationName + "'"; @@ -79,6 +96,10 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi String msg = "Failed to retrieve the device service"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (IdnAuthenticationException | BadRequestException | UnexpectedResponseException e) { + String msg = "Error encountered while registering api application"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } finally { PrivilegedCarbonContext.endTenantFlow(); } @@ -89,61 +110,49 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi public Response register(RegistrationProfile registrationProfile) { try { if ((registrationProfile.getTags() != null && registrationProfile.getTags().length != 0)) { - if (!APIUtil.getAllowedApisTags().containsAll(Arrays.asList(registrationProfile.getTags()))) { - return Response.status(Response.Status.NOT_ACCEPTABLE).entity("APIs(Tags) are not allowed to this user." + if (!new HashSet<>(APIUtil.getAllowedApisTags()).containsAll(Arrays.asList(registrationProfile.getTags()))) { + return Response.status(Response.Status.NOT_ACCEPTABLE).entity("APIs(Tags) are not allowed to this" + + " user." ).build(); } } - String username = APIUtil.getAuthenticatedUser(); - APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); - String validityPeriod; - if (registrationProfile.getValidityPeriod() == null) { - validityPeriod = ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD; - } else { - validityPeriod = registrationProfile.getValidityPeriod(); - } - String applicationName = registrationProfile.getApplicationName(); + IdnAuthenticationProfile idnAuthenticationProfile = new IdnAuthenticationProfile(); + idnAuthenticationProfile.setUsername(registrationProfile.getUsername()); + idnAuthenticationProfile.setPassword(registrationProfile.getPassword()); - if (username.equals(registrationProfile.getUsername())) { - synchronized (ApiApplicationRegistrationServiceImpl.class) { - ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( - applicationName, registrationProfile.getTags(), - ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, - registrationProfile.isAllowedToAllDomains(), validityPeriod, - registrationProfile.getPassword(), null, registrationProfile.getSupportedGrantTypes(), - registrationProfile.getCallbackUrl(), false); - return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build(); - } - } - - PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(PrivilegedCarbonContext. - getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration().getAdminUserName()); + ApiApplicationProfile apiApplicationProfile = new ApiApplicationProfile(); + apiApplicationProfile.setApplicationName(registrationProfile.getApplicationName()); + apiApplicationProfile.setTags(registrationProfile.getTags()); + apiApplicationProfile.setCallbackUrl(registrationProfile.getCallbackUrl()); + apiApplicationProfile.setGrantTypes(String.join(" ", registrationProfile.getSupportedGrantTypes())); - synchronized (ApiApplicationRegistrationServiceImpl.class) { - ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( - applicationName, registrationProfile.getTags(), - ApiApplicationConstants.DEFAULT_TOKEN_TYPE, registrationProfile.getUsername(), - registrationProfile.isAllowedToAllDomains(), validityPeriod, - registrationProfile.getPassword(), null, registrationProfile.getSupportedGrantTypes(), - registrationProfile.getCallbackUrl(), false); - return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build(); - } - } catch (APIManagerException e) { - String msg = "Error occurred while registering an application with apis '" - + StringUtils.join(registrationProfile.getTags(), ",") + "'"; + ApiApplicationKey apiApplicationKey = + apiManagementProviderService.registerApiApplication(idnAuthenticationProfile, + apiApplicationProfile); + return Response.status(Response.Status.CREATED).entity(apiApplicationKey).build(); + } catch (IdnAuthenticationException e) { + String msg = "Failed to authenticate the user " + registrationProfile.getUsername(); log.error(msg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("false").build(); - } catch (DeviceManagementException e) { - String msg = "Failed to retrieve the device service"; + return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build(); + } catch (BadRequestException e) { + String msg = + "Received bad request for registering api application " + registrationProfile.getApplicationName(); + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (UnexpectedResponseException e) { + String msg = + "Received unexpected response when registering the api application " + registrationProfile.getApplicationName(); log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } catch (UserStoreException e) { - String msg = "Failed to access user space."; + } catch (DeviceManagementException | APIManagerException e) { + String msg = + "Error occurred while registering an application " + registrationProfile.getApplicationName() + + " with apis '" + + StringUtils.join(registrationProfile.getTags(), ",") + "'"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } } - } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/api/common/GsonMessageBodyHandler.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/api/common/GsonMessageBodyHandler.java new file mode 100644 index 0000000000..1a5ff6bc18 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/api/common/GsonMessageBodyHandler.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.application.extension.api.common; + + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +@Provider +@Produces(APPLICATION_JSON) +@Consumes(APPLICATION_JSON) +public class GsonMessageBodyHandler implements MessageBodyWriter, MessageBodyReader { + + private Gson gson; + private static final String UTF_8 = "UTF-8"; + + public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + private Gson getGson() { + if (gson == null) { + final GsonBuilder gsonBuilder = new GsonBuilder(); + gson = gsonBuilder.create(); + } + return gson; + } + + public Object readFrom(Class objectClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringStringMultivaluedMap, InputStream entityStream) + throws IOException, WebApplicationException { + + InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8"); + + try { + return getGson().fromJson(reader, type); + } finally { + reader.close(); + } + } + + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + public long getSize(Object o, Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + public void writeTo(Object object, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringObjectMultivaluedMap, OutputStream entityStream) + throws IOException, WebApplicationException { + + OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8); + try { + getGson().toJson(object, type, writer); + } finally { + writer.close(); + } + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 7f844d0445..aef39a63d1 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -31,9 +31,11 @@ - + + + diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/webapp/WEB-INF/web.xml b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/webapp/WEB-INF/web.xml index 3d13c6bcf3..13202982cc 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/webapp/WEB-INF/web.xml +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.api/src/main/webapp/WEB-INF/web.xml @@ -37,12 +37,12 @@ doAuthentication - true + false basicAuth - true + false @@ -59,10 +59,10 @@ false - - ApiPermissionFilter - io.entgra.device.mgt.core.apimgt.application.extension.api.filter.ApiPermissionFilter - + + + + HttpHeaderSecurityFilter @@ -100,9 +100,9 @@ /* - - ApiPermissionFilter - /* - + + + + diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/pom.xml b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/pom.xml index 4e86ea95a3..cde28e6b79 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/pom.xml +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/pom.xml @@ -46,6 +46,12 @@ org.wso2.carbon org.wso2.carbon.core + + + com.google.code.gson + gson + + org.wso2.carbon @@ -88,7 +94,11 @@ io.entgra.device.mgt.core.device.mgt.common - + + com.google.code.gson + gson + provided + @@ -122,6 +132,7 @@ API Management Application Bundle io.entgra.device.mgt.core.apimgt.application.extension.internal + com.google.gson.*;version="${google.gson.version}", io.entgra.device.mgt.core.apimgt.application.extension.bean, io.entgra.device.mgt.core.apimgt.application.extension.dto, io.entgra.device.mgt.core.apimgt.application.extension.exception, diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/APIManagementProviderService.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/APIManagementProviderService.java index 589923a920..e4114b0c4c 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/APIManagementProviderService.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/APIManagementProviderService.java @@ -18,46 +18,48 @@ package io.entgra.device.mgt.core.apimgt.application.extension; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.ApiApplicationProfile; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.IdnAuthenticationProfile; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.Token; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.TokenCreationProfile; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; -import io.entgra.device.mgt.core.identity.jwt.client.extension.dto.AccessTokenInfo; - -import java.util.ArrayList; +import io.entgra.device.mgt.core.apimgt.application.extension.exception.IdnAuthenticationException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; /** - * This comprise on operation that is been done with api manager from CDMF. This service needs to be implemented in APIM. + * This comprise on operation that is been done with api manager from CDMF. This service needs to be implemented in + * APIM. */ public interface APIManagementProviderService { /** * Check whether the tier is loaded for the tenant. + * * @return */ boolean isTierLoaded(); - ApiApplicationKey generateAndRetrieveApplicationKeys(String applicationName, String[] tags, - String keyType, String username, - boolean isAllowedAllDomains, - String validityTime, - String password, String accessToken, - ArrayList supportedGrantTypes, - String callbackUrl, - boolean isMappingRequired) throws APIManagerException; - /** - * To get access token for given scopes and for the given validity period - * @param scopes Scopes - * @param tags Tags - * @param applicationName Application Name - * @param tokenType Token Type - * @param validityPeriod Validity Period - * @param username Name of the user to create the token. If null, set as carbon context user - * @return {@link String} Access Token - * @throws APIManagerException if error occurred while getting the access token for given scopes, - * validity period etc. + * Create and retrieve API application token base on {@link TokenCreationProfile} + * @param tokenCreationProfile {@link TokenCreationProfile} + * @return Retrieve {@link Token} result on a successful execution + * @throws APIManagerException Throws when error occurred while retrieving the token */ - AccessTokenInfo getAccessToken(String scopes, String[] tags, String applicationName, String - tokenType, String validityPeriod, String username) - throws APIManagerException; + Token getToken(TokenCreationProfile tokenCreationProfile) throws APIManagerException; + /** + * Register API application base on {@link ApiApplicationProfile} + * @param idnAuthenticationProfile Application owner's authentication user details + * @param apiApplicationProfile {@link ApiApplicationProfile} + * @return {@link ApiApplicationKey} result on a successful execution + * @throws IdnAuthenticationException Throws when authentication error occurred + * @throws APIManagerException Throws when error encountered while registering the application profile + * @throws BadRequestException Throws when the application profile contains invalid attributes + * @throws UnexpectedResponseException Throws when unexpected response received from the REST API client + */ + ApiApplicationKey registerApiApplication(IdnAuthenticationProfile idnAuthenticationProfile, + ApiApplicationProfile apiApplicationProfile) + throws IdnAuthenticationException, APIManagerException, BadRequestException, UnexpectedResponseException; } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/APIManagementProviderServiceImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/APIManagementProviderServiceImpl.java index 3e612e5838..218b111f82 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/APIManagementProviderServiceImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/APIManagementProviderServiceImpl.java @@ -18,420 +18,319 @@ package io.entgra.device.mgt.core.apimgt.application.extension; -import io.entgra.device.mgt.core.apimgt.application.extension.bean.APIRegistrationProfile; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.ApiApplicationProfile; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.IdnAuthenticationProfile; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.Token; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.TokenCreationProfile; +import io.entgra.device.mgt.core.apimgt.application.extension.constants.ApiApplicationConstants; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; +import io.entgra.device.mgt.core.apimgt.application.extension.exception.IdnAuthenticationException; import io.entgra.device.mgt.core.apimgt.application.extension.internal.APIApplicationManagerExtensionDataHolder; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.ConsumerRESTAPIServices; import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.APIInfo; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application; import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.ApplicationKey; import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.KeyManager; import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Subscription; -import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException; -import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException; -import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata; -import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; -import io.entgra.device.mgt.core.identity.jwt.client.extension.JWTClient; -import io.entgra.device.mgt.core.identity.jwt.client.extension.dto.AccessTokenInfo; -import io.entgra.device.mgt.core.identity.jwt.client.extension.exception.JWTClientException; -import io.entgra.device.mgt.core.identity.jwt.client.extension.service.JWTClientManagerService; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.ConsumerRESTAPIServices; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.ApiApplicationInfo; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.OAuthClientException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; +import okhttp3.Credentials; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; import org.wso2.carbon.apimgt.impl.APIManagerFactory; +import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder; import org.wso2.carbon.apimgt.impl.utils.APIUtil; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; /** * This class represents an implementation of APIManagementProviderService. */ public class APIManagementProviderServiceImpl implements APIManagementProviderService { - private static final Log log = LogFactory.getLog(APIManagementProviderServiceImpl.class); public static final APIManagerFactory API_MANAGER_FACTORY = APIManagerFactory.getInstance(); + private static final Log log = LogFactory.getLog(APIManagementProviderServiceImpl.class); + private static final APIManagerConfiguration config = + ServiceReferenceHolder.getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration(); + private static final OkHttpClient client = new OkHttpClient(); private static final String UNLIMITED_TIER = "Unlimited"; + private static final String JWT_TOKEN_TYPE = "JWT"; + private static final Gson gson = new Gson(); - @Override - public boolean isTierLoaded() { + private static JSONObject generateRequestBody(TokenCreationProfile tokenCreationProfile) { + JSONObject requestBody = new JSONObject(); - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + if ("password".equals(tokenCreationProfile.getGrantType())) { + requestBody.put("username", tokenCreationProfile.getUsername()); + requestBody.put("password", tokenCreationProfile.getPassword()); + } - try { - APIUtil.getTiers(APIConstants.TIER_APPLICATION_TYPE, tenantDomain); - return true; - } catch (APIManagementException e) { - log.error("APIs not ready", e); + if ("refresh_token".equals(tokenCreationProfile.getGrantType())) { + requestBody.put("refresh_token", tokenCreationProfile.getRefreshToken()); } - return false; + if ("authorization_code".equals(tokenCreationProfile.getGrantType())) { + requestBody.put("code", tokenCreationProfile.getCode()); + requestBody.put("redirect_uri", tokenCreationProfile.getCallbackUrl()); + } + + requestBody.put("grant_type", tokenCreationProfile.getGrantType()); + requestBody.put("scope", tokenCreationProfile.getScope()); + return requestBody; } - @Override - public synchronized ApiApplicationKey generateAndRetrieveApplicationKeys(String applicationName, String[] tags, - String keyType, String username, - boolean isAllowedAllDomains, - String validityTime, - String password, String accessToken, - ArrayList supportedGrantTypes, - String callbackUrl, - boolean isMappingRequired) - throws APIManagerException { - - ApiApplicationInfo apiApplicationInfo = new ApiApplicationInfo(); - if (StringUtils.isEmpty(accessToken)) { - apiApplicationInfo = getApplicationInfo(username, password); - } else { - apiApplicationInfo.setAccess_token(accessToken); + private static ApiApplicationKey registerApiApplication(ApiApplicationProfile apiApplicationProfile) + throws APIManagerException, BadRequestException, UnexpectedResponseException { + if (apiApplicationProfile.getGrantTypes().contains("authorization_code") + && StringUtils.isEmpty(apiApplicationProfile.getCallbackUrl())) { + throw new BadRequestException("Invalid request found."); } ConsumerRESTAPIServices consumerRESTAPIServices = APIApplicationManagerExtensionDataHolder.getInstance().getConsumerRESTAPIServices(); - try { - Map headerParams = new HashMap<>(); - if (!"carbon.super".equals(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true))) { - headerParams.put("X-WSO2-Tenant", "carbon.super"); - } + List applications = + Arrays.asList(consumerRESTAPIServices.getAllApplications(apiApplicationProfile.getApplicationName())); - Map uniqueApiSet = new HashMap<>(); - if (tags != null) { - for (String tag : tags) { - Map queryParams = new HashMap<>(); - queryParams.put("tag", tag); - - APIInfo[] apiInfos = consumerRESTAPIServices.getAllApis(apiApplicationInfo, queryParams, headerParams); - Arrays.stream(apiInfos).forEach(apiInfo -> uniqueApiSet.putIfAbsent(apiInfo.getName(), apiInfo)); - } + if (applications.size() > 1) { + String msg = "Found more than one application with the same application name : [ " + + apiApplicationProfile.getApplicationName() + " ]"; + throw new APIManagerException(msg); } - List uniqueApiList = new ArrayList<>(uniqueApiSet.values()); - - io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application[] applications = - consumerRESTAPIServices.getAllApplications(apiApplicationInfo, applicationName); - if (applications.length == 0) { - return handleNewAPIApplication(applicationName, uniqueApiList, apiApplicationInfo, keyType, - validityTime, supportedGrantTypes, callbackUrl, isMappingRequired); - } else { - if (applications.length == 1) { - Optional applicationOpt = - Arrays.stream(applications).findFirst(); - io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application application = - applicationOpt.get(); - - MetadataManagementService metadataManagementService = APIApplicationManagerExtensionDataHolder.getInstance().getMetadataManagementService(); - Metadata metaData = metadataManagementService.retrieveMetadata(applicationName); - if (metaData == null) { - // Todo add a comment - consumerRESTAPIServices.deleteApplication(apiApplicationInfo, application.getApplicationId()); - return handleNewAPIApplication(applicationName, uniqueApiList, apiApplicationInfo, keyType, - validityTime, supportedGrantTypes, callbackUrl, isMappingRequired); - } else { - Subscription[] subscriptions = consumerRESTAPIServices.getAllSubscriptions(apiApplicationInfo, application.getApplicationId()); - for (Subscription subscription : subscriptions) { - uniqueApiList.removeIf(apiInfo -> Objects.equals(apiInfo.getId(), subscription.getApiInfo().getId())); - } - - if (!uniqueApiList.isEmpty()) { - addSubscriptions(application, uniqueApiList, apiApplicationInfo); - } - - String[] metaValues = metaData.getMetaValue().split(":"); - if (metaValues.length != 2) { - String msg = "Found invalid Meta value for meta key: " + applicationName + ". Meta Value: " - + metaData.getMetaValue(); - log.error(msg); - throw new APIManagerException(msg); - } - String applicationId = metaValues[0]; - String keyMappingId = metaValues[1]; - ApplicationKey applicationKey = consumerRESTAPIServices.getKeyDetails(apiApplicationInfo, applicationId, keyMappingId); - ApiApplicationKey apiApplicationKey = new ApiApplicationKey(); - apiApplicationKey.setConsumerKey(applicationKey.getConsumerKey()); - apiApplicationKey.setConsumerSecret(applicationKey.getConsumerSecret()); - return apiApplicationKey; - } - } else { - String msg = "Found more than one application for application name: " + applicationName; - log.error(msg); - throw new APIManagerException(msg); - } + Set apis = new HashSet<>(); + for (String tag : apiApplicationProfile.getTags()) { + Map queryParam = new HashMap<>(); + queryParam.putIfAbsent("tag", tag); + apis.addAll(Arrays.asList(consumerRESTAPIServices.getAllApis(queryParam, new HashMap<>()))); } + + return applications.isEmpty() ? createAndRetrieveApplicationKeys(apiApplicationProfile, apis) : + updateAndRetrieveApplicationKeys(applications.get(0), apiApplicationProfile, apis); + } catch (APIServicesException e) { - String msg = "Error occurred while processing the response of APIM REST endpoints."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (BadRequestException e) { - String msg = "Provided incorrect payload when invoking APIM REST endpoints."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (UnexpectedResponseException e) { - String msg = "Error occurred while invoking APIM REST endpoints."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (MetadataManagementException e) { - String msg = "Error occurred while getting meta data for meta key: " + applicationName; - log.error(msg, e); - throw new APIManagerException(msg, e); + throw new RuntimeException(e); } - } + } - private ApiApplicationKey handleNewAPIApplication(String applicationName, List uniqueApiList, - ApiApplicationInfo apiApplicationInfo, String keyType, String validityTime, - ArrayList supportedGrantTypes, String callbackUrl, - boolean isMappingRequired) throws APIManagerException { + private static ApiApplicationKey updateAndRetrieveApplicationKeys(Application application, + ApiApplicationProfile apiApplicationProfile, + Set apis) + throws BadRequestException, UnexpectedResponseException, APIServicesException, APIManagerException { ConsumerRESTAPIServices consumerRESTAPIServices = APIApplicationManagerExtensionDataHolder.getInstance().getConsumerRESTAPIServices(); - io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application application = new io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application(); - application.setName(applicationName); - application.setThrottlingPolicy(UNLIMITED_TIER); - try { - application = consumerRESTAPIServices.createApplication(apiApplicationInfo, application); - addSubscriptions(application, uniqueApiList, apiApplicationInfo); - - KeyManager[] keyManagers = consumerRESTAPIServices.getAllKeyManagers(apiApplicationInfo); - KeyManager keyManager; - if (keyManagers.length == 1) { - keyManager = keyManagers[0]; - } else { - String msg = - "Found invalid number of key managers. No of key managers found from the APIM: " + keyManagers.length; - log.error(msg); - throw new APIManagerException(msg); + List availableSubscriptions = + Arrays.asList(consumerRESTAPIServices.getAllSubscriptions(application.getApplicationId())); + List allSubscriptions = constructSubscriptionList(application.getApplicationId(), apis); + + List newSubscriptions = new ArrayList<>(); + for (Subscription subscription : allSubscriptions) { + if (!availableSubscriptions.contains(subscription)) { + newSubscriptions.add(subscription); } + } - ApplicationKey applicationKey; + ApplicationKey[] applicationKeys = consumerRESTAPIServices.getAllKeys(application.getApplicationId()); + if (applicationKeys.length == 0) { + return generateApplicationKeys(application.getApplicationId(), apiApplicationProfile.getGrantTypes(), + apiApplicationProfile.getCallbackUrl()); + } - if (isMappingRequired) { - // If we need to get opaque token instead of the JWT token, we have to do the mapping. Therefore, if - // it is a requirement then we have to call the method with enabling the flag. - APIApplicationServices apiApplicationServices = APIApplicationManagerExtensionDataHolder.getInstance() - .getApiApplicationServices(); + ApplicationKey applicationKey = applicationKeys[0]; - APIApplicationKey apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials( - "ClientForMapping", - "client_credentials password refresh_token urn:ietf:params:oauth:grant-type:jwt-bearer"); + // Received { "code":900967,"message":"General Error" } when updating the grant types of existing application. + // Hence, as an alternative we check if there is any grant type difference and if yes simply delete the + // previous application and create a new one. + boolean isGrantsAreUpdated = + !new HashSet<>(applicationKey.getSupportedGrantTypes()). + equals(new HashSet<>(Arrays.asList(apiApplicationProfile.getGrantTypes().split(Constants.SPACE)))); - apiApplicationInfo.setClientId(apiApplicationKey.getClientId()); - apiApplicationInfo.setClientSecret(apiApplicationKey.getClientSecret()); + if (isGrantsAreUpdated) { + consumerRESTAPIServices.deleteApplication(application.getApplicationId()); + return createAndRetrieveApplicationKeys(apiApplicationProfile, apis); + } - applicationKey = consumerRESTAPIServices.mapApplicationKeys(apiApplicationInfo, application, - keyManager.getName(), keyType); - } else { - applicationKey = consumerRESTAPIServices.generateApplicationKeys(apiApplicationInfo, application.getApplicationId(), - keyManager.getName(), validityTime, keyType); - } - if (supportedGrantTypes != null || StringUtils.isNotEmpty(callbackUrl)) { - applicationKey = consumerRESTAPIServices.updateGrantType(apiApplicationInfo, application.getApplicationId(), - applicationKey.getKeyMappingId(), keyManager.getName(), supportedGrantTypes, callbackUrl); - } + if (!newSubscriptions.isEmpty()) { + consumerRESTAPIServices.createSubscriptions(newSubscriptions); + } - ApiApplicationKey apiApplicationKey = new ApiApplicationKey(); - apiApplicationKey.setConsumerKey(applicationKey.getConsumerKey()); - apiApplicationKey.setConsumerSecret(applicationKey.getConsumerSecret()); + return new ApiApplicationKey(applicationKey.getConsumerKey(), applicationKey.getConsumerSecret()); + } - Metadata metaData = new Metadata(); - metaData.setMetaKey(applicationName); - String metaValue = application.getApplicationId() + ":" + applicationKey.getKeyMappingId(); - metaData.setMetaValue(metaValue); + private static ApiApplicationKey createAndRetrieveApplicationKeys(ApiApplicationProfile apiApplicationProfile, + Set apis) + throws BadRequestException, UnexpectedResponseException, APIServicesException, APIManagerException { + ConsumerRESTAPIServices consumerRESTAPIServices = + APIApplicationManagerExtensionDataHolder.getInstance().getConsumerRESTAPIServices(); - MetadataManagementService metadataManagementService = APIApplicationManagerExtensionDataHolder.getInstance().getMetadataManagementService(); - metadataManagementService.createMetadata(metaData); - return apiApplicationKey; - } catch (MetadataKeyAlreadyExistsException e) { - String msg = "Since meta key:" + applicationName + " already exists, meta data creating process failed."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (MetadataManagementException e) { - String msg = "Error occurred while creating meta data for meta key: " + applicationName; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (BadRequestException e) { - String msg = "Provided incorrect payload when invoking APIM REST endpoints to handle new API application."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (UnexpectedResponseException e) { - String msg = "Error occurred while invoking APIM REST endpoints to handle new API application."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (APIServicesException e) { - String msg = "Error occurred while processing the response of APIM REST endpoints to handle new API application."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } - } + Application application = new Application(); + application.setName(apiApplicationProfile.getApplicationName()); + application.setThrottlingPolicy(UNLIMITED_TIER); + application.setTokenType(JWT_TOKEN_TYPE); + application.setOwner(apiApplicationProfile.getOwner()); + + application = consumerRESTAPIServices.createApplication(application); + + List subscriptions = constructSubscriptionList(application.getApplicationId(), apis); - /** - * This method can be used to add a new subscriptions providing the ids of the APIs and the applications. - * - * @param application {@link io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application} - * @param apiInfos {@link List} - * @param apiApplicationInfo {@link ApiApplicationInfo} - * @throws BadRequestException if incorrect data provided to call subscribing REST API. - * @throws UnexpectedResponseException if error occurred while processing the subscribing REST API. - * @throws APIServicesException if error occurred while invoking the subscribing REST API. - */ - private void addSubscriptions( - io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application application, - List apiInfos, ApiApplicationInfo apiApplicationInfo) - throws BadRequestException, UnexpectedResponseException, APIServicesException { + consumerRESTAPIServices.createSubscriptions(subscriptions); + return generateApplicationKeys(application.getApplicationId(), apiApplicationProfile.getGrantTypes(), + apiApplicationProfile.getCallbackUrl()); + } + + private static ApiApplicationKey generateApplicationKeys(String applicationId, String grantTypes, + String callbackUrl) + throws APIManagerException, BadRequestException, UnexpectedResponseException, APIServicesException { ConsumerRESTAPIServices consumerRESTAPIServices = APIApplicationManagerExtensionDataHolder.getInstance().getConsumerRESTAPIServices(); - List subscriptionList = new ArrayList<>(); - apiInfos.forEach(apiInfo -> { + KeyManager[] keyManagers = consumerRESTAPIServices.getAllKeyManagers(); + + if (keyManagers.length != 1) { + throw new APIManagerException("Found invalid number of key managers."); + } + + ApplicationKey applicationKey = consumerRESTAPIServices.generateApplicationKeys(applicationId, + keyManagers[0].getName(), ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD, + ApiApplicationConstants.DEFAULT_TOKEN_TYPE, grantTypes, callbackUrl); + return new ApiApplicationKey(applicationKey.getConsumerKey(), applicationKey.getConsumerSecret()); + } + + private static List constructSubscriptionList(String applicationId, Set apiInfos) { + return apiInfos.stream().map(apiInfo -> { Subscription subscription = new Subscription(); + subscription.setApplicationId(applicationId); subscription.setApiId(apiInfo.getId()); - subscription.setApplicationId(application.getApplicationId()); subscription.setThrottlingPolicy(UNLIMITED_TIER); - subscription.setRequestedThrottlingPolicy(UNLIMITED_TIER); - subscriptionList.add(subscription); - }); - - consumerRESTAPIServices.createSubscriptions(apiApplicationInfo, subscriptionList); + return subscription; + }).collect(Collectors.toList()); } @Override - public AccessTokenInfo getAccessToken(String scopes, String[] tags, String applicationName, String tokenType, - String validityPeriod, String username) throws APIManagerException { + public boolean isTierLoaded() { + + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + try { - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true); - ApiApplicationKey clientCredentials = getClientCredentials(tenantDomain, tags, applicationName, tokenType, - validityPeriod); + APIUtil.getTiers(APIConstants.TIER_APPLICATION_TYPE, tenantDomain); + return true; + } catch (APIManagementException e) { + log.error("APIs not ready", e); + } - if (clientCredentials == null) { - String msg = "Oauth Application creation is failed."; - log.error(msg); - throw new APIManagerException(msg); - } + return false; + } - if (username == null || username.isEmpty()) { - username = - PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername() + "@" + PrivilegedCarbonContext - .getThreadLocalCarbonContext().getTenantDomain(true); - } else { - if (!username.contains("@")) { - username += "@" + PrivilegedCarbonContext - .getThreadLocalCarbonContext().getTenantDomain(true); - } + @Override + public Token getToken(TokenCreationProfile tokenCreationProfile) throws APIManagerException { + JSONObject requestBody = generateRequestBody(tokenCreationProfile); + + Request request = new Request.Builder() + .url(config.getFirstProperty(Constants.TOKE_END_POINT)) + .post(RequestBody + .create(requestBody.toString(), + MediaType.parse("application/json; charset=utf-8"))) + .addHeader("Authorization", Credentials.basic(tokenCreationProfile.getBasicAuthUsername(), + tokenCreationProfile.getBasicAuthPassword())) + .build(); + + try (Response response = client.newCall(request).execute()) { + if (response.isSuccessful()) { + return gson.fromJson(response.body() != null ? response.body().string() : null, Token.class); } - JWTClientManagerService jwtClientManagerService = APIApplicationManagerExtensionDataHolder.getInstance() - .getJwtClientManagerService(); - JWTClient jwtClient = jwtClientManagerService.getJWTClient(); + String msg = "Error response [ " + response.code() + " ] received for the token acquiring request"; + log.error(msg); + throw new APIManagerException(msg); - return jwtClient - .getAccessToken(clientCredentials.getConsumerKey(), clientCredentials.getConsumerSecret(), username, - scopes); - } catch (JWTClientException e) { - String msg = "JWT Error occurred while registering Application to get access token."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (APIManagerException e) { - String msg = "Error occurred while getting access tokens."; - log.error(msg, e); - throw new APIManagerException(msg, e); - } catch (UserStoreException e) { - String msg = "User management exception when getting client credentials."; + } catch (IOException e) { + String msg = "Error encountered while sending token acquiring request"; log.error(msg, e); throw new APIManagerException(msg, e); } } - /** - * Get Client credentials of application belongs to tenant admin - * - * @param tenantDomain Tenant Domain - * @param tags Tags - * @param applicationName Application Name - * @param tokenType Token Type - * @param validityPeriod Validity Period - * @return {@link ApiApplicationKey} - * @throws APIManagerException if error occurred while generating access token - * @throws UserStoreException if error occurred while getting admin username. - */ - private ApiApplicationKey getClientCredentials(String tenantDomain, String[] tags, String applicationName, - String tokenType, String validityPeriod) throws APIManagerException, UserStoreException { - - APIRegistrationProfile registrationProfile = new APIRegistrationProfile(); - registrationProfile.setAllowedToAllDomains(false); - registrationProfile.setMappingAnExistingOAuthApp(false); - registrationProfile.setTags(tags); - registrationProfile.setApplicationName(applicationName); - - if (tenantDomain == null || tenantDomain.isEmpty()) { - tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; - } + @Override + public ApiApplicationKey registerApiApplication(IdnAuthenticationProfile idnAuthenticationProfile, + ApiApplicationProfile apiApplicationProfile) + throws IdnAuthenticationException, APIManagerException, BadRequestException, UnexpectedResponseException { + String flowStartingDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; + MetadataManagementService metadataManagementService = + APIApplicationManagerExtensionDataHolder.getInstance().getMetadataManagementService(); + try { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername( - PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration() - .getAdminUserName()); - - return generateAndRetrieveApplicationKeys(registrationProfile.getApplicationName(), - registrationProfile.getTags(), tokenType, PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName(), - registrationProfile.isAllowedToAllDomains(), validityPeriod, PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminPassword(), null, null, null, false); - } finally { - PrivilegedCarbonContext.endTenantFlow(); + Metadata metaData = + metadataManagementService.retrieveMetadata(Constants.API_PUBLISHING_ENABLED_TENANT_LIST_KEY); + if (metaData != null) { + JsonArray tenants = gson.fromJson(metaData.getMetaValue(), JsonArray.class); + + for (JsonElement tenant : tenants) { + if (Objects.equals(tenant.getAsString(), idnAuthenticationProfile.getTenantDomain())) { + flowStartingDomain = idnAuthenticationProfile.getTenantDomain(); + } + } + } + } catch (MetadataManagementException metadataManagementException) { + log.warn("Failed to load API publishing enabled tenant domains from meta data registry."); } - } - private ApiApplicationInfo getApplicationInfo(String username, String password) - throws APIManagerException { - - APIApplicationServices apiApplicationServices = APIApplicationManagerExtensionDataHolder.getInstance() - .getApiApplicationServices(); + if (log.isDebugEnabled()) { + log.info("Start API application registration sequences though " + flowStartingDomain + " domain."); + } - APIApplicationKey apiApplicationKey; - io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo accessTokenInfo; try { - if (username == null || password == null) { - apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials( - "ClientForConsumerRestCalls", - "client_credentials password refresh_token urn:ietf:params:oauth:grant-type:jwt-bearer"); - } else { - apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentialsWithUser( - "ClientForConsumerRestCalls", - username, password, - "client_credentials password refresh_token urn:ietf:params:oauth:grant-type:jwt-bearer"); + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(flowStartingDomain, true); + if (APIApplicationManagerExtensionDataHolder.getInstance().getIoAuthClientService(). + doAuthenticate(idnAuthenticationProfile.getUsername(), idnAuthenticationProfile.getPassword())) { + apiApplicationProfile.setOwner(idnAuthenticationProfile.getUsername()); + return registerApiApplication(apiApplicationProfile); } - accessTokenInfo = apiApplicationServices.generateAccessTokenFromRegisteredApplication( - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - } catch (APIServicesException e) { - String errorMsg = "Error occurred while generating the API application"; - log.error(errorMsg, e); - throw new APIManagerException(errorMsg, e); - } - ApiApplicationInfo applicationInfo = new ApiApplicationInfo(); - applicationInfo.setClientId(apiApplicationKey.getClientId()); - applicationInfo.setClientSecret(apiApplicationKey.getClientSecret()); - applicationInfo.setAccess_token(accessTokenInfo.getAccess_token()); - applicationInfo.setRefresh_token(accessTokenInfo.getRefresh_token()); + throw new IdnAuthenticationException( + "Failed to authenticate the user : [ " + idnAuthenticationProfile.getUsername() + " ]"); - return applicationInfo; + } catch (OAuthClientException e) { + String msg = + "Error encountered while performing authentication for user : [ " + idnAuthenticationProfile.getUsername() + " ]"; + log.error(msg, e); + throw new APIManagerException(msg, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } } } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/ApiApplicationProfile.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/ApiApplicationProfile.java new file mode 100644 index 0000000000..3fec87fad0 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/ApiApplicationProfile.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.application.extension.bean; + +public class ApiApplicationProfile { + private String applicationName; + private String tags[]; + private String callbackUrl; + private String grantTypes; + private String owner; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public String[] getTags() { + return tags; + } + + public void setTags(String[] tags) { + this.tags = tags; + } + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callbackUrl) { + this.callbackUrl = callbackUrl; + } + + public String getGrantTypes() { + return grantTypes; + } + + public void setGrantTypes(String grantTypes) { + this.grantTypes = grantTypes; + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/IdnAuthenticationProfile.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/IdnAuthenticationProfile.java new file mode 100644 index 0000000000..102d601f43 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/IdnAuthenticationProfile.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.application.extension.bean; + +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; + +public class IdnAuthenticationProfile { + private String username; + private String password; + private String tenantDomain; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + String []usernameParts = this.username.split("@(?=[^@]*$)"); + if (usernameParts.length == 2) { + this.tenantDomain = usernameParts[usernameParts.length - 1]; + return; + } + this.tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getTenantDomain() { + return tenantDomain; + } + + public void setTenantDomain(String tenantDomain) { + this.tenantDomain = tenantDomain; + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/Token.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/Token.java new file mode 100644 index 0000000000..34037427a4 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/Token.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.application.extension.bean; + +public class Token { + private long expires_in; + private String refresh_token; + private String access_token; + private String scope; + private String token_type; + + public long getExpires_in() { + return expires_in; + } + + public void setExpires_in(long expires_in) { + this.expires_in = expires_in; + } + + public String getRefresh_token() { + return refresh_token; + } + + public void setRefresh_token(String refresh_token) { + this.refresh_token = refresh_token; + } + + public String getAccess_token() { + return access_token; + } + + public void setAccess_token(String access_token) { + this.access_token = access_token; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getToken_type() { + return token_type; + } + + public void setToken_type(String token_type) { + this.token_type = token_type; + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/TokenCreationProfile.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/TokenCreationProfile.java new file mode 100644 index 0000000000..dd9e196f71 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/bean/TokenCreationProfile.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.application.extension.bean; + +public class TokenCreationProfile { + private String basicAuthUsername; + private String basicAuthPassword; + private String grantType; + private String scope; + private String username; + private String password; + private String callbackUrl; + private String refreshToken; + private String code; + + public String getBasicAuthUsername() { + return basicAuthUsername; + } + + public void setBasicAuthUsername(String basicAuthUsername) { + this.basicAuthUsername = basicAuthUsername; + } + + public String getBasicAuthPassword() { + return basicAuthPassword; + } + + public void setBasicAuthPassword(String basicAuthPassword) { + this.basicAuthPassword = basicAuthPassword; + } + + public String getGrantType() { + return grantType; + } + + public void setGrantType(String grantType) { + this.grantType = grantType; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callbackUrl) { + this.callbackUrl = callbackUrl; + } + + public String getRefreshToken() { + return refreshToken; + } + + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/dto/ApiApplicationKey.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/dto/ApiApplicationKey.java index 526d36cd60..ed99e96cca 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/dto/ApiApplicationKey.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/dto/ApiApplicationKey.java @@ -25,29 +25,37 @@ import org.json.simple.JSONObject; * This holds api application consumer key and secret. */ public class ApiApplicationKey { - private String consumerKey; - private String consumerSecret; + private String client_id; + private String client_secret; - public String getConsumerKey() { - return this.consumerKey; + public ApiApplicationKey(String client_id, String client_secret) { + this.client_id = client_id; + this.client_secret = client_secret; } - public void setConsumerKey(String consumerKey) { - this.consumerKey = consumerKey; + public ApiApplicationKey() { } - public String getConsumerSecret() { - return this.consumerSecret; + public String getClient_id() { + return this.client_id; } - public void setConsumerSecret(String consumerSecret) { - this.consumerSecret = consumerSecret; + public void setClient_id(String client_id) { + this.client_id = client_id; + } + + public String getClient_secret() { + return this.client_secret; + } + + public void setClient_secret(String client_secret) { + this.client_secret = client_secret; } public String toString() { JSONObject obj = new JSONObject(); - obj.put(ApiApplicationConstants.OAUTH_CLIENT_ID, this.getConsumerKey()); - obj.put(ApiApplicationConstants.OAUTH_CLIENT_SECRET, this.getConsumerSecret()); + obj.put(ApiApplicationConstants.OAUTH_CLIENT_ID, this.getClient_id()); + obj.put(ApiApplicationConstants.OAUTH_CLIENT_SECRET, this.getClient_secret()); return obj.toString(); } } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/exception/IdnAuthenticationException.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/exception/IdnAuthenticationException.java new file mode 100644 index 0000000000..5de7829896 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/exception/IdnAuthenticationException.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.application.extension.exception; + +public class IdnAuthenticationException extends Exception { + public IdnAuthenticationException(String msg) { + super(msg); + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java index e3bbebc4d0..4b14026f56 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java @@ -20,6 +20,7 @@ package io.entgra.device.mgt.core.apimgt.application.extension.internal; import io.entgra.device.mgt.core.apimgt.application.extension.APIManagementProviderService; import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices; import io.entgra.device.mgt.core.apimgt.extension.rest.api.ConsumerRESTAPIServices; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.IOAuthClientService; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; import org.wso2.carbon.context.PrivilegedCarbonContext; import io.entgra.device.mgt.core.identity.jwt.client.extension.service.JWTClientManagerService; @@ -41,6 +42,7 @@ public class APIApplicationManagerExtensionDataHolder { private ConsumerRESTAPIServices consumerRESTAPIServices; private APIApplicationServices apiApplicationServices; private MetadataManagementService metadataManagementService; + private IOAuthClientService ioAuthClientService; private APIApplicationManagerExtensionDataHolder() { } @@ -134,4 +136,15 @@ public class APIApplicationManagerExtensionDataHolder { public void setMetadataManagementService(MetadataManagementService metadataManagementService) { this.metadataManagementService = metadataManagementService; } + + public IOAuthClientService getIoAuthClientService() { + if (ioAuthClientService == null) { + throw new IllegalStateException("Auth client service not initialized properly"); + } + return ioAuthClientService; + } + + public void setIoAuthClientService(IOAuthClientService ioAuthClientService) { + this.ioAuthClientService = ioAuthClientService; + } } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java index b3dc6dbd9d..cc1b2ab4f5 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension/src/main/java/io/entgra/device/mgt/core/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java @@ -21,6 +21,7 @@ import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationService import io.entgra.device.mgt.core.apimgt.extension.rest.api.ConsumerRESTAPIServices; import io.entgra.device.mgt.core.apimgt.application.extension.APIManagementProviderService; import io.entgra.device.mgt.core.apimgt.application.extension.APIManagementProviderServiceImpl; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.IOAuthClientService; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -209,4 +210,34 @@ public class APIApplicationManagerExtensionServiceComponent { } APIApplicationManagerExtensionDataHolder.getInstance().setMetadataManagementService(null); } + + /** + * Sets IOAuthclientService. + * + * @param ioAuthClientService An instance of {@link IOAuthClientService} + */ + @Reference( + name = "APIM.application.oauth.client.service", + service = io.entgra.device.mgt.core.apimgt.extension.rest.api.IOAuthClientService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetAPIApplicationServices") + protected void setIOAuthClientService(IOAuthClientService ioAuthClientService) { + if (log.isDebugEnabled()) { + log.debug("Setting IOAuthclientService."); + } + APIApplicationManagerExtensionDataHolder.getInstance().setIoAuthClientService(ioAuthClientService); + } + + /** + * Unset IOAuthclientService. + * + * @param ioAuthClientService An instance of {@link IOAuthClientService} + */ + protected void unsetAPIApplicationServices(IOAuthClientService ioAuthClientService) { + if (log.isDebugEnabled()) { + log.debug("Unsetting DCR REST API Service"); + } + APIApplicationManagerExtensionDataHolder.getInstance().setIoAuthClientService(null); + } } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/ConsumerRESTAPIServices.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/ConsumerRESTAPIServices.java index 2cb3cf692c..52ae8947f2 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/ConsumerRESTAPIServices.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/ConsumerRESTAPIServices.java @@ -18,7 +18,11 @@ package io.entgra.device.mgt.core.apimgt.extension.rest.api; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.*; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.APIInfo; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.ApplicationKey; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.KeyManager; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Subscription; import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.ApiApplicationInfo; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; @@ -29,44 +33,47 @@ import java.util.Map; public interface ConsumerRESTAPIServices { - Application[] getAllApplications(ApiApplicationInfo apiApplicationInfo, String appName) + Application[] getAllApplications(String appName) throws APIServicesException, BadRequestException, UnexpectedResponseException; - Application getDetailsOfAnApplication(ApiApplicationInfo apiApplicationInfo, String applicationId) + Application getDetailsOfAnApplication(String applicationId) throws APIServicesException, BadRequestException, UnexpectedResponseException; - Application createApplication(ApiApplicationInfo apiApplicationInfo, Application application) + Application createApplication(Application application) throws APIServicesException, BadRequestException, UnexpectedResponseException; - Boolean deleteApplication(ApiApplicationInfo apiApplicationInfo, String applicationId) + Boolean deleteApplication(String applicationId) throws APIServicesException, BadRequestException, UnexpectedResponseException; - Subscription[] getAllSubscriptions(ApiApplicationInfo apiApplicationInfo, String applicationId) + Subscription[] getAllSubscriptions(String applicationId) throws APIServicesException, BadRequestException, UnexpectedResponseException; - APIInfo[] getAllApis(ApiApplicationInfo apiApplicationInfo, Map queryParams, Map headerParams) + APIInfo[] getAllApis(Map queryParams, Map headerParams) throws APIServicesException, BadRequestException, UnexpectedResponseException; - Subscription createSubscription(ApiApplicationInfo apiApplicationInfo, Subscription subscriptions) + Subscription createSubscription(Subscription subscriptions) throws APIServicesException, BadRequestException, UnexpectedResponseException; - Subscription[] createSubscriptions(ApiApplicationInfo apiApplicationInfo, List subscriptions) + public ApplicationKey[] getAllKeys(String applicationId) throws APIServicesException, BadRequestException, UnexpectedResponseException; - ApplicationKey generateApplicationKeys(ApiApplicationInfo apiApplicationInfo, String applicationId, String keyManager, - String validityTime, String keyType) + Subscription[] createSubscriptions(List subscriptions) throws APIServicesException, BadRequestException, UnexpectedResponseException; - ApplicationKey mapApplicationKeys(ApiApplicationInfo apiApplicationInfo, Application application, String keyManager, String keyType) + ApplicationKey generateApplicationKeys(String applicationId, String keyManager, + String validityTime, String keyType, String grantTypesToBeSupported, String callbackUrl) throws APIServicesException, BadRequestException, UnexpectedResponseException; - ApplicationKey getKeyDetails(ApiApplicationInfo apiApplicationInfo, String applicationId, String keyMapId) + ApplicationKey mapApplicationKeys(String consumerKey, String consumerSecret, Application application, + String keyManager, String keyType) throws APIServicesException, BadRequestException, UnexpectedResponseException; - ApplicationKey updateGrantType(ApiApplicationInfo apiApplicationInfo, String applicationId, String keyMapId, String keyManager, - List supportedGrantTypes, String callbackUrl) + ApplicationKey getKeyDetails(String applicationId, String keyMapId) throws APIServicesException, BadRequestException, UnexpectedResponseException; - KeyManager[] getAllKeyManagers(ApiApplicationInfo apiApplicationInfo) + ApplicationKey updateGrantType(String applicationId, String keyMapId, List supportedGrantTypes, String callbackUrl) + throws APIServicesException, BadRequestException, UnexpectedResponseException; + + KeyManager[] getAllKeyManagers() throws APIServicesException, BadRequestException, UnexpectedResponseException; } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/ConsumerRESTAPIServicesImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/ConsumerRESTAPIServicesImpl.java index 998331cc0d..6a5e3f67b3 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/ConsumerRESTAPIServicesImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/ConsumerRESTAPIServicesImpl.java @@ -19,121 +19,88 @@ package io.entgra.device.mgt.core.apimgt.extension.rest.api; import com.google.gson.Gson; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.*; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.APIInfo; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.ApplicationKey; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.KeyManager; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Scopes; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Subscription; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.OAuthClientResponse; import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.ApiApplicationInfo; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.OAuthClientException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.util.HttpsTrustManagerUtils; -import okhttp3.*; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.internal.APIManagerServiceDataHolder; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.JSONArray; import org.json.JSONObject; -import java.io.IOException; import java.util.List; import java.util.Map; public class ConsumerRESTAPIServicesImpl implements ConsumerRESTAPIServices { private static final Log log = LogFactory.getLog(ConsumerRESTAPIServicesImpl.class); - private static final OkHttpClient client = new OkHttpClient(HttpsTrustManagerUtils.getSSLClient().newBuilder()); private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private static final Gson gson = new Gson(); private static final String host = System.getProperty(Constants.IOT_CORE_HOST); private static final String port = System.getProperty(Constants.IOT_CORE_HTTPS_PORT); private static final String endPointPrefix = Constants.HTTPS_PROTOCOL + Constants.SCHEME_SEPARATOR + host + Constants.COLON + port; + private static final IOAuthClientService client = + APIManagerServiceDataHolder.getInstance().getIoAuthClientService(); @Override - public Application[] getAllApplications(ApiApplicationInfo apiApplicationInfo, String appName) + public Application[] getAllApplications(String appName) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getAllApplicationsUrl = endPointPrefix + Constants.APPLICATIONS_API + "?query=" + appName; Request.Builder builder = new Request.Builder(); builder.url(getAllApplicationsUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.get(); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray applicationList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(applicationList.toString(), Application[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return getAllApplications(refreshedApiApplicationInfo, appName); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray applicationList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(applicationList.toString(), Application[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving applications for application name : [ " + appName + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public Application getDetailsOfAnApplication(ApiApplicationInfo apiApplicationInfo, String applicationId) + public Application getDetailsOfAnApplication(String applicationId) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getDetailsOfAPPUrl = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + applicationId; Request.Builder builder = new Request.Builder(); builder.url(getDetailsOfAPPUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.get(); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return gson.fromJson(response.body().string(), Application.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return getDetailsOfAnApplication(refreshedApiApplicationInfo, applicationId); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), Application.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving details of application ID : [ " + applicationId + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public Application createApplication(ApiApplicationInfo apiApplicationInfo, Application application) + public Application createApplication(Application application) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getAllScopesUrl = endPointPrefix + Constants.APPLICATIONS_API; JSONArray groups = new JSONArray(); @@ -161,123 +128,68 @@ public class ConsumerRESTAPIServicesImpl implements ConsumerRESTAPIServices { Request.Builder builder = new Request.Builder(); builder.url(getAllScopesUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.post(requestBody); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { - return gson.fromJson(response.body().string(), Application.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return createApplication(refreshedApiApplicationInfo, application); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), Application.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while creating application : [ " + application.getName() + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public Boolean deleteApplication(ApiApplicationInfo apiApplicationInfo, String applicationId) + public Boolean deleteApplication(String applicationId) throws APIServicesException, BadRequestException, UnexpectedResponseException { String deleteScopesUrl = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + applicationId; Request.Builder builder = new Request.Builder(); builder.url(deleteScopesUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.delete(); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return deleteApplication(refreshedApiApplicationInfo, applicationId); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = + "Error occurred while deleting application associated with application ID : [ " + applicationId + "]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public Subscription[] getAllSubscriptions(ApiApplicationInfo apiApplicationInfo, String applicationId) + public Subscription[] getAllSubscriptions(String applicationId) throws APIServicesException, BadRequestException, UnexpectedResponseException { - - String getAllScopesUrl = endPointPrefix + Constants.SUBSCRIPTION_API + "?applicationId=" + applicationId + "&limit=1000"; + String getAllScopesUrl = endPointPrefix + Constants.SUBSCRIPTION_API + "?applicationId=" + applicationId + + "&limit=1000"; Request.Builder builder = new Request.Builder(); builder.url(getAllScopesUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.get(); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray subscriptionList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(subscriptionList.toString(), Subscription[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return getAllSubscriptions(refreshedApiApplicationInfo, applicationId); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray subscriptionList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(subscriptionList.toString(), Subscription[].class); + } catch (OAuthClientException e) { + String msg = + "Error occurred while retrieving all subscription of application associated with application ID :" + + " [ " + applicationId + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public APIInfo[] getAllApis(ApiApplicationInfo apiApplicationInfo, Map queryParams, Map headerParams) + public APIInfo[] getAllApis(Map queryParams, Map headerParams) throws APIServicesException, BadRequestException, UnexpectedResponseException { - StringBuilder getAPIsURL = new StringBuilder(endPointPrefix + Constants.DEV_PORTAL_API); for (Map.Entry query : queryParams.entrySet()) { @@ -286,8 +198,6 @@ public class ConsumerRESTAPIServicesImpl implements ConsumerRESTAPIServices { Request.Builder builder = new Request.Builder(); builder.url(getAPIsURL.toString()); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); for (Map.Entry header : headerParams.entrySet()) { builder.addHeader(header.getKey(), header.getValue()); @@ -296,86 +206,48 @@ public class ConsumerRESTAPIServicesImpl implements ConsumerRESTAPIServices { Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray apiList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(apiList.toString(), APIInfo[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return getAllApis(refreshedApiApplicationInfo, queryParams, headerParams); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray apiList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(apiList.toString(), APIInfo[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving all APIs"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public Subscription createSubscription(ApiApplicationInfo apiApplicationInfo, Subscription subscriptions) + public Subscription createSubscription(Subscription subscription) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String createSubscriptionUrl = endPointPrefix + Constants.SUBSCRIPTION_API; JSONObject subscriptionObject = new JSONObject(); - subscriptionObject.put("applicationId", subscriptions.getApplicationId()); - subscriptionObject.put("apiId", subscriptions.getApiId()); - subscriptionObject.put("throttlingPolicy", subscriptions.getThrottlingPolicy()); - subscriptionObject.put("requestedThrottlingPolicy", subscriptions.getRequestedThrottlingPolicy()); + subscriptionObject.put("applicationId", subscription.getApplicationId()); + subscriptionObject.put("apiId", subscription.getApiId()); + subscriptionObject.put("throttlingPolicy", subscription.getThrottlingPolicy()); + subscriptionObject.put("requestedThrottlingPolicy", subscription.getRequestedThrottlingPolicy()); RequestBody requestBody = RequestBody.create(JSON, subscriptionObject.toString()); Request.Builder builder = new Request.Builder(); builder.url(createSubscriptionUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); - builder.post(requestBody); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { - return gson.fromJson(response.body().string(), Subscription.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return createSubscription(refreshedApiApplicationInfo, subscriptions); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), Subscription.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while adding subscription : [ " + subscription.getSubscriptionId() + " ] for" + + " application associated with application ID : [ " + subscription.getApplicationId() + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public Subscription[] createSubscriptions(ApiApplicationInfo apiApplicationInfo, List subscriptions) + public Subscription[] createSubscriptions(List subscriptions) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String createSubscriptionsUrl = endPointPrefix + Constants.SUBSCRIPTION_API + "/multiple"; String subscriptionsList = gson.toJson(subscriptions); @@ -383,109 +255,64 @@ public class ConsumerRESTAPIServicesImpl implements ConsumerRESTAPIServices { Request.Builder builder = new Request.Builder(); builder.url(createSubscriptionsUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.post(requestBody); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return gson.fromJson(response.body().string(), Subscription[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return createSubscriptions(refreshedApiApplicationInfo, subscriptions); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), Subscription[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while adding subscriptions"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public ApplicationKey generateApplicationKeys(ApiApplicationInfo apiApplicationInfo, String applicationId, String keyManager, - String validityTime, String keyType) + public ApplicationKey generateApplicationKeys(String applicationId, String keyManager, String validityTime, + String keyType, String grantTypesToBeSupported, String callbackUrl) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String generateApplicationKeysUrl = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + applicationId + "/generate-keys"; - JSONArray grantTypesToBeSupported = new JSONArray(); - grantTypesToBeSupported.put("password"); - grantTypesToBeSupported.put("client_credentials"); - - JSONArray scopes = new JSONArray(); - scopes.put("am_application_scope"); - scopes.put("default"); - JSONObject keyInfo = new JSONObject(); keyInfo.put("keyType", keyType); keyInfo.put("keyManager", keyManager); - keyInfo.put("grantTypesToBeSupported", grantTypesToBeSupported); - keyInfo.put("callbackUrl", ""); - keyInfo.put("scopes", scopes); - keyInfo.put("validityTime", 3600); - keyInfo.put("additionalProperties", new JSONObject()); + keyInfo.put("grantTypesToBeSupported", grantTypesToBeSupported.split(Constants.SPACE)); + if (!StringUtils.isEmpty(callbackUrl)) { + keyInfo.put("callbackUrl", callbackUrl); + } + keyInfo.put("validityTime", validityTime); RequestBody requestBody = RequestBody.create(JSON, keyInfo.toString()); Request.Builder builder = new Request.Builder(); builder.url(generateApplicationKeysUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.post(requestBody); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return gson.fromJson(response.body().string(), ApplicationKey.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return generateApplicationKeys(refreshedApiApplicationInfo, applicationId, keyManager, validityTime, keyType); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), ApplicationKey.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while generating application keys for application associated with " + + "application ID : [ " + applicationId + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public ApplicationKey mapApplicationKeys(ApiApplicationInfo apiApplicationInfo, Application application, String keyManager, String keyType) + public ApplicationKey mapApplicationKeys(String consumerKey, String consumerSecret, Application application, + String keyManager, String keyType) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getAllScopesUrl = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + application.getApplicationId() + "/map-keys"; JSONObject payload = new JSONObject(); - payload.put("consumerKey", apiApplicationInfo.getClientId()); - payload.put("consumerSecret", apiApplicationInfo.getClientSecret()); + payload.put("consumerKey", consumerKey); + payload.put("consumerSecret", consumerSecret); payload.put("keyManager", keyManager); payload.put("keyType", keyType); @@ -493,101 +320,76 @@ public class ConsumerRESTAPIServicesImpl implements ConsumerRESTAPIServices { Request.Builder builder = new Request.Builder(); builder.url(getAllScopesUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.post(requestBody); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return gson.fromJson(response.body().string(), ApplicationKey.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return mapApplicationKeys(refreshedApiApplicationInfo, application, keyManager, keyType); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), ApplicationKey.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while mapping application keys"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public ApplicationKey getKeyDetails(ApiApplicationInfo apiApplicationInfo, String applicationId, String keyMapId) + public ApplicationKey getKeyDetails(String applicationId, String keyMapId) throws APIServicesException, BadRequestException, UnexpectedResponseException { - - String getKeyDetails = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + applicationId + "/oauth-keys/" + keyMapId; + String getKeyDetails = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + applicationId + + "/oauth-keys/" + keyMapId; Request.Builder builder = new Request.Builder(); builder.url(getKeyDetails); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.get(); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return gson.fromJson(response.body().string(), ApplicationKey.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return getKeyDetails(refreshedApiApplicationInfo, applicationId, keyMapId); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), ApplicationKey.class); + } catch (OAuthClientException e) { + String msg = + "Error occurred while retrieving key details of application associated with application ID : [ " + applicationId + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public ApplicationKey updateGrantType(ApiApplicationInfo apiApplicationInfo, String applicationId, String keyMapId, String keyManager, - List supportedGrantTypes, String callbackUrl) + public ApplicationKey[] getAllKeys(String applicationId) throws APIServicesException, BadRequestException, UnexpectedResponseException { - - String getKeyDetails = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + applicationId + "/oauth-keys/" + keyMapId; + String getKeyDetails = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + applicationId + + "/oauth-keys"; Request.Builder builder = new Request.Builder(); builder.url(getKeyDetails); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); + builder.get(); + Request request = builder.build(); - JSONArray supportedGrantTypeList = new JSONArray(); - for (String string : supportedGrantTypes) { - supportedGrantTypeList.put(string); + try { + OAuthClientResponse response = client.execute(request); + JSONArray keyList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(keyList.toString(), ApplicationKey[].class); + } catch (OAuthClientException e) { + String msg = + "Error occurred while retrieving key details of application associated with application ID : [ " + applicationId + " ]"; + log.error(msg, e); + throw new APIServicesException(msg, e); } + } + + @Override + public ApplicationKey updateGrantType(String applicationId, String keyMapId, List supportedGrantTypes, String callbackUrl) + throws APIServicesException, BadRequestException, UnexpectedResponseException { + String getKeyDetails = endPointPrefix + Constants.APPLICATIONS_API + Constants.SLASH + applicationId + + "/oauth-keys/" + keyMapId; + + Request.Builder builder = new Request.Builder(); + builder.url(getKeyDetails); JSONObject payload = new JSONObject(); - payload.put("keyMappingId", keyMapId); - payload.put("keyManager", keyManager); - payload.put("supportedGrantTypes", supportedGrantTypeList); + payload.put("supportedGrantTypes", supportedGrantTypes); payload.put("callbackUrl", (callbackUrl != null ? callbackUrl : "")); - payload.put("additionalProperties", new JSONObject()); RequestBody requestBody = RequestBody.create(JSON, payload.toString()); @@ -595,80 +397,34 @@ public class ConsumerRESTAPIServicesImpl implements ConsumerRESTAPIServices { Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return gson.fromJson(response.body().string(), ApplicationKey.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return updateGrantType(refreshedApiApplicationInfo, applicationId, keyMapId, keyManager, supportedGrantTypes, callbackUrl); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), ApplicationKey.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while updating the grant types of the application associated with " + + "application ID : [ " + applicationId + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public KeyManager[] getAllKeyManagers(ApiApplicationInfo apiApplicationInfo) + public KeyManager[] getAllKeyManagers() throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getAllKeyManagersUrl = endPointPrefix + Constants.KEY_MANAGERS_API; Request.Builder builder = new Request.Builder(); builder.url(getAllKeyManagersUrl); - builder.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + apiApplicationInfo.getAccess_token()); builder.get(); Request request = builder.build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray keyManagerList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(keyManagerList.toString(), KeyManager[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(apiApplicationInfo.getRefresh_token(), - apiApplicationInfo.getClientId(), apiApplicationInfo.getClientSecret()); - ApiApplicationInfo refreshedApiApplicationInfo = returnApplicationInfo(apiApplicationInfo, refreshedAccessToken); - return getAllKeyManagers(refreshedApiApplicationInfo); - //TODO: max attempt count - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray keyManagerList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(keyManagerList.toString(), KeyManager[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving all key managers"; log.error(msg, e); throw new APIServicesException(msg, e); } } - - private ApiApplicationInfo returnApplicationInfo(ApiApplicationInfo apiApplicationInfo, AccessTokenInfo refreshedToken) { - - ApiApplicationInfo applicationInfo = new ApiApplicationInfo(); - applicationInfo.setClientId(apiApplicationInfo.getClientId()); - applicationInfo.setClientSecret(apiApplicationInfo.getClientSecret()); - applicationInfo.setAccess_token(refreshedToken.getAccess_token()); - applicationInfo.setRefresh_token(refreshedToken.getRefresh_token()); - return applicationInfo; - } } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/IOAuthClientService.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/IOAuthClientService.java new file mode 100644 index 0000000000..4a113e40ea --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/IOAuthClientService.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.extension.rest.api; + +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.OAuthClientResponse; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.OAuthClientException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; +import okhttp3.Request; + +public interface IOAuthClientService { + /** + * Handle execution of a APIM REST services invocation request. Token and cache handling will be handled by the + * service itself. + * + * @param request Instance of {@link Request} to execute + * @return Instance of {@link OAuthClientResponse} when successful invocation happens + * @throws OAuthClientException Throws when error encountered while sending the request + * @throws BadRequestException Throws when received of an invalid request + * @throws UnexpectedResponseException Throws when unexpected response received + */ + OAuthClientResponse execute(Request request) throws OAuthClientException, BadRequestException, + UnexpectedResponseException; + + /** + * Use to authenticate user against Identify Server + * + * @param username Username of the user + * @param password Password of the User + * @return Returns true if the requested user is authenticated user, otherwise false + * @throws OAuthClientException Throws when error encountered while authenticating + */ + boolean doAuthenticate(String username, String password) throws OAuthClientException; +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/OAuthClient.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/OAuthClient.java new file mode 100644 index 0000000000..53e86b19b5 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/OAuthClient.java @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.extension.rest.api; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.OAuthClientResponse; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.OAuthClientException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.util.HttpsTrustManagerUtils; +import okhttp3.Credentials; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; +import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; +import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class OAuthClient implements IOAuthClientService { + + private static final Log log = LogFactory.getLog(OAuthClient.class); + private static final OkHttpClient client = new OkHttpClient(HttpsTrustManagerUtils.getSSLClient().newBuilder()); + private static final Gson gson = new Gson(); + private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + private static final String IDN_DCR_CLIENT_PREFIX = "_REST_API_INVOKER_SERVICE"; + private static final String IDN_REST_API_INVOKER_USER = "rest_service_reserved_user"; + private static final String IDN_REST_API_INVOKER_USER_PWD = "rest_service_reserved_user"; + private static final APIManagerConfiguration config = + ServiceReferenceHolder.getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration(); + private static final String tokenEndpoint = config.getFirstProperty(Constants.TOKE_END_POINT); + private static final String dcrEndpoint = config.getFirstProperty(Constants.DCR_END_POINT); + private static final Map cache = new ConcurrentHashMap<>(); + private static final int MAX_RETRY_ATTEMPT = 2; + + private OAuthClient() { + } + + public static OAuthClient getInstance() { + return OAuthClientHolder.INSTANCE; + } + + /** + * Handle execution of a APIM REST services invocation request. Token and cache handling will be handled by the + * service itself. + * + * @param request Instance of {@link Request} to execute + * @return Instance of {@link OAuthClientResponse} when successful invocation happens + * @throws OAuthClientException {@link OAuthClientException} + * @throws BadRequestException {@link BadRequestException} + * @throws UnexpectedResponseException {@link UnexpectedResponseException} + */ + @Override + public OAuthClientResponse execute(Request request) throws OAuthClientException, BadRequestException, + UnexpectedResponseException { + int currentRetryAttempt = 0; + OAuthClientResponse oAuthClientResponse; + + while (true) { + try { + request = intercept(request); + try (Response response = client.newCall(request).execute()) { + if (response.isSuccessful()) { + oAuthClientResponse = mapToOAuthClientResponse(response); + break; + } + + if (response.code() == HttpStatus.SC_NOT_FOUND) { + if (log.isDebugEnabled()) { + log.info("Resource not found for the request [ " + request.url() + " ]"); + } + oAuthClientResponse = mapToOAuthClientResponse(response); + break; + } + + // entering to the retrying phase, so increment the counter + currentRetryAttempt++; + if (response.code() == HttpStatus.SC_UNAUTHORIZED) { + if (currentRetryAttempt <= MAX_RETRY_ATTEMPT) { + refresh(); + } else { + String msg = + "Request [ " + request.url() + " ] failed with code : [ " + response.code() + " ]" + + " & body : [ " + (response.body() != null ? + response.body().string() : " empty body received!") + " ]"; + log.error(msg); + throw new UnexpectedResponseException(msg); + } + } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { + String msg = + "Encountered a bad request! Request [ " + request.url() + " ] failed with code : " + + "[ " + response.code() + " ] & body : [ " + (response.body() != null ? + response.body().string() : " empty body received!") + " ]"; + log.error(msg); + throw new BadRequestException(msg); + } else { + String msg = + "Request [ " + request.url() + " ]failed with code : [ " + response.code() + " ] & " + + "body : [ " + (response.body() != null ? response.body().string() : " empty " + + "body received!") + " ]"; + log.error(msg); + throw new UnexpectedResponseException(msg); + } + } + } catch (IOException ex) { + String msg = + "Error occurred while executing the request : [ " + request.method() + ":" + request.url() + + " ]"; + throw new OAuthClientException(msg, ex); + } + } + return oAuthClientResponse; + } + + @Override + public boolean doAuthenticate(String username, String password) throws OAuthClientException { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + + CacheWrapper cacheWrapper = cache.computeIfAbsent(tenantDomain, key -> { + CacheWrapper constructedWrapper = null; + try { + Keys keys = idnDynamicClientRegistration(); + Tokens tokens = idnTokenGeneration(keys); + constructedWrapper = new CacheWrapper(keys, tokens); + } catch (Exception e) { + log.error("Error encountered while updating the cache", e); + } + return constructedWrapper; + }); + + if (cacheWrapper != null) { + String tokenRequestJsonStr = (new JSONObject()) + .put("grant_type", Constants.PASSWORD_GRANT_TYPE) + .put("username", username) + .put("password", password) + .put("scope", Constants.SCOPES) + .put("callbackUrl", Constants.PLACEHOLDING_CALLBACK_URL) + .toString(); + + RequestBody requestBody = RequestBody.Companion.create(tokenRequestJsonStr, JSON); + Request tokenRequest = new Request.Builder() + .url(tokenEndpoint) + .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Credentials.basic(cacheWrapper.keys.consumerKey, + cacheWrapper.keys.consumerSecret)) + .post(requestBody) + .build(); + + try (Response response = client.newCall(tokenRequest).execute()) { + if (response.isSuccessful()) { + Tokens tokens = mapTokens(response.body()); + if (tokens.accessToken != null) { + if (log.isDebugEnabled()) { + log.info("IDN authentication success for user : [ " + username + " ]"); + } + return true; + } + } + } catch (IOException e) { + String msg = + "Error encountered while performing IDN authentication for received user : [ " + username + + " ]"; + log.error(msg, e); + throw new OAuthClientException(msg, e); + + } + } + if (log.isDebugEnabled()) { + log.info("IDN authentication failed for user : [ " + username + " ]"); + } + return false; + } + + /** + * Dynamic client registration will be handled through here. These clients can be located under carbon console's + * service provider section in respective tenants. + * + * @return Instance of {@link Keys} containing the dcr client's credentials + * @throws IOException Throws when error encountered while executing dcr request + * @throws OAuthClientException Throws when failed to register dcr client + */ + private Keys idnDynamicClientRegistration() throws IOException, OAuthClientException { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + createRestClientInvokerUserIfNotExists(tenantDomain); + String tenantAwareClientName = tenantDomain.toUpperCase() + IDN_DCR_CLIENT_PREFIX; + + List grantTypes = Arrays.asList(Constants.PASSWORD_GRANT_TYPE, Constants.REFRESH_TOKEN_GRANT_TYPE); + String dcrRequestJsonStr = (new JSONObject()) + .put("clientName", tenantAwareClientName) + .put("owner", IDN_REST_API_INVOKER_USER + "@" + tenantDomain) + .put("saasApp", true) + .put("grantType", String.join(Constants.SPACE, grantTypes)) + .put("tokenType", "Default") + .toString(); + + RequestBody requestBody = RequestBody.Companion.create(dcrRequestJsonStr, JSON); + Request dcrRequest = new Request.Builder() + .url(dcrEndpoint) + .addHeader(Constants.AUTHORIZATION_HEADER_NAME, + Credentials.basic(IDN_REST_API_INVOKER_USER + "@" + tenantDomain + , IDN_REST_API_INVOKER_USER_PWD)) + .post(requestBody) + .build(); + + try (Response response = client.newCall(dcrRequest).execute()) { + if (response.isSuccessful()) { + return mapKeys(response.body()); + } + } + + String msg = "Error encountered while processing DCR request. Tried client : [ " + tenantAwareClientName + " ]"; + log.error(msg); + throw new OAuthClientException(msg); + } + + /** + * Token obtaining procedure will be handled here. Since the required permissions for invoking the APIM REST + * services are available for the tenant admins, this procedure will use admin credentials for obtaining tokens. + * Also, please note that these tokens are only use for invoking APIM REST services only. The password grant uses + * since it facilitates the use of refresh token. + * + * @param keys Dcr client credentials to obtain a token + * @return Instance of {@link Tokens} containing the tokens + * @throws IOException Throws when error encountered while executing token request + * @throws OAuthClientException Throws when failed to obtain tokens + */ + private Tokens idnTokenGeneration(Keys keys) throws IOException, OAuthClientException { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String tokenRequestJsonStr = (new JSONObject()) + .put("grant_type", Constants.PASSWORD_GRANT_TYPE) + .put("username", IDN_REST_API_INVOKER_USER + "@" + tenantDomain) + .put("password", IDN_REST_API_INVOKER_USER_PWD) + .put("scope", Constants.SCOPES) + .put("callbackUrl", Constants.PLACEHOLDING_CALLBACK_URL) + .toString(); + + RequestBody requestBody = RequestBody.Companion.create(tokenRequestJsonStr, JSON); + Request tokenRequest = new Request.Builder() + .url(tokenEndpoint) + .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Credentials.basic(keys.consumerKey, + keys.consumerSecret)) + .post(requestBody) + .build(); + + try (Response response = client.newCall(tokenRequest).execute()) { + if (response.isSuccessful()) { + return mapTokens(response.body()); + } + } + + String msg = "Error encountered while processing token registration request"; + log.error(msg); + throw new OAuthClientException(msg); + } + + /** + * Obtain and refresh idn auth tokens. Note that in the first try it try to obtain new tokens via refresh_token + * grant type, if it fails it tries to obtain new tokens via password grant type. + * + * @param keys Instance of {@link Keys} containing the dcr client's credentials + * @param refreshToken Refresh token + * @return Instance of {@link Tokens} containing the tokens + * @throws IOException Throws when error encountered while executing token request + * @throws OAuthClientException Throws when failed to obtain tokens + */ + private Tokens idnTokenRefresh(Keys keys, String refreshToken) throws IOException, + OAuthClientException { + String tokenRequestJsonStr = (new JSONObject()) + .put("grant_type", Constants.REFRESH_TOKEN_GRANT_TYPE) + .put("refresh_token", refreshToken) + .put("scope", Constants.SCOPES) + .toString(); + + RequestBody requestBody = RequestBody.Companion.create(tokenRequestJsonStr, JSON); + Request tokenRequest = new Request.Builder() + .url(tokenEndpoint) + .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Credentials.basic(keys.consumerKey, + keys.consumerSecret)) + .post(requestBody) + .build(); + + try (Response response = client.newCall(tokenRequest).execute()) { + if (response.isSuccessful()) { + return mapTokens(response.body()); + } else { + return idnTokenGeneration(keys); + } + } + } + + /** + * Intercept the request and add authorization header base on available tokens. + * + * @param request Instance of the {@link Request} to intercept + * @return Intercepted request + * @throws OAuthClientException Throws when error encountered while adding authorization header + */ + private Request intercept(Request request) throws OAuthClientException { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + CacheWrapper cacheWrapper = cache.computeIfAbsent(tenantDomain, key -> { + CacheWrapper constructedWrapper = null; + try { + Keys keys = idnDynamicClientRegistration(); + Tokens tokens = idnTokenGeneration(keys); + constructedWrapper = new CacheWrapper(keys, tokens); + } catch (Exception e) { + log.error("Error encountered while updating the cache", e); + } + return constructedWrapper; + }); + + if (cacheWrapper == null) { + throw new OAuthClientException("Failed to obtain tokens. Hence aborting request intercepting sequence"); + } + + return new Request.Builder(request).header(Constants.AUTHORIZATION_HEADER_NAME, + Constants.AUTHORIZATION_HEADER_PREFIX_BEARER + cacheWrapper.tokens.accessToken).build(); + } + + /** + * Refresh cached tokens. + * + * @throws OAuthClientException Throws when error encountered while refreshing the tokens + */ + private void refresh() throws OAuthClientException { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + CacheWrapper cacheWrapper = cache.computeIfPresent(tenantDomain, (key, value) -> { + CacheWrapper updatedCacheWrapper = null; + try { + Tokens tokens = idnTokenRefresh(value.keys, value.tokens.refreshToken); + updatedCacheWrapper = new CacheWrapper(value.keys, tokens); + } catch (Exception e) { + log.error("Error encountered while updating the cache", e); + } + return updatedCacheWrapper; + }); + + if (cacheWrapper == null) { + throw new OAuthClientException("Failed to refresh tokens. Hence aborting request executing process"); + } + } + + private Keys mapKeys(ResponseBody responseBody) throws IOException { + Keys keys = new Keys(); + if (responseBody == null) { + if (log.isDebugEnabled()) { + log.debug("Received empty request body for mapping into keys"); + } + return keys; + } + + JsonObject jsonObject = gson.fromJson(responseBody.string(), JsonObject.class); + keys.consumerKey = jsonObject.get("clientId").getAsString(); + keys.consumerSecret = jsonObject.get("clientSecret").getAsString(); + return keys; + } + + private Tokens mapTokens(ResponseBody responseBody) throws IOException { + Tokens tokens = new Tokens(); + if (responseBody == null) { + if (log.isDebugEnabled()) { + log.debug("Received empty request body for mapping into tokens"); + } + return tokens; + } + + JsonObject jsonObject = gson.fromJson(responseBody.string(), JsonObject.class); + tokens.accessToken = jsonObject.get("access_token").getAsString(); + tokens.refreshToken = jsonObject.get("refresh_token").getAsString(); + return tokens; + } + + private OAuthClientResponse mapToOAuthClientResponse(Response response) throws IOException { + return new OAuthClientResponse(response.code(), + response.body() != null ? response.body().string() : null, response.isSuccessful()); + } + + public void createRestClientInvokerUserIfNotExists(String tenantDomain) throws OAuthClientException { + try { + UserStoreManager userStoreManager = + PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager(); + if (!userStoreManager.isExistingUser(MultitenantUtils.getTenantAwareUsername(IDN_REST_API_INVOKER_USER))) { + if (log.isDebugEnabled()) { + log.debug("Creating user '" + IDN_REST_API_INVOKER_USER + "' in '" + tenantDomain + "' tenant domain."); + } + String[] roles = {Constants.ADMIN_ROLE_KEY}; + userStoreManager.addUser( + MultitenantUtils.getTenantAwareUsername(IDN_REST_API_INVOKER_USER), + IDN_REST_API_INVOKER_USER_PWD, + roles, + null, + "" + ); + } + } catch (UserStoreException e) { + String msg = + "Error occurred while creating " + IDN_REST_API_INVOKER_USER + "in tenant: '" + tenantDomain + "'."; + log.error(msg); + throw new OAuthClientException(msg, e); + } + } + + /** + * Holder for {@link OAuthClient} instance + */ + private static class OAuthClientHolder { + private static final OAuthClient INSTANCE = new OAuthClient(); + } + + /** + * Act as an internal data class for containing dcr credentials, hence no need of expose as a bean + */ + private class Keys { + String consumerKey; + String consumerSecret; + } + + /** + * Act as an internal data class for containing dcr tokens, hence no need of expose as a bean + */ + private class Tokens { + String accessToken; + String refreshToken; + } + + /** + * Act as an internal data class for containing cached tokens and keys, hence no need of expose as a bean + */ + private class CacheWrapper { + Keys keys; + Tokens tokens; + + CacheWrapper(Keys keys, Tokens tokens) { + this.keys = keys; + this.tokens = tokens; + } + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServices.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServices.java index da24e906a1..cc6da9f36a 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServices.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServices.java @@ -18,9 +18,13 @@ package io.entgra.device.mgt.core.apimgt.extension.rest.api; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.*; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIInfo; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevision; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevisionDeployment; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Documentation; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Mediation; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.MediationPolicy; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; @@ -29,86 +33,86 @@ import java.util.List; public interface PublisherRESTAPIServices { - Scope[] getScopes(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo) + Scope[] getScopes() throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean isSharedScopeNameExists(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String key) + boolean isSharedScopeNameExists(String key) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean addNewSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope) + boolean addNewSharedScope(Scope scope) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean updateSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope) + boolean updateSharedScope(Scope scope) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean deleteSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope) + boolean deleteSharedScope(Scope scope) throws APIServicesException, BadRequestException, UnexpectedResponseException; - APIInfo getApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String apiUuid) + APIInfo getApi(String apiUuid) throws APIServicesException, BadRequestException, UnexpectedResponseException; - APIInfo[] getApis(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo) + APIInfo[] getApis() throws APIServicesException, BadRequestException, UnexpectedResponseException; - APIInfo addAPI(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIInfo api) + APIInfo addAPI(APIInfo api) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean updateApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIInfo api) + boolean updateApi(APIInfo api) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean saveAsyncApiDefinition(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid, + boolean saveAsyncApiDefinition(String uuid, String asyncApiDefinition) throws APIServicesException, BadRequestException, UnexpectedResponseException; - MediationPolicy[] getAllApiSpecificMediationPolicies(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String apiUuid) + MediationPolicy[] getAllApiSpecificMediationPolicies( + String apiUuid) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean addApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, Mediation mediation) + boolean addApiSpecificMediationPolicy( + String uuid, Mediation mediation) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean deleteApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, Mediation mediation) + boolean deleteApiSpecificMediationPolicy( + String uuid, Mediation mediation) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean changeLifeCycleStatus(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, String action) + boolean changeLifeCycleStatus( + String uuid, String action) throws APIServicesException, BadRequestException, UnexpectedResponseException; - APIRevision[] getAPIRevisions(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid, + APIRevision[] getAPIRevisions(String uuid, Boolean deploymentStatus) throws APIServicesException, BadRequestException, UnexpectedResponseException; - APIRevision addAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - APIRevision apiRevision) + APIRevision addAPIRevision( + APIRevision apiRevision) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean deployAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid, + boolean deployAPIRevision(String uuid, String apiRevisionId, List apiRevisionDeploymentList) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean undeployAPIRevisionDeployment(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - APIRevision apiRevisionDeployment, String uuid) + boolean undeployAPIRevisionDeployment( + APIRevision apiRevisionDeployment, String uuid) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean deleteAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - APIRevision apiRevision, String uuid) + boolean deleteAPIRevision( + APIRevision apiRevision, String uuid) throws APIServicesException, BadRequestException, UnexpectedResponseException; - Documentation[] getDocumentations(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid) + Documentation[] getDocumentations( + String uuid) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean deleteDocumentations(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, String documentID) + boolean deleteDocumentations( + String uuid, String documentID) throws APIServicesException, BadRequestException, UnexpectedResponseException; - Documentation addDocumentation(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, Documentation documentation) + Documentation addDocumentation( + String uuid, Documentation documentation) throws APIServicesException, BadRequestException, UnexpectedResponseException; - boolean addDocumentationContent(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String apiUuid, String docId, String docContent) + boolean addDocumentationContent( + String apiUuid, String docId, String docContent) throws APIServicesException, BadRequestException, UnexpectedResponseException; } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServicesImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServicesImpl.java index e322ae0307..35412b9365 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServicesImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServicesImpl.java @@ -19,16 +19,27 @@ package io.entgra.device.mgt.core.apimgt.extension.rest.api; import com.google.gson.Gson; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.OAuthClientResponse; import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.*; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIInfo; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevision; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevisionDeployment; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.AdditionalProperties; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Documentation; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Mediation; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.MediationPolicy; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Operations; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.OAuthClientException; import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.util.HttpsTrustManagerUtils; -import okhttp3.*; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.internal.APIManagerServiceDataHolder; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.Request; import okhttp3.Request.Builder; +import okhttp3.RequestBody; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,110 +47,62 @@ import org.apache.commons.ssl.Base64; import org.json.JSONArray; import org.json.JSONObject; -import java.io.IOException; import java.util.List; public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { private static final Log log = LogFactory.getLog(PublisherRESTAPIServicesImpl.class); - private static final OkHttpClient client = new OkHttpClient(HttpsTrustManagerUtils.getSSLClient().newBuilder()); private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private static final Gson gson = new Gson(); private static final String host = System.getProperty(Constants.IOT_CORE_HOST); private static final String port = System.getProperty(Constants.IOT_CORE_HTTPS_PORT); private static final String endPointPrefix = Constants.HTTPS_PROTOCOL + Constants.SCHEME_SEPARATOR + host + Constants.COLON + port; + private static final IOAuthClientService client = + APIManagerServiceDataHolder.getInstance().getIoAuthClientService(); @Override - public Scope[] getScopes(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo) + public Scope[] getScopes() throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getAllScopesUrl = endPointPrefix + Constants.GET_ALL_SCOPES; Request request = new Request.Builder() .url(getAllScopesUrl) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .get() .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray scopeList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(scopeList.toString(), Scope[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return getScopes(apiApplicationKey, refreshedAccessToken); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray scopeList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(scopeList.toString(), Scope[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving scopes"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean isSharedScopeNameExists(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String key) - throws APIServicesException, BadRequestException, UnexpectedResponseException { - + public boolean isSharedScopeNameExists(String key) throws APIServicesException, BadRequestException, + UnexpectedResponseException { String keyValue = new String(Base64.encodeBase64((key).getBytes())).replace(Constants.QUERY_KEY_VALUE_SEPARATOR, Constants.EMPTY_STRING); String getScopeUrl = endPointPrefix + Constants.SCOPE_API_ENDPOINT + keyValue; Request request = new Request.Builder() .url(getScopeUrl) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .head() .build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return isSharedScopeNameExists(apiApplicationKey, refreshedAccessToken, key); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else if (HttpStatus.SC_NOT_FOUND == response.code()) { - String msg = "Shared scope key not found : " + key; - if (log.isDebugEnabled()) { - log.debug(msg); - } - return false; - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while checking the shared scope existence for scope key : [ " + key + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean addNewSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope) + public boolean addNewSharedScope(Scope scope) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String addNewSharedScopeEndPoint = endPointPrefix + Constants.SCOPE_API_ENDPOINT; JSONArray bindings = new JSONArray(); @@ -159,42 +122,21 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { RequestBody requestBody = RequestBody.create(JSON, payload.toString()); Request request = new Request.Builder() .url(addNewSharedScopeEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return addNewSharedScope(apiApplicationKey, refreshedAccessToken, scope); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid scope object"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.message(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while adding new shared scope : [ " + scope.getName() + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean updateSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope) + public boolean updateSharedScope(Scope scope) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String updateScopeUrl = endPointPrefix + Constants.SCOPE_API_ENDPOINT + scope.getId(); JSONArray bindings = new JSONArray(); @@ -214,40 +156,21 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { RequestBody requestBody = RequestBody.create(JSON, payload.toString()); Request request = new Request.Builder() .url(updateScopeUrl) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .put(requestBody) .build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return updateSharedScope(apiApplicationKey, refreshedAccessToken, scope); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid scope object"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while updating the scope : [ " + scope.getName() + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean deleteSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope) + public boolean deleteSharedScope(Scope scope) throws APIServicesException, BadRequestException, UnexpectedResponseException { String updateScopeUrl = endPointPrefix + Constants.SCOPE_API_ENDPOINT + scope.getId(); @@ -268,121 +191,57 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { RequestBody requestBody = RequestBody.create(JSON, payload.toString()); Request request = new Request.Builder() .url(updateScopeUrl) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .delete(requestBody) .build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return deleteSharedScope(apiApplicationKey, refreshedAccessToken, scope); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid scope object"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while deleting shared scope : [ " + scope.getName() + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public APIInfo getApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String apiUuid) + public APIInfo getApi(String apiUuid) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getAllApi = endPointPrefix + Constants.API_ENDPOINT + apiUuid; Request request = new Request.Builder() .url(getAllApi) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .get() .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return gson.fromJson(response.body().string(), APIInfo.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return getApi(apiApplicationKey, refreshedAccessToken, apiUuid); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), APIInfo.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving API associated with API UUID : [ " + apiUuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public APIInfo[] getApis(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo) - throws APIServicesException, BadRequestException, UnexpectedResponseException { - + public APIInfo[] getApis() throws APIServicesException, BadRequestException, UnexpectedResponseException { String getAllApis = endPointPrefix + Constants.GET_ALL_APIS; Request request = new Request.Builder() .url(getAllApis) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .get() .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray apiList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(apiList.toString(), APIInfo[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return getApis(apiApplicationKey, refreshedAccessToken); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray apiList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(apiList.toString(), APIInfo[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving APIs"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public APIInfo addAPI(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIInfo api) - throws APIServicesException, BadRequestException, UnexpectedResponseException { - + public APIInfo addAPI(APIInfo api) throws APIServicesException, BadRequestException, UnexpectedResponseException { String addAPIEndPoint = endPointPrefix + Constants.API_ENDPOINT; JSONObject payload = new JSONObject(); @@ -406,7 +265,8 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { payload.put("apiThrottlingPolicy", api.getApiThrottlingPolicy()); payload.put("authorizationHeader", api.getAuthorizationHeader()); payload.put("visibility", api.getVisibility()); - payload.put("subscriptionAvailability", (api.getSubscriptionAvailability() != null ? api.getSubscriptionAvailability() : "")); + payload.put("subscriptionAvailability", (api.getSubscriptionAvailability() != null ? + api.getSubscriptionAvailability() : "")); //Lists if (api.getTransport() != null) { @@ -474,55 +334,41 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { } //objects - payload.put("monetization", (api.getMonetization() != null ? new JSONObject(gson.toJson(api.getMonetization())) : null)); - payload.put("corsConfiguration", (api.getCorsConfiguration() != null ? new JSONObject(gson.toJson(api.getCorsConfiguration())) : null)); - payload.put("websubSubscriptionConfiguration", (api.getWebsubSubscriptionConfiguration() != null ? new JSONObject(gson.toJson(api.getWebsubSubscriptionConfiguration())) : null)); + payload.put("monetization", (api.getMonetization() != null ? + new JSONObject(gson.toJson(api.getMonetization())) : null)); + payload.put("corsConfiguration", (api.getCorsConfiguration() != null ? + new JSONObject(gson.toJson(api.getCorsConfiguration())) : null)); + payload.put("websubSubscriptionConfiguration", (api.getWebsubSubscriptionConfiguration() != null ? + new JSONObject(gson.toJson(api.getWebsubSubscriptionConfiguration())) : null)); payload.put("workflowStatus", (api.getWorkflowStatus() != null ? api.getWorkflowStatus() : null)); payload.put("endpointConfig", (api.getEndpointConfig() != null ? api.getEndpointConfig() : null)); - payload.put("endpointImplementationType", (api.getEndpointImplementationType() != null ? api.getEndpointImplementationType() : null)); - payload.put("threatProtectionPolicies", (api.getThreatProtectionPolicies() != null ? api.getThreatProtectionPolicies() : null)); - payload.put("serviceInfo", (api.getServiceInfo() != null ? new JSONObject(gson.toJson(api.getServiceInfo())) : null)); - payload.put("advertiseInfo", (api.getAdvertiseInfo() != null ? new JSONObject(gson.toJson(api.getAdvertiseInfo())) : null)); + payload.put("endpointImplementationType", (api.getEndpointImplementationType() != null ? + api.getEndpointImplementationType() : null)); + payload.put("threatProtectionPolicies", (api.getThreatProtectionPolicies() != null ? + api.getThreatProtectionPolicies() : null)); + payload.put("serviceInfo", (api.getServiceInfo() != null ? new JSONObject(gson.toJson(api.getServiceInfo())) + : null)); + payload.put("advertiseInfo", (api.getAdvertiseInfo() != null ? + new JSONObject(gson.toJson(api.getAdvertiseInfo())) : null)); RequestBody requestBody = RequestBody.create(JSON, payload.toString()); Request request = new Request.Builder() .url(addAPIEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { - return gson.fromJson(response.body().string(), APIInfo.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return addAPI(apiApplicationKey, refreshedAccessToken, api); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid API request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response status : " + response.code() + " Response message : " + response.message(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), APIInfo.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while creating API : [ " + api.getName() + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean updateApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIInfo api) + public boolean updateApi(APIInfo api) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String updateAPIEndPoint = endPointPrefix + Constants.API_ENDPOINT + api.getId(); JSONObject payload = new JSONObject(); @@ -546,7 +392,8 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { payload.put("apiThrottlingPolicy", api.getApiThrottlingPolicy()); payload.put("authorizationHeader", api.getAuthorizationHeader()); payload.put("visibility", api.getVisibility()); - payload.put("subscriptionAvailability", (api.getSubscriptionAvailability() != null ? api.getSubscriptionAvailability() : "")); + payload.put("subscriptionAvailability", (api.getSubscriptionAvailability() != null ? + api.getSubscriptionAvailability() : "")); //Lists if (api.getTransport() != null) { @@ -614,56 +461,41 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { } //objects - payload.put("monetization", (api.getMonetization() != null ? new JSONObject(gson.toJson(api.getMonetization())) : null)); - payload.put("corsConfiguration", (api.getCorsConfiguration() != null ? new JSONObject(gson.toJson(api.getCorsConfiguration())) : null)); - payload.put("websubSubscriptionConfiguration", (api.getWebsubSubscriptionConfiguration() != null ? new JSONObject(gson.toJson(api.getWebsubSubscriptionConfiguration())) : null)); + payload.put("monetization", (api.getMonetization() != null ? + new JSONObject(gson.toJson(api.getMonetization())) : null)); + payload.put("corsConfiguration", (api.getCorsConfiguration() != null ? + new JSONObject(gson.toJson(api.getCorsConfiguration())) : null)); + payload.put("websubSubscriptionConfiguration", (api.getWebsubSubscriptionConfiguration() != null ? + new JSONObject(gson.toJson(api.getWebsubSubscriptionConfiguration())) : null)); payload.put("workflowStatus", (api.getWorkflowStatus() != null ? api.getWorkflowStatus() : null)); payload.put("endpointConfig", (api.getEndpointConfig() != null ? api.getEndpointConfig() : null)); - payload.put("endpointImplementationType", (api.getEndpointImplementationType() != null ? api.getEndpointImplementationType() : null)); - payload.put("threatProtectionPolicies", (api.getThreatProtectionPolicies() != null ? api.getThreatProtectionPolicies() : null)); - payload.put("serviceInfo", (api.getServiceInfo() != null ? new JSONObject(gson.toJson(api.getServiceInfo())) : null)); - payload.put("advertiseInfo", (api.getAdvertiseInfo() != null ? new JSONObject(gson.toJson(api.getAdvertiseInfo())) : null)); + payload.put("endpointImplementationType", (api.getEndpointImplementationType() != null ? + api.getEndpointImplementationType() : null)); + payload.put("threatProtectionPolicies", (api.getThreatProtectionPolicies() != null ? + api.getThreatProtectionPolicies() : null)); + payload.put("serviceInfo", (api.getServiceInfo() != null ? new JSONObject(gson.toJson(api.getServiceInfo())) + : null)); + payload.put("advertiseInfo", (api.getAdvertiseInfo() != null ? + new JSONObject(gson.toJson(api.getAdvertiseInfo())) : null)); RequestBody requestBody = RequestBody.create(JSON, payload.toString()); Request request = new Request.Builder() .url(updateAPIEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .put(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return updateApi(apiApplicationKey, refreshedAccessToken, api); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid API request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while updating API : [ " + api.getName() + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean saveAsyncApiDefinition(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, String asyncApiDefinition) + public boolean saveAsyncApiDefinition(String uuid, String asyncApiDefinition) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String saveAsyncAPI = endPointPrefix + Constants.API_ENDPOINT + uuid + "/asyncapi"; RequestBody requestBody = new MultipartBody.Builder() @@ -674,33 +506,13 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { Request request = new Request.Builder() .url(saveAsyncAPI) .addHeader(Constants.HEADER_CONTENT_TYPE, "multipart/form-data") - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .put(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { //Check the response - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return saveAsyncApiDefinition(apiApplicationKey, refreshedAccessToken, uuid, asyncApiDefinition); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid API definition request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while saving async definition of the API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } @@ -708,51 +520,27 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { } @Override - public MediationPolicy[] getAllApiSpecificMediationPolicies(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String apiUuid) + public MediationPolicy[] getAllApiSpecificMediationPolicies(String apiUuid) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getAPIMediationEndPoint = endPointPrefix + Constants.API_ENDPOINT + apiUuid + "/mediation-policies"; Request request = new Request.Builder() .url(getAPIMediationEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .get() .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray mediationPolicyList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(mediationPolicyList.toString(), MediationPolicy[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return getAllApiSpecificMediationPolicies(apiApplicationKey, refreshedAccessToken, apiUuid); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray mediationPolicyList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(mediationPolicyList.toString(), MediationPolicy[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving mediation policies for API : [ " + apiUuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean addApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, Mediation mediation) - throws APIServicesException, BadRequestException, UnexpectedResponseException { - + public boolean addApiSpecificMediationPolicy(String uuid, Mediation mediation) throws APIServicesException, + BadRequestException, UnexpectedResponseException { String addAPIMediation = endPointPrefix + Constants.API_ENDPOINT + uuid + "/mediation-policies"; RequestBody requestBody = new MultipartBody.Builder() @@ -764,33 +552,13 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { Request request = new Builder() .url(addAPIMediation) .addHeader(Constants.HEADER_CONTENT_TYPE, "multipart/form-data") - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { // Check response status - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return addApiSpecificMediationPolicy(apiApplicationKey, refreshedAccessToken, uuid, mediation); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_CREATED == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while adding mediation policies for API : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } @@ -798,41 +566,20 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { } @Override - public boolean deleteApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, Mediation mediation) - throws APIServicesException, BadRequestException, UnexpectedResponseException { - - String deleteApiMediationEndPOint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/mediation-policies/" + mediation.getUuid(); + public boolean deleteApiSpecificMediationPolicy(String uuid, Mediation mediation) throws APIServicesException, + BadRequestException, UnexpectedResponseException { + String deleteApiMediationEndPOint = + endPointPrefix + Constants.API_ENDPOINT + uuid + "/mediation-policies/" + mediation.getUuid(); Request request = new Request.Builder() .url(deleteApiMediationEndPOint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .delete() .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_NO_CONTENT == response.code()) { // Check response status - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return deleteApiSpecificMediationPolicy(apiApplicationKey, refreshedAccessToken, uuid, mediation); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid mediation policy"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_NO_CONTENT == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while deleting mediation policy for API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } @@ -840,93 +587,49 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { } @Override - public boolean changeLifeCycleStatus(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, String action) + public boolean changeLifeCycleStatus(String uuid, String action) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String changeAPIStatusEndPoint = endPointPrefix + Constants.API_ENDPOINT + "change-lifecycle?apiId=" + uuid + "&action=" + action; RequestBody requestBody = RequestBody.create(JSON, Constants.EMPTY_STRING); Request request = new Request.Builder() .url(changeAPIStatusEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return changeLifeCycleStatus(apiApplicationKey, refreshedAccessToken, uuid, action); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while changing the life cycle state of the API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public APIRevision[] getAPIRevisions(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid, - Boolean deploymentStatus) + public APIRevision[] getAPIRevisions(String uuid, Boolean deploymentStatus) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getAPIRevisionsEndPoint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/revisions?query=deployed:" + deploymentStatus; Request request = new Request.Builder() .url(getAPIRevisionsEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .get() .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray revisionList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(revisionList.toString(), APIRevision[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return getAPIRevisions(apiApplicationKey, refreshedAccessToken, uuid, deploymentStatus); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray revisionList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(revisionList.toString(), APIRevision[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving API revisions for API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public APIRevision addAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIRevision apiRevision) + public APIRevision addAPIRevision(APIRevision apiRevision) throws APIServicesException, BadRequestException, UnexpectedResponseException { String addNewScope = endPointPrefix + Constants.API_ENDPOINT + apiRevision.getApiUUID() + "/revisions"; @@ -937,44 +640,25 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { RequestBody requestBody = RequestBody.create(JSON, payload.toString()); Request request = new Request.Builder() .url(addNewScope) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { - return gson.fromJson(response.body().string(), APIRevision.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return addAPIRevision(apiApplicationKey, refreshedAccessToken, apiRevision); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid API revision request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), APIRevision.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while creating API revision for API UUID : [ " + apiRevision.getApiUUID() + + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean deployAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid, - String apiRevisionId, List apiRevisionDeploymentList) + public boolean deployAPIRevision(String uuid, String apiRevisionId, + List apiRevisionDeploymentList) throws APIServicesException, BadRequestException, UnexpectedResponseException { - - String deployAPIRevisionEndPoint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/deploy-revision?revisionId=" + apiRevisionId; + String deployAPIRevisionEndPoint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/deploy-revision" + + "?revisionId=" + apiRevisionId; APIRevisionDeployment apiRevisionDeployment = apiRevisionDeploymentList.get(0); JSONArray payload = new JSONArray(); @@ -987,45 +671,25 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { RequestBody requestBody = RequestBody.create(JSON, payload.toString()); Request request = new Request.Builder() .url(deployAPIRevisionEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return deployAPIRevision(apiApplicationKey, refreshedAccessToken, uuid, apiRevisionId, - apiRevisionDeploymentList); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid API revision request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_CREATED == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while deploying API revision for API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean undeployAPIRevisionDeployment(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - APIRevision apiRevisionDeployment, String uuid) + public boolean undeployAPIRevisionDeployment(APIRevision apiRevisionDeployment, String uuid) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String undeployAPIRevisionEndPoint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/undeploy-revision?revisionId=" + String undeployAPIRevisionEndPoint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/undeploy-revision" + + "?revisionId=" + apiRevisionDeployment.getId(); List apiRevisionDeployments = apiRevisionDeployment.getDeploymentInfo(); APIRevisionDeployment earliestDeployment = apiRevisionDeployments.get(0); @@ -1040,167 +704,81 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { RequestBody requestBody = RequestBody.create(JSON, payload.toString()); Request request = new Request.Builder() .url(undeployAPIRevisionEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return undeployAPIRevisionDeployment(apiApplicationKey, refreshedAccessToken, apiRevisionDeployment, uuid); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid API revision request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_CREATED == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while undeploy API revision associated with API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean deleteAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - APIRevision apiRevision, String uuid) + public boolean deleteAPIRevision(APIRevision apiRevision, String uuid) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String apiRevisionEndPoint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/revisions/" + apiRevision.getId(); Request request = new Request.Builder() .url(apiRevisionEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .delete() .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return deleteAPIRevision(apiApplicationKey, refreshedAccessToken, apiRevision, uuid); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while deleting API revision associated with API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public Documentation[] getDocumentations(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid) + public Documentation[] getDocumentations(String uuid) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getDocumentationsEndPoint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/documents?limit=1000"; Request request = new Request.Builder() .url(getDocumentationsEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .get() .build(); try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - JSONArray documentList = (JSONArray) new JSONObject(response.body().string()).get("list"); - return gson.fromJson(documentList.toString(), Documentation[].class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return getDocumentations(apiApplicationKey, refreshedAccessToken, uuid); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + JSONArray documentList = (JSONArray) new JSONObject(response.getBody()).get("list"); + return gson.fromJson(documentList.toString(), Documentation[].class); + } catch (OAuthClientException e) { + String msg = "Error occurred while retrieving API documentation for API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean deleteDocumentations(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, String documentID) + public boolean deleteDocumentations(String uuid, String documentID) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String getDocumentationsEndPoint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/documents/" + documentID; Request request = new Request.Builder() .url(getDocumentationsEndPoint) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .delete() .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_OK == response.code()) { - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return deleteDocumentations(apiApplicationKey, refreshedAccessToken, uuid, documentID); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_OK == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while deleting API documentation associated with API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public Documentation addDocumentation(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String uuid, Documentation documentation) + public Documentation addDocumentation(String uuid, Documentation documentation) throws APIServicesException, BadRequestException, UnexpectedResponseException { - String addNewScope = endPointPrefix + Constants.API_ENDPOINT + uuid + "/documents"; JSONObject payload = new JSONObject(); @@ -1216,44 +794,23 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { Request request = new Request.Builder() .url(addNewScope) .addHeader(Constants.HEADER_CONTENT_TYPE, Constants.APPLICATION_JSON) - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { // Check response status - return gson.fromJson(response.body().string(), Documentation.class); - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return addDocumentation(apiApplicationKey, refreshedAccessToken, uuid, documentation); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid documentation request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return gson.fromJson(response.getBody(), Documentation.class); + } catch (OAuthClientException e) { + String msg = "Error occurred while creating documentation for API UUID : [ " + uuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } } @Override - public boolean addDocumentationContent(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, - String apiUuid, String docId, String docContent) + public boolean addDocumentationContent(String apiUuid, String docId, String docContent) throws APIServicesException, BadRequestException, UnexpectedResponseException { - - String addDocumentationContentEndPoint = endPointPrefix + Constants.API_ENDPOINT + apiUuid + "/documents/" + docId + "/content"; + String addDocumentationContentEndPoint = + endPointPrefix + Constants.API_ENDPOINT + apiUuid + "/documents/" + docId + "/content"; RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) @@ -1263,33 +820,13 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { Request request = new Request.Builder() .url(addDocumentationContentEndPoint) .addHeader(Constants.HEADER_CONTENT_TYPE, "multipart/form-data") - .addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER - + accessTokenInfo.getAccess_token()) .post(requestBody) .build(); - try { - Response response = client.newCall(request).execute(); - if (HttpStatus.SC_CREATED == response.code()) { // Check response status - return true; - } else if (HttpStatus.SC_UNAUTHORIZED == response.code()) { - APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); - AccessTokenInfo refreshedAccessToken = apiApplicationServices. - generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(), - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - //TODO: max attempt count - return addDocumentationContent(apiApplicationKey, refreshedAccessToken, apiUuid, docId, docContent); - } else if (HttpStatus.SC_BAD_REQUEST == response.code()) { - String msg = "Bad Request, Invalid documentation request body"; - log.error(msg); - throw new BadRequestException(msg); - } else { - String msg = "Response : " + response.code() + response.body(); - log.error(msg); - throw new UnexpectedResponseException(msg); - } - } catch (IOException e) { - String msg = "Error occurred while processing the response"; + OAuthClientResponse response = client.execute(request); + return HttpStatus.SC_CREATED == response.getCode(); + } catch (OAuthClientException e) { + String msg = "Error occurred while adding documentation content for API UUID : [ " + apiUuid + " ]"; log.error(msg, e); throw new APIServicesException(msg, e); } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/APIMConsumer/APIInfo.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/APIMConsumer/APIInfo.java index 0435fc64ec..1269006c43 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/APIMConsumer/APIInfo.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/APIMConsumer/APIInfo.java @@ -21,6 +21,7 @@ package io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Set; /** @@ -28,6 +29,20 @@ import java.util.Set; */ public class APIInfo { + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + APIInfo apiInfo = (APIInfo) o; + return Objects.equals(id, apiInfo.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } private String id; private String name; diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/APIMConsumer/Subscription.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/APIMConsumer/Subscription.java index 2ff525f5dc..488b7424cc 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/APIMConsumer/Subscription.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/APIMConsumer/Subscription.java @@ -20,7 +20,23 @@ package io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer; import org.json.JSONObject; +import java.util.Objects; + public class Subscription { + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Subscription that = (Subscription) o; + return Objects.equals(apiId, that.apiId); + } + + @Override + public int hashCode() { + return Objects.hashCode(apiId); + } private String subscriptionId; private String applicationId; diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/OAuthClientResponse.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/OAuthClientResponse.java new file mode 100644 index 0000000000..6a983bbf77 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/bean/OAuthClientResponse.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.extension.rest.api.bean; + +public class OAuthClientResponse { + private final int code; + private final String body; + private final boolean isSuccessful; + + public OAuthClientResponse(int code, String body, boolean isSuccessful) { + this.code = code; + this.body = body; + this.isSuccessful = isSuccessful; + } + + public int getCode() { + return code; + } + + public String getBody() { + return body; + } + + public boolean isSuccessful() { + return isSuccessful; + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/constants/Constants.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/constants/Constants.java index 34b4f04681..857ded894c 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/constants/Constants.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/constants/Constants.java @@ -76,4 +76,6 @@ public final class Constants { public static final String SCOPE_PUBLISH_RESERVED_USER_PASSWORD = "&gKfyE8E4rUY4Q"; public static final String ADMIN_ROLE_KEY = "admin"; public static final String PERM_SCOPE_MAPPING_META_KEY = "perm-scope-mapping"; + public static final String PLACEHOLDING_CALLBACK_URL = HTTPS_PROTOCOL + SCHEME_SEPARATOR + "localhost"; + public static final String API_PUBLISHING_ENABLED_TENANT_LIST_KEY = "api-publishing-enabled-tenant-list"; } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/exceptions/OAuthClientException.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/exceptions/OAuthClientException.java new file mode 100644 index 0000000000..ba9c223252 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/exceptions/OAuthClientException.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions; + +public class OAuthClientException extends Exception { + public OAuthClientException(String msg) { + super(msg); + } + + public OAuthClientException(String msg, Throwable throwable) { + super(msg, throwable); + } +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/internal/APIManagerServiceComponent.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/internal/APIManagerServiceComponent.java index 69015d5697..5f39fd2b9c 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/internal/APIManagerServiceComponent.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/internal/APIManagerServiceComponent.java @@ -22,6 +22,8 @@ import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationService import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServicesImpl; import io.entgra.device.mgt.core.apimgt.extension.rest.api.ConsumerRESTAPIServices; import io.entgra.device.mgt.core.apimgt.extension.rest.api.ConsumerRESTAPIServicesImpl; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.IOAuthClientService; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.OAuthClient; import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices; import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServicesImpl; import org.apache.commons.logging.Log; @@ -46,6 +48,10 @@ public class APIManagerServiceComponent { try { BundleContext bundleContext = componentContext.getBundleContext(); + IOAuthClientService ioAuthClientService = OAuthClient.getInstance(); + bundleContext.registerService(IOAuthClientService.class, ioAuthClientService, null); + APIManagerServiceDataHolder.getInstance().setIoAuthClientService(ioAuthClientService); + APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl(); bundleContext.registerService(APIApplicationServices.class.getName(), apiApplicationServices, null); APIManagerServiceDataHolder.getInstance().setApiApplicationServices(apiApplicationServices); diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/internal/APIManagerServiceDataHolder.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/internal/APIManagerServiceDataHolder.java index 3153d50a89..8522471cc4 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/internal/APIManagerServiceDataHolder.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/internal/APIManagerServiceDataHolder.java @@ -19,6 +19,7 @@ package io.entgra.device.mgt.core.apimgt.extension.rest.api.internal; import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.IOAuthClientService; import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices; import io.entgra.device.mgt.core.apimgt.extension.rest.api.ConsumerRESTAPIServices; import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService; @@ -32,6 +33,7 @@ public class APIManagerServiceDataHolder { private PublisherRESTAPIServices publisherRESTAPIServices; private RealmService realmService; private TenantManager tenantManager; + private IOAuthClientService ioAuthClientService; private static APIManagerServiceDataHolder thisInstance = new APIManagerServiceDataHolder(); @@ -40,7 +42,7 @@ public class APIManagerServiceDataHolder { private APIManagerServiceDataHolder() { } - static APIManagerServiceDataHolder getInstance() { + public static APIManagerServiceDataHolder getInstance() { return thisInstance; } @@ -102,4 +104,15 @@ public class APIManagerServiceDataHolder { public void setConsumerRESTAPIServices(ConsumerRESTAPIServices consumerRESTAPIServices) { this.consumerRESTAPIServices = consumerRESTAPIServices; } + + public IOAuthClientService getIoAuthClientService() { + if (ioAuthClientService == null) { + throw new IllegalStateException("OAuth client service is not initialized properly"); + } + return ioAuthClientService; + } + + public void setIoAuthClientService(IOAuthClientService ioAuthClientService) { + this.ioAuthClientService = ioAuthClientService; + } } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.keymgt.extension/src/main/java/io/entgra/device/mgt/core/apimgt/keymgt/extension/service/KeyMgtServiceImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.keymgt.extension/src/main/java/io/entgra/device/mgt/core/apimgt/keymgt/extension/service/KeyMgtServiceImpl.java index 2752bfb4d1..b7e531a9d7 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.keymgt.extension/src/main/java/io/entgra/device/mgt/core/apimgt/keymgt/extension/service/KeyMgtServiceImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.keymgt.extension/src/main/java/io/entgra/device/mgt/core/apimgt/keymgt/extension/service/KeyMgtServiceImpl.java @@ -447,7 +447,7 @@ public class KeyMgtServiceImpl implements KeyMgtService { ConsumerRESTAPIServices consumerRESTAPIServices = KeyMgtDataHolder.getInstance().getConsumerRESTAPIServices(); io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application[] applications = - consumerRESTAPIServices.getAllApplications(apiApplicationInfo, applicationName); + consumerRESTAPIServices.getAllApplications(applicationName); if (applications.length == 1) { return applications[0]; } else { diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java index c3e5a6bc54..acf51b77f7 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java @@ -114,11 +114,7 @@ public class APIPublisherServiceImpl implements APIPublisherService { tenants.addAll(config.getTenants().getTenant()); RealmService realmService = (RealmService) PrivilegedCarbonContext.getThreadLocalCarbonContext() .getOSGiService(RealmService.class, null); - - APIApplicationServices apiApplicationServices = APIPublisherDataHolder.getInstance().getApiApplicationServices(); PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices(); - APIApplicationKey apiApplicationKey; - AccessTokenInfo accessTokenInfo; try { boolean tenantFound = false; @@ -151,15 +147,10 @@ public class APIPublisherServiceImpl implements APIPublisherService { if (tenantFound) { PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(apiConfig.getOwner()); - int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); - + log.info("Initiating API publishing sequence for API [ " + apiConfig.getName() + "] in domain [ " + + tenantDomain + " ]"); try { APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain); - apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials( - "ClientForPublisherRestCalls", - "client_credentials password refresh_token"); - accessTokenInfo = apiApplicationServices.generateAccessTokenFromRegisteredApplication( - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); } catch (APIServicesException e) { String errorMsg = "Error occurred while generating the API application"; log.error(errorMsg, e); @@ -169,11 +160,10 @@ public class APIPublisherServiceImpl implements APIPublisherService { try { apiConfig.setOwner(APIUtil.getTenantAdminUserName(tenantDomain)); apiConfig.setTenantDomain(tenantDomain); - APIProvider apiProvider = API_MANAGER_FACTORY.getAPIProvider(apiConfig.getOwner()); APIIdentifier apiIdentifier = new APIIdentifier(APIUtil.replaceEmailDomain(apiConfig.getOwner()), apiConfig.getName(), apiConfig.getVersion()); - APIInfo[] apiList = publisherRESTAPIServices.getApis(apiApplicationKey, accessTokenInfo); + APIInfo[] apiList = publisherRESTAPIServices.getApis(); boolean apiFound = false; for (int i = 0; i < apiList.length; i++) { APIInfo apiObj = apiList[i]; @@ -187,14 +177,12 @@ public class APIPublisherServiceImpl implements APIPublisherService { String apiUuid = apiIdentifier.getUUID(); if (!apiFound) { // add new scopes as shared scopes - addNewSharedScope(apiConfig.getScopes(), publisherRESTAPIServices, apiApplicationKey, - accessTokenInfo); + addNewSharedScope(apiConfig.getScopes(), publisherRESTAPIServices); APIInfo api = getAPI(apiConfig, true); - APIInfo createdAPI = publisherRESTAPIServices.addAPI(apiApplicationKey, accessTokenInfo, api); + APIInfo createdAPI = publisherRESTAPIServices.addAPI(api); apiUuid = createdAPI.getId(); if (apiConfig.getEndpointType() != null && "WS".equals(apiConfig.getEndpointType())) { - publisherRESTAPIServices.saveAsyncApiDefinition(apiApplicationKey, accessTokenInfo, - apiUuid, apiConfig.getAsyncApiDefinition()); + publisherRESTAPIServices.saveAsyncApiDefinition(apiUuid, apiConfig.getAsyncApiDefinition()); } if (CREATED_STATUS.equals(createdAPI.getLifeCycleStatus())) { // if endpoint type "dynamic" and then add in sequence @@ -204,17 +192,14 @@ public class APIPublisherServiceImpl implements APIPublisherService { mediation.setConfig(apiConfig.getInSequenceConfig()); mediation.setType("in"); mediation.setGlobal(false); - publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey, - accessTokenInfo, apiUuid, mediation); + publisherRESTAPIServices.addApiSpecificMediationPolicy(apiUuid, mediation); } - publisherRESTAPIServices.changeLifeCycleStatus(apiApplicationKey, accessTokenInfo, - apiUuid, PUBLISH_ACTION); + publisherRESTAPIServices.changeLifeCycleStatus(apiUuid, PUBLISH_ACTION); APIRevision apiRevision = new APIRevision(); apiRevision.setApiUUID(apiUuid); apiRevision.setDescription("Initial Revision"); - String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiApplicationKey, - accessTokenInfo, apiRevision).getId(); + String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiRevision).getId(); APIRevisionDeployment apiRevisionDeployment = new APIRevisionDeployment(); apiRevisionDeployment.setName(API_PUBLISH_ENVIRONMENT); @@ -223,8 +208,7 @@ public class APIPublisherServiceImpl implements APIPublisherService { List apiRevisionDeploymentList = new ArrayList<>(); apiRevisionDeploymentList.add(apiRevisionDeployment); - publisherRESTAPIServices.deployAPIRevision(apiApplicationKey, accessTokenInfo, - apiUuid, apiRevisionId, apiRevisionDeploymentList); + publisherRESTAPIServices.deployAPIRevision(apiUuid, apiRevisionId, apiRevisionDeploymentList); } } else { if (WebappPublisherConfig.getInstance().isEnabledUpdateApi()) { @@ -248,20 +232,17 @@ public class APIPublisherServiceImpl implements APIPublisherService { // upgrade to 5.0.0 first before updating from 5.0.0 to the most recent version if we // are updating from a version that is older than 5.0.0. - addNewSharedScope(apiConfig.getScopes(), publisherRESTAPIServices, apiApplicationKey, - accessTokenInfo); + addNewSharedScope(apiConfig.getScopes(), publisherRESTAPIServices); // Get existing API - APIInfo existingAPI = publisherRESTAPIServices.getApi(apiApplicationKey, accessTokenInfo, - apiUuid); + APIInfo existingAPI = publisherRESTAPIServices.getApi(apiUuid); APIInfo api = getAPI(apiConfig, true); api.setLifeCycleStatus(existingAPI.getLifeCycleStatus()); api.setId(apiUuid); - publisherRESTAPIServices.updateApi(apiApplicationKey, accessTokenInfo, api); + publisherRESTAPIServices.updateApi(api); if (apiConfig.getEndpointType() != null && "WS".equals(apiConfig.getEndpointType())) { - publisherRESTAPIServices.saveAsyncApiDefinition(apiApplicationKey, accessTokenInfo, - apiUuid, apiConfig.getAsyncApiDefinition()); + publisherRESTAPIServices.saveAsyncApiDefinition(apiUuid, apiConfig.getAsyncApiDefinition()); } // if endpoint type "dynamic" and then add /update in sequence @@ -273,45 +254,37 @@ public class APIPublisherServiceImpl implements APIPublisherService { mediation.setGlobal(false); MediationPolicy[] mediationList = publisherRESTAPIServices - .getAllApiSpecificMediationPolicies(apiApplicationKey, accessTokenInfo, apiUuid); + .getAllApiSpecificMediationPolicies(apiUuid); boolean isMediationPolicyFound = false; for (int i = 0; i < mediationList.length; i++) { MediationPolicy mediationPolicy = mediationList[i]; if (apiConfig.getInSequenceName().equals(mediationPolicy.getName())) { mediation.setUuid(mediationPolicy.getId()); - publisherRESTAPIServices.deleteApiSpecificMediationPolicy(apiApplicationKey, - accessTokenInfo, apiUuid, mediation); - publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey, - accessTokenInfo, apiUuid, mediation); + publisherRESTAPIServices.deleteApiSpecificMediationPolicy(apiUuid, mediation); + publisherRESTAPIServices.addApiSpecificMediationPolicy(apiUuid, mediation); isMediationPolicyFound = true; break; } } if (!isMediationPolicyFound) { - publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey, - accessTokenInfo, apiUuid, mediation); + publisherRESTAPIServices.addApiSpecificMediationPolicy(apiUuid, mediation); } } - int apiRevisionCount = publisherRESTAPIServices.getAPIRevisions(apiApplicationKey, - accessTokenInfo, apiUuid, null).length; + int apiRevisionCount = publisherRESTAPIServices.getAPIRevisions(apiUuid, null).length; if (apiRevisionCount >= 5) { // This will retrieve the deployed revision - APIRevision[] revisionDeploymentList = publisherRESTAPIServices.getAPIRevisions( - apiApplicationKey, accessTokenInfo, apiUuid, true); + APIRevision[] revisionDeploymentList = publisherRESTAPIServices.getAPIRevisions(apiUuid, true); if (revisionDeploymentList.length > 0) { APIRevision latestRevisionDeployment = revisionDeploymentList[0]; - publisherRESTAPIServices.undeployAPIRevisionDeployment(apiApplicationKey, - accessTokenInfo, latestRevisionDeployment, apiUuid); + publisherRESTAPIServices.undeployAPIRevisionDeployment(latestRevisionDeployment, apiUuid); } // This will retrieve the undeployed revision list - APIRevision[] undeployedRevisionList = publisherRESTAPIServices.getAPIRevisions(apiApplicationKey, - accessTokenInfo, apiUuid, false); + APIRevision[] undeployedRevisionList = publisherRESTAPIServices.getAPIRevisions(apiUuid, false); if (undeployedRevisionList.length > 0) { APIRevision earliestUndeployRevision = undeployedRevisionList[0]; - publisherRESTAPIServices.deleteAPIRevision(apiApplicationKey, accessTokenInfo, - earliestUndeployRevision, apiUuid); + publisherRESTAPIServices.deleteAPIRevision(earliestUndeployRevision, apiUuid); } } @@ -319,8 +292,7 @@ public class APIPublisherServiceImpl implements APIPublisherService { APIRevision apiRevision = new APIRevision(); apiRevision.setApiUUID(apiUuid); apiRevision.setDescription("Updated Revision"); - String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiApplicationKey, - accessTokenInfo, apiRevision).getId(); + String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiRevision).getId(); APIRevisionDeployment apiRevisionDeployment = new APIRevisionDeployment(); apiRevisionDeployment.setName(API_PUBLISH_ENVIRONMENT); @@ -330,12 +302,10 @@ public class APIPublisherServiceImpl implements APIPublisherService { List apiRevisionDeploymentList = new ArrayList<>(); apiRevisionDeploymentList.add(apiRevisionDeployment); - publisherRESTAPIServices.deployAPIRevision(apiApplicationKey, accessTokenInfo, - apiUuid, apiRevisionId, apiRevisionDeploymentList); + publisherRESTAPIServices.deployAPIRevision(apiUuid, apiRevisionId, apiRevisionDeploymentList); if (CREATED_STATUS.equals(existingAPI.getLifeCycleStatus())) { - publisherRESTAPIServices.changeLifeCycleStatus(apiApplicationKey, accessTokenInfo, - apiUuid, PUBLISH_ACTION); + publisherRESTAPIServices.changeLifeCycleStatus(apiUuid, PUBLISH_ACTION); } } } @@ -365,27 +335,23 @@ public class APIPublisherServiceImpl implements APIPublisherService { apiDocumentation.setSummary(apiConfig.getApiDocumentationSummary()); apiDocumentation.setOtherTypeName(null); - Documentation[] documentList = publisherRESTAPIServices.getDocumentations(apiApplicationKey, - accessTokenInfo, apiUuid); + Documentation[] documentList = publisherRESTAPIServices.getDocumentations(apiUuid); if (documentList.length > 0) { for (int i = 0; i < documentList.length; i++) { Documentation existingDoc = documentList[i]; if (existingDoc.getName().equals(apiConfig.getApiDocumentationName()) && existingDoc.getType().equals(Documentation.DocumentationType.HOWTO.name())) { - publisherRESTAPIServices.deleteDocumentations(apiApplicationKey, accessTokenInfo, - apiUuid, existingDoc.getDocumentId()); + publisherRESTAPIServices.deleteDocumentations(apiUuid, existingDoc.getDocumentId()); } } } else { log.info("There is no any existing api documentation."); } - Documentation createdDoc = publisherRESTAPIServices.addDocumentation(apiApplicationKey, accessTokenInfo, - apiUuid, apiDocumentation); + Documentation createdDoc = publisherRESTAPIServices.addDocumentation(apiUuid, apiDocumentation); - publisherRESTAPIServices.addDocumentationContent(apiApplicationKey, accessTokenInfo, apiUuid, - createdDoc.getDocumentId(), docContent); + publisherRESTAPIServices.addDocumentationContent(apiUuid, createdDoc.getDocumentId(), docContent); } } catch (APIManagementException | IOException | APIServicesException | @@ -411,17 +377,13 @@ public class APIPublisherServiceImpl implements APIPublisherService { * * @param apiScopes set of API scopes * @param publisherRESTAPIServices {@link PublisherRESTAPIServices} - * @param apiApplicationKey API application Key - * @param accessTokenInfo Details of access token * @throws BadRequestException if invalid payload receives to add new shared scopes. * @throws UnexpectedResponseException if the response is not either 200 or 400. * @throws APIServicesException if error occurred while processing the response. */ - private void addNewSharedScope(Set apiScopes, PublisherRESTAPIServices publisherRESTAPIServices, - APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo) throws BadRequestException, UnexpectedResponseException, APIServicesException { + private void addNewSharedScope(Set apiScopes, PublisherRESTAPIServices publisherRESTAPIServices) throws BadRequestException, UnexpectedResponseException, APIServicesException { for (ApiScope apiScope : apiScopes) { - if (!publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, - apiScope.getKey())) { + if (!publisherRESTAPIServices.isSharedScopeNameExists(apiScope.getKey())) { Scope scope = new Scope(); scope.setName(apiScope.getKey()); scope.setDescription(apiScope.getDescription()); @@ -429,7 +391,7 @@ public class APIPublisherServiceImpl implements APIPublisherService { List bindings = new ArrayList<>(apiScope.getRoles()); bindings.add(ADMIN_ROLE_KEY); scope.setBindings(bindings); - publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope); + publisherRESTAPIServices.addNewSharedScope(scope); } } } @@ -449,20 +411,9 @@ public class APIPublisherServiceImpl implements APIPublisherService { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); - - APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain); - APIApplicationKey apiApplicationKey = - apiApplicationServices.createAndRetrieveApplicationCredentials( - "ClientForPublisherRestCalls", "client_credentials password refresh_token" - ); - AccessTokenInfo accessTokenInfo = - apiApplicationServices.generateAccessTokenFromRegisteredApplication( - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - Scope scope = new Scope(); for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) { - if (!publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, - defaultPermission.getScopeMapping().getKey())) { + if (!publisherRESTAPIServices.isSharedScopeNameExists(defaultPermission.getScopeMapping().getKey())) { ScopeMapping scopeMapping = defaultPermission.getScopeMapping(); List bindings = new ArrayList<>( @@ -472,7 +423,7 @@ public class APIPublisherServiceImpl implements APIPublisherService { scope.setDescription(scopeMapping.getName()); scope.setDisplayName(scopeMapping.getName()); scope.setBindings(bindings); - publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope); + publisherRESTAPIServices.addNewSharedScope(scope); } } } catch (BadRequestException | UnexpectedResponseException | APIServicesException e) { @@ -507,17 +458,6 @@ public class APIPublisherServiceImpl implements APIPublisherService { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); - try { - APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain); - apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials("ClientForPublisherRestCalls", - "client_credentials password refresh_token"); - accessTokenInfo = apiApplicationServices.generateAccessTokenFromRegisteredApplication( - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - } catch (APIServicesException e) { - String errorMsg = "Error occurred while generating the API application"; - log.error(errorMsg, e); - throw new APIManagerPublisherException(e); - } try { fileName = @@ -583,7 +523,7 @@ public class APIPublisherServiceImpl implements APIPublisherService { } } //Set scope details which related to the scope key - Scope[] scopes = publisherRESTAPIServices.getScopes(apiApplicationKey, accessTokenInfo); + Scope[] scopes = publisherRESTAPIServices.getScopes(); for (int i = 0; i < scopes.length; i++) { Scope relatedScope = scopes[i]; if (relatedScope.getName().equals(scopeMapping[2].toString())) { @@ -595,13 +535,13 @@ public class APIPublisherServiceImpl implements APIPublisherService { } scope.setBindings(rolesList); - if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) { - publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope); + if (publisherRESTAPIServices.isSharedScopeNameExists(scope.getName())) { + publisherRESTAPIServices.updateSharedScope(scope); // todo: permission changed in update path, is not handled yet. } else { // This scope doesn't have an api attached. log.warn(scope.getName() + " not available as shared, add as new scope"); - publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope); + publisherRESTAPIServices.addNewSharedScope(scope); // add permission if not exist try { PermissionUtils.putPermission(permission); @@ -647,32 +587,17 @@ public class APIPublisherServiceImpl implements APIPublisherService { String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); APIApplicationServices apiApplicationServices = APIPublisherDataHolder.getInstance().getApiApplicationServices(); PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices(); - APIApplicationKey apiApplicationKey; - AccessTokenInfo accessTokenInfo; - try { - APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain); - apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials( - "ClientForPublisherRestCalls", - "client_credentials password refresh_token" - ); - accessTokenInfo = apiApplicationServices.generateAccessTokenFromRegisteredApplication( - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - } catch (APIServicesException e) { - String errorMsg = "Error occurred while generating the API application"; - log.error(errorMsg, e); - throw new APIManagerPublisherException(e); - } try { - Scope[] scopeList = publisherRESTAPIServices.getScopes(apiApplicationKey, accessTokenInfo); + Scope[] scopeList = publisherRESTAPIServices.getScopes(); Map permScopeMap = APIPublisherDataHolder.getInstance().getPermScopeMapping(); if (permissions.length != 0) { - updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, permissions, permScopeMap, false); + updateScopes(roleName, publisherRESTAPIServices, scopeList, permissions, permScopeMap, false); } if (removedPermissions.length != 0) { - updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, removedPermissions, permScopeMap, true); + updateScopes(roleName, publisherRESTAPIServices, scopeList, removedPermissions, permScopeMap, true); } try { @@ -704,8 +629,6 @@ public class APIPublisherServiceImpl implements APIPublisherService { * * @param roleName Role Name * @param publisherRESTAPIServices {@link PublisherRESTAPIServices} - * @param apiApplicationKey {@link APIApplicationKey} - * @param accessTokenInfo {@link AccessTokenInfo} * @param scopeList scope list returning from APIM * @param permissions List of permissions * @param permScopeMap Permission Scope map @@ -713,7 +636,6 @@ public class APIPublisherServiceImpl implements APIPublisherService { * @throws APIManagerPublisherException If the method receives invalid permission to update. */ private void updateScopes (String roleName, PublisherRESTAPIServices publisherRESTAPIServices, - APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope[] scopeList, String[] permissions, Map permScopeMap, boolean removingPermissions ) throws APIManagerPublisherException { for (String permission : permissions) { @@ -752,8 +674,8 @@ public class APIPublisherServiceImpl implements APIPublisherService { scope.setBindings(existingRoleList); try { - if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) { - publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope); + if (publisherRESTAPIServices.isSharedScopeNameExists(scope.getName())) { + publisherRESTAPIServices.updateSharedScope(scope); } else { // todo: come to this level means, that scope is removed from API, but haven't removed from the scope-role-permission-mappings list log.warn(scope.getName() + " not available as shared scope"); diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java index bd3451c4e3..115a944282 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java @@ -20,6 +20,8 @@ package io.entgra.device.mgt.core.apimgt.webapp.publisher; import com.google.gson.Gson; import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants; +import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.Tenants; +import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.WebappPublisherConfig; import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope; import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException; import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder; @@ -37,9 +39,13 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.core.ServerStartupObserver; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Stack; public class APIPublisherStartupHandler implements ServerStartupObserver { @@ -112,6 +118,7 @@ public class APIPublisherStartupHandler implements ServerStartupObserver { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); + updateApiPublishingEnabledTenants(tenantDomain); updateScopeMetadataEntryWithDefaultScopes(); } finally { PrivilegedCarbonContext.endTenantFlow(); @@ -202,4 +209,31 @@ public class APIPublisherStartupHandler implements ServerStartupObserver { log.error("Error encountered while updating permission scope mapping metadata with default scopes"); } } + + private void updateApiPublishingEnabledTenants(String superTenantDomain) { + MetadataManagementService metadataManagementService = APIPublisherDataHolder.getInstance().getMetadataManagementService(); + WebappPublisherConfig webappPublisherConfig = WebappPublisherConfig.getInstance(); + + Metadata tenantsEntry = new Metadata(); + List tenants = new ArrayList<>(); + + tenants.add(superTenantDomain); + tenants.addAll(webappPublisherConfig.getTenants().getTenant()); + + tenantsEntry.setMetaKey(Constants.API_PUBLISHING_ENABLED_TENANT_LIST_KEY); + tenantsEntry.setMetaValue(gson.toJson(tenants)); + + try { + if (metadataManagementService.retrieveMetadata(Constants.API_PUBLISHING_ENABLED_TENANT_LIST_KEY) == null) { + metadataManagementService.createMetadata(tenantsEntry); + return; + } + + metadataManagementService.updateMetadata(tenantsEntry); + } catch (MetadataKeyAlreadyExistsException e) { + log.error("Metadata entry already exists for " + Constants.API_PUBLISHING_ENABLED_TENANT_LIST_KEY); + } catch (MetadataManagementException e) { + log.error("Error encountered while updating api publish enabled tenants metadata with default scopes"); + } + } } diff --git a/components/apimgt-extensions/pom.xml b/components/apimgt-extensions/pom.xml index 3d2c974ad5..22a10509de 100644 --- a/components/apimgt-extensions/pom.xml +++ b/components/apimgt-extensions/pom.xml @@ -37,8 +37,8 @@ io.entgra.device.mgt.core.apimgt.application.extension io.entgra.device.mgt.core.apimgt.application.extension.api io.entgra.device.mgt.core.apimgt.annotations - io.entgra.device.mgt.core.apimgt.keymgt.extension - io.entgra.device.mgt.core.apimgt.keymgt.extension.api + + io.entgra.device.mgt.core.apimgt.analytics.extension io.entgra.device.mgt.core.apimgt.extension.rest.api diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/OAuthUtils.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/OAuthUtils.java index 96e4c40fd1..581ea51301 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/OAuthUtils.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/OAuthUtils.java @@ -19,8 +19,13 @@ package io.entgra.device.mgt.core.application.mgt.core.util; import io.entgra.device.mgt.core.apimgt.application.extension.APIManagementProviderService; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.ApiApplicationProfile; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.IdnAuthenticationProfile; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; +import io.entgra.device.mgt.core.apimgt.application.extension.exception.IdnAuthenticationException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; import io.entgra.device.mgt.core.application.mgt.common.dto.ApiRegistrationProfile; import io.entgra.device.mgt.core.identity.jwt.client.extension.JWTClient; import io.entgra.device.mgt.core.identity.jwt.client.extension.dto.AccessTokenInfo; @@ -58,15 +63,26 @@ public class OAuthUtils { String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() .getRealmConfiguration().getAdminUserName(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username); + String password = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminPassword(); PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); APIManagementProviderService apiManagementProviderService = (APIManagementProviderService) ctx. getOSGiService(APIManagementProviderService.class, null); + + IdnAuthenticationProfile idnAuthenticationProfile = new IdnAuthenticationProfile(); + idnAuthenticationProfile.setUsername(username); + idnAuthenticationProfile.setPassword(password); + + ApiApplicationProfile apiApplicationProfile = new ApiApplicationProfile(); + apiApplicationProfile.setApplicationName(registrationProfile.getApplicationName()); + apiApplicationProfile.setTags(registrationProfile.getTags()); + apiApplicationProfile.setGrantTypes("refresh_token client_credentials password"); apiApplicationKeyInfo = apiManagementProviderService. - generateAndRetrieveApplicationKeys(registrationProfile.getApplicationName(), - registrationProfile.getTags(), Constants.ApplicationInstall.DEFAULT_TOKEN_TYPE, - username, registrationProfile.isAllowedToAllDomains(), - Constants.ApplicationInstall.DEFAULT_VALIDITY_PERIOD, PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminPassword(), null, null, null, false); + registerApiApplication(idnAuthenticationProfile, apiApplicationProfile); + } catch (IdnAuthenticationException | BadRequestException | UnexpectedResponseException e) { + String msg = "Error encountered while registering api application"; + log.error(msg); + throw new APIManagerException(msg, e); } finally { PrivilegedCarbonContext.endTenantFlow(); } @@ -80,7 +96,7 @@ public class OAuthUtils { JWTClientManagerService jwtClientManagerService = (JWTClientManagerService) ctx. getOSGiService(JWTClientManagerService.class, null); JWTClient jwtClient = jwtClientManagerService.getJWTClient(); - return jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(), apiApplicationKey.getConsumerSecret(), + return jwtClient.getAccessToken(apiApplicationKey.getClient_id(), apiApplicationKey.getClient_secret(), username, Constants.ApplicationInstall.SUBSCRIPTION_SCOPE); } catch (JWTClientException e) { String errorMsg = "Error while generating an OAuth token for user " + username; diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java index afaab6c01d..2ad038ae57 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -19,22 +19,15 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; import io.entgra.device.mgt.core.apimgt.application.extension.APIManagementProviderService; -import io.entgra.device.mgt.core.apimgt.application.extension.APIManagementProviderServiceImpl; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.ApiApplicationProfile; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.IdnAuthenticationProfile; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; -import io.entgra.device.mgt.core.apimgt.application.extension.internal.APIApplicationManagerExtensionDataHolder; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServicesImpl; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey; -import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException; -import io.entgra.device.mgt.core.apimgt.keymgt.extension.DCRResponse; -import io.entgra.device.mgt.core.apimgt.keymgt.extension.TokenRequest; -import io.entgra.device.mgt.core.apimgt.keymgt.extension.TokenResponse; -import io.entgra.device.mgt.core.apimgt.keymgt.extension.exception.KeyMgtException; -import io.entgra.device.mgt.core.apimgt.keymgt.extension.service.KeyMgtService; -import io.entgra.device.mgt.core.apimgt.keymgt.extension.service.KeyMgtServiceImpl; +import io.entgra.device.mgt.core.apimgt.application.extension.exception.IdnAuthenticationException; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.Token; +import io.entgra.device.mgt.core.apimgt.application.extension.bean.TokenCreationProfile; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException; import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException; @@ -135,7 +128,6 @@ import java.util.List; import java.util.Properties; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ExecutionException; @Path("/devices") public class DeviceManagementServiceImpl implements DeviceManagementService { @@ -956,51 +948,46 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { } String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); String applicationName = type.replace(" ", "").replace("_", "") + "_" + tenantDomain; - KeyMgtService keyMgtService = new KeyMgtServiceImpl(); + APIManagementProviderService apiManagementProviderService = DeviceMgtAPIUtils.getAPIManagementService(); + try { ApiApplicationKey apiApplicationKey; try { - APIApplicationServices apiApplicationServices = DeviceMgtAPIUtils.getApiApplicationServices(); - APIApplicationKey adminDCRResponse = apiApplicationServices.createAndRetrieveApplicationCredentials( - "ClientForJWTTokenGeneration", - "client_credentials password refresh_token urn:ietf:params:oauth:grant-type:jwt-bearer" - ); - - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - JWTClientManagerService jwtClientManagerService = (JWTClientManagerService) ctx. - getOSGiService(JWTClientManagerService.class, null); - JWTClient jwtClient = jwtClientManagerService.getJWTClient(); - AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(adminDCRResponse.getClientId(), - adminDCRResponse.getClientSecret(), - username, "appm:subscribe apim:admin apim:api_key apim:app_import_export apim:app_manage" + - " apim:store_settings apim:sub_alert_manage apim:sub_manage apim:subscribe openid perm:device:enroll " + - "perm:devices:details perm:devices:features perm:devices:search perm:devices:view perm:groups:groups " + - "perm:users:send-invitation"); - - APIManagementProviderService apiManagementProviderService = DeviceMgtAPIUtils.getAPIManagementService(); - apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(applicationName, - new String[] {"device_management"}, "PRODUCTION", null, false, String.valueOf(validityTime), - null, accessTokenInfo.getAccessToken(), null, null,true); - - } catch (JWTClientException e) { - String msg = "Error while generating an application tokens for Tenant Admin."; + String adminUserName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName(); + String adminPassword = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminPassword(); + + IdnAuthenticationProfile idnAuthenticationProfile = new IdnAuthenticationProfile(); + idnAuthenticationProfile.setUsername(adminUserName); + idnAuthenticationProfile.setPassword(adminPassword); + + ApiApplicationProfile apiApplicationProfile = new ApiApplicationProfile(); + apiApplicationProfile.setApplicationName(applicationName); + apiApplicationProfile.setTags(new String[] {"device_management"}); + apiApplicationProfile.setGrantTypes("client_credentials password refresh_token"); + + apiApplicationKey = apiManagementProviderService.registerApiApplication(idnAuthenticationProfile, apiApplicationProfile); + } catch (UserStoreException e) { + String msg = "Failed to retrieve the tenant" + tenantDomain + "'"; log.error(msg, e); return Response.serverError().entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (APIServicesException e) { - String msg = "Error while generating api Application"; + } catch (IdnAuthenticationException | + io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException | + UnexpectedResponseException e) { + String msg = "Error encountered while registering api application"; log.error(msg, e); return Response.serverError().entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } //todo call REST APIs - deviceConfig.setClientId(apiApplicationKey.getConsumerKey()); - deviceConfig.setClientSecret(apiApplicationKey.getConsumerSecret()); + deviceConfig.setClientId(apiApplicationKey.getClient_id()); + deviceConfig.setClientSecret(apiApplicationKey.getClient_secret()); StringBuilder scopes = new StringBuilder("device:" + type.replace(" ", "") + ":" + id); for (String topic : mqttEventTopicStructure) { @@ -1018,13 +1005,15 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { // add scopes for update operation /tenantDomain/deviceType/deviceId/update/operation scopes.append(" perm:topic:pub:" + tenantDomain + ":" + type + ":" + id + ":update:operation"); - TokenRequest tokenRequest = new TokenRequest(apiApplicationKey.getConsumerKey(), - apiApplicationKey.getConsumerSecret(), - null, scopes.toString(), "client_credentials", null, - null, null, null, validityTime); - TokenResponse tokenResponse = keyMgtService.generateAccessToken(tokenRequest); - deviceConfig.setAccessToken(tokenResponse.getAccessToken()); - deviceConfig.setRefreshToken(tokenResponse.getRefreshToken()); + TokenCreationProfile tokenCreationProfile = new TokenCreationProfile(); + tokenCreationProfile.setGrantType("client_credentials"); + tokenCreationProfile.setScope(scopes.toString()); + tokenCreationProfile.setBasicAuthUsername(apiApplicationKey.getClient_id()); + tokenCreationProfile.setBasicAuthPassword(apiApplicationKey.getClient_secret()); + + Token token = apiManagementProviderService.getToken(tokenCreationProfile); + deviceConfig.setAccessToken(token.getAccess_token()); + deviceConfig.setRefreshToken(token.getRefresh_token()); try { deviceConfig.setPlatformConfiguration(deviceManagementProviderService.getConfiguration(type)); @@ -1039,16 +1028,6 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { deviceConfig.setHttpGateway("http://" + System.getProperty("iot.gateway.host") + ":" + System.getProperty("iot.gateway.http.port")); deviceConfig.setHttpsGateway("https://" + System.getProperty("iot.gateway.host") + ":" + System.getProperty("iot.gateway.https.port")); - } catch (KeyMgtException e) { - String msg = "Error occurred while creating oauth application, device id : " + id + ", device type : " + type; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (io.entgra.device.mgt.core.apimgt.keymgt.extension.exception.BadRequestException e) { - String msg = "Error occurred while generating token, device id : " + id + ", device type : " + type; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } catch (APIManagerException e) { String msg = "Error while calling rest Call for application key generation"; log.error(msg, e); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/TenantCreateObserver.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/TenantCreateObserver.java index 9f1ce69d12..ad8c8a062c 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/TenantCreateObserver.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/TenantCreateObserver.java @@ -142,36 +142,18 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser */ private void publishScopesToTenant(String tenantDomain) throws TenantManagementException { if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { - APIApplicationServices apiApplicationServices = DeviceManagementDataHolder.getInstance().getApiApplicationServices(); - APIApplicationKey apiApplicationKey; - AccessTokenInfo accessTokenInfo; - try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); - - APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain); - apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials( - "ClientForScopePublish", - "client_credentials password refresh_token"); - accessTokenInfo = apiApplicationServices.generateAccessTokenFromRegisteredApplication( - apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()); - } catch (APIServicesException e) { - msg = "Error occurred while generating the API application for tenant: '" + tenantDomain + "'."; - log.error(msg, e); - throw new TenantManagementException(msg, e); - } - - try { PublisherRESTAPIServices publisherRESTAPIServices = DeviceManagementDataHolder.getInstance().getPublisherRESTAPIServices(); - Scope[] superTenantScopes = getAllScopesFromSuperTenant(apiApplicationServices, publisherRESTAPIServices); + Scope[] superTenantScopes = getAllScopesFromSuperTenant(publisherRESTAPIServices); if (superTenantScopes != null) { if (log.isDebugEnabled()) { log.debug("Number of super tenant scopes already published - " + superTenantScopes.length); } - Scope[] subTenantScopes = publisherRESTAPIServices.getScopes(apiApplicationKey, accessTokenInfo); + Scope[] subTenantScopes = publisherRESTAPIServices.getScopes(); if (subTenantScopes.length > 0) { // If there is already existing scopes on the sub tenant space then do a comparison with the @@ -211,8 +193,7 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser if (log.isDebugEnabled()) { log.debug("Starting to add new/updated shared scopes to the tenant: '" + tenantDomain + "'."); } - publishSharedScopes(missingScopes, publisherRESTAPIServices, apiApplicationKey, - accessTokenInfo); + publishSharedScopes(missingScopes, publisherRESTAPIServices); } for (Scope subTenantScope : subTenantScopes) { @@ -242,10 +223,9 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser log.debug("Starting to delete shared scopes from the tenant: '" + tenantDomain + "'."); } for (Scope deletedScope : deletedScopes) { - if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, - deletedScope.getName())) { + if (publisherRESTAPIServices.isSharedScopeNameExists(deletedScope.getName())) { Scope scope = createScopeObject(deletedScope); - publisherRESTAPIServices.deleteSharedScope(apiApplicationKey, accessTokenInfo, scope); + publisherRESTAPIServices.deleteSharedScope(scope); } } } @@ -254,8 +234,7 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser log.debug("Starting to publish shared scopes to newly created tenant: '" + tenantDomain + "'."); } - publishSharedScopes(Arrays.asList(superTenantScopes), publisherRESTAPIServices, - apiApplicationKey, accessTokenInfo); + publishSharedScopes(Arrays.asList(superTenantScopes), publisherRESTAPIServices); } } else { msg = "Unable to publish scopes to sub tenants due to super tenant scopes list being empty."; @@ -334,15 +313,13 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser /** * Get all the scopes from the super tenant space - * @param apiApplicationServices {@link APIApplicationServices} is used to create an OAuth application and retrieve client ID and secret * @param publisherRESTAPIServices {@link PublisherRESTAPIServices} is used to get all scopes under a given tenant using client credentials * @return array of {@link Scope} * @throws BadRequestException if an invalid request is sent to the API Manager Publisher REST API Service * @throws UnexpectedResponseException if an unexpected response is received from the API Manager Publisher REST API Service * @throws TenantManagementException if an error occurred while processing the request sent to API Manager Publisher REST API Service */ - private Scope[] getAllScopesFromSuperTenant(APIApplicationServices apiApplicationServices, - PublisherRESTAPIServices publisherRESTAPIServices) throws BadRequestException, + private Scope[] getAllScopesFromSuperTenant(PublisherRESTAPIServices publisherRESTAPIServices) throws BadRequestException, UnexpectedResponseException, TenantManagementException { try { @@ -350,12 +327,7 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser // in order to see if any new scopes were added or deleted PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); - APIApplicationKey superTenantApiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials( - "ClientForScopePublish", - "client_credentials password refresh_token"); - AccessTokenInfo superTenantAccessToken = apiApplicationServices.generateAccessTokenFromRegisteredApplication( - superTenantApiApplicationKey.getClientId(), superTenantApiApplicationKey.getClientSecret()); - return publisherRESTAPIServices.getScopes(superTenantApiApplicationKey, superTenantAccessToken); + return publisherRESTAPIServices.getScopes(); } catch (APIServicesException e) { msg = "Error occurred while retrieving access token from super tenant"; log.error(msg, e); @@ -369,21 +341,17 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser * Add shared scopes to the tenant space. * @param scopeList {@link List} of {@link Scope} * @param publisherRESTAPIServices {@link PublisherRESTAPIServices} is used to add shared scopes to a given tenant using client credentials - * @param apiApplicationKey {@link APIApplicationKey} contains client credentials of the OAuth application - * @param accessTokenInfo {@link AccessTokenInfo} contains token information generated from the client credentials * @throws BadRequestException if an invalid request is sent to the API Manager Publisher REST API Service * @throws UnexpectedResponseException if an unexpected response is received from the API Manager Publisher REST API Service * @throws APIServicesException if an error occurred while processing the request sent to API Manager Publisher REST API Service */ - private void publishSharedScopes (List scopeList, PublisherRESTAPIServices publisherRESTAPIServices, - APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo) + private void publishSharedScopes (List scopeList, PublisherRESTAPIServices publisherRESTAPIServices) throws BadRequestException, UnexpectedResponseException, APIServicesException { for (Scope tenantScope : scopeList) { - if (!publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, - tenantScope.getName())) { + if (!publisherRESTAPIServices.isSharedScopeNameExists(tenantScope.getName())) { Scope scope = createScopeObject(tenantScope); - publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope); + publisherRESTAPIServices.addNewSharedScope(scope); } } } diff --git a/features/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.feature/src/main/resources/synapse-configs/default/api/_API_Application_Registration_.xml b/features/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.feature/src/main/resources/synapse-configs/default/api/_API_Application_Registration_.xml index ac1a28320b..6434dd349f 100644 --- a/features/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.feature/src/main/resources/synapse-configs/default/api/_API_Application_Registration_.xml +++ b/features/apimgt-extensions/io.entgra.device.mgt.core.apimgt.application.extension.feature/src/main/resources/synapse-configs/default/api/_API_Application_Registration_.xml @@ -55,25 +55,6 @@ - - - - - - - - - 60000 - fault - - - - - - - - - diff --git a/features/apimgt-extensions/pom.xml b/features/apimgt-extensions/pom.xml index 3906798627..2354407942 100644 --- a/features/apimgt-extensions/pom.xml +++ b/features/apimgt-extensions/pom.xml @@ -36,7 +36,7 @@ io.entgra.device.mgt.core.apimgt.webapp.publisher.feature io.entgra.device.mgt.core.apimgt.application.extension.feature - io.entgra.device.mgt.core.apimgt.keymgt.extension.feature + io.entgra.device.mgt.core.apimgt.analytics.extension.feature io.entgra.device.mgt.core.apimgt.extension.rest.api.feature