mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Add improvements to api application registation logic
This commit is contained in:
parent
a45820e845
commit
40a5b00f80
@ -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();
|
||||
}
|
||||
}
|
||||
ApiApplicationProfile apiApplicationProfile = new ApiApplicationProfile();
|
||||
apiApplicationProfile.setApplicationName(registrationProfile.getApplicationName());
|
||||
apiApplicationProfile.setTags(registrationProfile.getTags());
|
||||
apiApplicationProfile.setCallbackUrl(registrationProfile.getCallbackUrl());
|
||||
apiApplicationProfile.setGrantTypes(String.join(" ", registrationProfile.getSupportedGrantTypes()));
|
||||
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(PrivilegedCarbonContext.
|
||||
getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration().getAdminUserName());
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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<Object>, MessageBodyReader<Object> {
|
||||
|
||||
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<Object> objectClass, Type type, Annotation[] annotations, MediaType mediaType,
|
||||
MultivaluedMap<String, String> 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<String, Object> stringObjectMultivaluedMap, OutputStream entityStream)
|
||||
throws IOException, WebApplicationException {
|
||||
|
||||
OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8);
|
||||
try {
|
||||
getGson().toJson(object, type, writer);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -31,9 +31,11 @@
|
||||
</bean>
|
||||
</jaxrs:serviceBeans>
|
||||
<jaxrs:providers>
|
||||
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
|
||||
<ref bean="jsonProvider"/>
|
||||
</jaxrs:providers>
|
||||
</jaxrs:server>
|
||||
|
||||
<bean id="jsonProvider" class="io.entgra.device.mgt.core.apimgt.application.extension.api.common.GsonMessageBodyHandler"/>
|
||||
|
||||
</beans>
|
||||
|
||||
|
||||
@ -37,12 +37,12 @@
|
||||
</servlet-mapping>
|
||||
<context-param>
|
||||
<param-name>doAuthentication</param-name>
|
||||
<param-value>true</param-value>
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
<!--This is to support basic auth.-->
|
||||
<context-param>
|
||||
<param-name>basicAuth</param-name>
|
||||
<param-value>true</param-value>
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
|
||||
<!--publish to apim-->
|
||||
@ -59,10 +59,10 @@
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
|
||||
<filter>
|
||||
<filter-name>ApiPermissionFilter</filter-name>
|
||||
<filter-class>io.entgra.device.mgt.core.apimgt.application.extension.api.filter.ApiPermissionFilter</filter-class>
|
||||
</filter>
|
||||
<!-- <filter>-->
|
||||
<!-- <filter-name>ApiPermissionFilter</filter-name>-->
|
||||
<!-- <filter-class>io.entgra.device.mgt.core.apimgt.application.extension.api.filter.ApiPermissionFilter</filter-class>-->
|
||||
<!-- </filter>-->
|
||||
|
||||
<filter>
|
||||
<filter-name>HttpHeaderSecurityFilter</filter-name>
|
||||
@ -100,9 +100,9 @@
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>ApiPermissionFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
<!-- <filter-mapping>-->
|
||||
<!-- <filter-name>ApiPermissionFilter</filter-name>-->
|
||||
<!-- <url-pattern>/*</url-pattern>-->
|
||||
<!-- </filter-mapping>-->
|
||||
|
||||
</web-app>
|
||||
|
||||
@ -46,6 +46,12 @@
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
@ -88,7 +94,11 @@
|
||||
<artifactId>io.entgra.device.mgt.core.device.mgt.common</artifactId>
|
||||
<!-- <scope>provided</scope>-->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@ -122,6 +132,7 @@
|
||||
<Bundle-Description>API Management Application Bundle</Bundle-Description>
|
||||
<Private-Package>io.entgra.device.mgt.core.apimgt.application.extension.internal</Private-Package>
|
||||
<Import-Packages>
|
||||
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,
|
||||
|
||||
@ -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<String> supportedGrantTypes,
|
||||
String callbackUrl,
|
||||
boolean isMappingRequired) throws APIManagerException;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
Token getToken(TokenCreationProfile tokenCreationProfile) 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.
|
||||
* 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
|
||||
*/
|
||||
AccessTokenInfo getAccessToken(String scopes, String[] tags, String applicationName, String
|
||||
tokenType, String validityPeriod, String username)
|
||||
throws APIManagerException;
|
||||
|
||||
ApiApplicationKey registerApiApplication(IdnAuthenticationProfile idnAuthenticationProfile,
|
||||
ApiApplicationProfile apiApplicationProfile)
|
||||
throws IdnAuthenticationException, APIManagerException, BadRequestException, UnexpectedResponseException;
|
||||
}
|
||||
|
||||
@ -18,56 +18,227 @@
|
||||
|
||||
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.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 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.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;
|
||||
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();
|
||||
|
||||
private static JSONObject generateRequestBody(TokenCreationProfile tokenCreationProfile) {
|
||||
JSONObject requestBody = new JSONObject();
|
||||
|
||||
if ("password".equals(tokenCreationProfile.getGrantType())) {
|
||||
requestBody.put("username", tokenCreationProfile.getUsername());
|
||||
requestBody.put("password", tokenCreationProfile.getPassword());
|
||||
}
|
||||
|
||||
if ("refresh_token".equals(tokenCreationProfile.getGrantType())) {
|
||||
requestBody.put("refresh_token", tokenCreationProfile.getRefreshToken());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
List<Application> applications =
|
||||
Arrays.asList(consumerRESTAPIServices.getAllApplications(apiApplicationProfile.getApplicationName()));
|
||||
|
||||
if (applications.size() > 1) {
|
||||
String msg = "Found more than one application with the same application name : [ " +
|
||||
apiApplicationProfile.getApplicationName() + " ]";
|
||||
throw new APIManagerException(msg);
|
||||
}
|
||||
|
||||
Set<APIInfo> apis = new HashSet<>();
|
||||
for (String tag : apiApplicationProfile.getTags()) {
|
||||
Map<String, String> 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) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static ApiApplicationKey updateAndRetrieveApplicationKeys(Application application,
|
||||
ApiApplicationProfile apiApplicationProfile,
|
||||
Set<APIInfo> apis)
|
||||
throws BadRequestException, UnexpectedResponseException, APIServicesException, APIManagerException {
|
||||
ConsumerRESTAPIServices consumerRESTAPIServices =
|
||||
APIApplicationManagerExtensionDataHolder.getInstance().getConsumerRESTAPIServices();
|
||||
|
||||
List<Subscription> availableSubscriptions =
|
||||
Arrays.asList(consumerRESTAPIServices.getAllSubscriptions(application.getApplicationId()));
|
||||
List<Subscription> allSubscriptions = constructSubscriptionList(application.getApplicationId(), apis);
|
||||
|
||||
List<Subscription> newSubscriptions = new ArrayList<>();
|
||||
for (Subscription subscription : allSubscriptions) {
|
||||
if (!availableSubscriptions.contains(subscription)) {
|
||||
newSubscriptions.add(subscription);
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationKey[] applicationKeys = consumerRESTAPIServices.getAllKeys(application.getApplicationId());
|
||||
if (applicationKeys.length == 0) {
|
||||
return generateApplicationKeys(application.getApplicationId(), apiApplicationProfile.getGrantTypes(),
|
||||
apiApplicationProfile.getCallbackUrl());
|
||||
}
|
||||
|
||||
ApplicationKey applicationKey = applicationKeys[0];
|
||||
|
||||
// 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))));
|
||||
|
||||
if (isGrantsAreUpdated) {
|
||||
consumerRESTAPIServices.deleteApplication(application.getApplicationId());
|
||||
return createAndRetrieveApplicationKeys(apiApplicationProfile, apis);
|
||||
}
|
||||
|
||||
if (!newSubscriptions.isEmpty()) {
|
||||
consumerRESTAPIServices.createSubscriptions(newSubscriptions);
|
||||
}
|
||||
|
||||
return new ApiApplicationKey(applicationKey.getConsumerKey(), applicationKey.getConsumerSecret());
|
||||
}
|
||||
|
||||
private static ApiApplicationKey createAndRetrieveApplicationKeys(ApiApplicationProfile apiApplicationProfile,
|
||||
Set<APIInfo> apis)
|
||||
throws BadRequestException, UnexpectedResponseException, APIServicesException, APIManagerException {
|
||||
ConsumerRESTAPIServices consumerRESTAPIServices =
|
||||
APIApplicationManagerExtensionDataHolder.getInstance().getConsumerRESTAPIServices();
|
||||
|
||||
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<Subscription> subscriptions = constructSubscriptionList(application.getApplicationId(), apis);
|
||||
|
||||
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();
|
||||
|
||||
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<Subscription> constructSubscriptionList(String applicationId, Set<APIInfo> apiInfos) {
|
||||
return apiInfos.stream().map(apiInfo -> {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setApplicationId(applicationId);
|
||||
subscription.setApiId(apiInfo.getId());
|
||||
subscription.setThrottlingPolicy(UNLIMITED_TIER);
|
||||
return subscription;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTierLoaded() {
|
||||
@ -85,353 +256,81 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ApiApplicationKey generateAndRetrieveApplicationKeys(String applicationName, String[] tags,
|
||||
String keyType, String username,
|
||||
boolean isAllowedAllDomains,
|
||||
String validityTime,
|
||||
String password, String accessToken,
|
||||
ArrayList<String> supportedGrantTypes,
|
||||
String callbackUrl,
|
||||
boolean isMappingRequired)
|
||||
throws APIManagerException {
|
||||
public Token getToken(TokenCreationProfile tokenCreationProfile) throws APIManagerException {
|
||||
JSONObject requestBody = generateRequestBody(tokenCreationProfile);
|
||||
|
||||
ApiApplicationInfo apiApplicationInfo = new ApiApplicationInfo();
|
||||
if (StringUtils.isEmpty(accessToken)) {
|
||||
apiApplicationInfo = getApplicationInfo(username, password);
|
||||
} else {
|
||||
apiApplicationInfo.setAccess_token(accessToken);
|
||||
}
|
||||
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();
|
||||
|
||||
ConsumerRESTAPIServices consumerRESTAPIServices =
|
||||
APIApplicationManagerExtensionDataHolder.getInstance().getConsumerRESTAPIServices();
|
||||
|
||||
try {
|
||||
Map<String, String> headerParams = new HashMap<>();
|
||||
if (!"carbon.super".equals(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true))) {
|
||||
headerParams.put("X-WSO2-Tenant", "carbon.super");
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (response.isSuccessful()) {
|
||||
return gson.fromJson(response.body() != null ? response.body().string() : null, Token.class);
|
||||
}
|
||||
|
||||
Map<String, APIInfo> uniqueApiSet = new HashMap<>();
|
||||
if (tags != null) {
|
||||
for (String tag : tags) {
|
||||
Map<String, String> queryParams = new HashMap<>();
|
||||
queryParams.put("tag", tag);
|
||||
String msg = "Error response [ " + response.code() + " ] received for the token acquiring request";
|
||||
log.error(msg);
|
||||
throw new APIManagerException(msg);
|
||||
|
||||
APIInfo[] apiInfos = consumerRESTAPIServices.getAllApis(apiApplicationInfo, queryParams, headerParams);
|
||||
Arrays.stream(apiInfos).forEach(apiInfo -> uniqueApiSet.putIfAbsent(apiInfo.getName(), apiInfo));
|
||||
}
|
||||
}
|
||||
|
||||
List<APIInfo> 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<io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.APIMConsumer.Application> 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);
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
} catch (IOException e) {
|
||||
String msg = "Error encountered while sending token acquiring request";
|
||||
log.error(msg, e);
|
||||
throw new APIManagerException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ApiApplicationKey handleNewAPIApplication(String applicationName, List<APIInfo> uniqueApiList,
|
||||
ApiApplicationInfo apiApplicationInfo, String keyType, String validityTime,
|
||||
ArrayList<String> supportedGrantTypes, String callbackUrl,
|
||||
boolean isMappingRequired) throws 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);
|
||||
}
|
||||
|
||||
ApplicationKey applicationKey;
|
||||
|
||||
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();
|
||||
|
||||
APIApplicationKey apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials(
|
||||
"ClientForMapping",
|
||||
"client_credentials password refresh_token urn:ietf:params:oauth:grant-type:jwt-bearer");
|
||||
|
||||
apiApplicationInfo.setClientId(apiApplicationKey.getClientId());
|
||||
apiApplicationInfo.setClientSecret(apiApplicationKey.getClientSecret());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ApiApplicationKey apiApplicationKey = new ApiApplicationKey();
|
||||
apiApplicationKey.setConsumerKey(applicationKey.getConsumerKey());
|
||||
apiApplicationKey.setConsumerSecret(applicationKey.getConsumerSecret());
|
||||
|
||||
Metadata metaData = new Metadata();
|
||||
metaData.setMetaKey(applicationName);
|
||||
String metaValue = application.getApplicationId() + ":" + applicationKey.getKeyMappingId();
|
||||
metaData.setMetaValue(metaValue);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<APIInfo>}
|
||||
* @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<APIInfo> apiInfos, ApiApplicationInfo apiApplicationInfo)
|
||||
throws BadRequestException, UnexpectedResponseException, APIServicesException {
|
||||
|
||||
ConsumerRESTAPIServices consumerRESTAPIServices =
|
||||
APIApplicationManagerExtensionDataHolder.getInstance().getConsumerRESTAPIServices();
|
||||
|
||||
List<Subscription> subscriptionList = new ArrayList<>();
|
||||
apiInfos.forEach(apiInfo -> {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setApiId(apiInfo.getId());
|
||||
subscription.setApplicationId(application.getApplicationId());
|
||||
subscription.setThrottlingPolicy(UNLIMITED_TIER);
|
||||
subscription.setRequestedThrottlingPolicy(UNLIMITED_TIER);
|
||||
subscriptionList.add(subscription);
|
||||
});
|
||||
|
||||
consumerRESTAPIServices.createSubscriptions(apiApplicationInfo, subscriptionList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessTokenInfo getAccessToken(String scopes, String[] tags, String applicationName, String tokenType,
|
||||
String validityPeriod, String username) throws APIManagerException {
|
||||
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 {
|
||||
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true);
|
||||
ApiApplicationKey clientCredentials = getClientCredentials(tenantDomain, tags, applicationName, tokenType,
|
||||
validityPeriod);
|
||||
Metadata metaData =
|
||||
metadataManagementService.retrieveMetadata(Constants.API_PUBLISHING_ENABLED_TENANT_LIST_KEY);
|
||||
if (metaData != null) {
|
||||
JsonArray tenants = gson.fromJson(metaData.getMetaValue(), JsonArray.class);
|
||||
|
||||
if (clientCredentials == null) {
|
||||
String msg = "Oauth Application creation is failed.";
|
||||
log.error(msg);
|
||||
throw new APIManagerException(msg);
|
||||
}
|
||||
|
||||
if (username == null || username.isEmpty()) {
|
||||
username =
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername() + "@" + PrivilegedCarbonContext
|
||||
.getThreadLocalCarbonContext().getTenantDomain(true);
|
||||
} else {
|
||||
if (!username.contains("@")) {
|
||||
username += "@" + PrivilegedCarbonContext
|
||||
.getThreadLocalCarbonContext().getTenantDomain(true);
|
||||
for (JsonElement tenant : tenants) {
|
||||
if (Objects.equals(tenant.getAsString(), idnAuthenticationProfile.getTenantDomain())) {
|
||||
flowStartingDomain = idnAuthenticationProfile.getTenantDomain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JWTClientManagerService jwtClientManagerService = APIApplicationManagerExtensionDataHolder.getInstance()
|
||||
.getJwtClientManagerService();
|
||||
JWTClient jwtClient = jwtClientManagerService.getJWTClient();
|
||||
|
||||
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.";
|
||||
log.error(msg, e);
|
||||
throw new APIManagerException(msg, e);
|
||||
} catch (MetadataManagementException metadataManagementException) {
|
||||
log.warn("Failed to load API publishing enabled tenant domains from meta data registry.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
if (log.isDebugEnabled()) {
|
||||
log.info("Start API application registration sequences though " + flowStartingDomain + " domain.");
|
||||
}
|
||||
|
||||
try {
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration()
|
||||
.getAdminUserName());
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(flowStartingDomain, true);
|
||||
if (APIApplicationManagerExtensionDataHolder.getInstance().getIoAuthClientService().
|
||||
doAuthenticate(idnAuthenticationProfile.getUsername(), idnAuthenticationProfile.getPassword())) {
|
||||
apiApplicationProfile.setOwner(idnAuthenticationProfile.getUsername());
|
||||
return registerApiApplication(apiApplicationProfile);
|
||||
}
|
||||
|
||||
return generateAndRetrieveApplicationKeys(registrationProfile.getApplicationName(),
|
||||
registrationProfile.getTags(), tokenType, PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
|
||||
.getRealmConfiguration().getAdminUserName(),
|
||||
registrationProfile.isAllowedToAllDomains(), validityPeriod, PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
|
||||
.getRealmConfiguration().getAdminPassword(), null, null, null, false);
|
||||
throw new IdnAuthenticationException(
|
||||
"Failed to authenticate the user : [ " + idnAuthenticationProfile.getUsername() + " ]");
|
||||
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
|
||||
private ApiApplicationInfo getApplicationInfo(String username, String password)
|
||||
throws APIManagerException {
|
||||
|
||||
APIApplicationServices apiApplicationServices = APIApplicationManagerExtensionDataHolder.getInstance()
|
||||
.getApiApplicationServices();
|
||||
|
||||
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");
|
||||
}
|
||||
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());
|
||||
|
||||
return applicationInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<String, String> queryParams, Map<String, String> headerParams)
|
||||
APIInfo[] getAllApis(Map<String, String> queryParams, Map<String, String> headerParams)
|
||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||
|
||||
Subscription createSubscription(ApiApplicationInfo apiApplicationInfo, Subscription subscriptions)
|
||||
Subscription createSubscription(Subscription subscriptions)
|
||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||
|
||||
Subscription[] createSubscriptions(ApiApplicationInfo apiApplicationInfo, List<Subscription> 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<Subscription> 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<String> supportedGrantTypes, String callbackUrl)
|
||||
ApplicationKey getKeyDetails(String applicationId, String keyMapId)
|
||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||
|
||||
KeyManager[] getAllKeyManagers(ApiApplicationInfo apiApplicationInfo)
|
||||
ApplicationKey updateGrantType(String applicationId, String keyMapId, List<String> supportedGrantTypes, String callbackUrl)
|
||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||
|
||||
KeyManager[] getAllKeyManagers()
|
||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||
}
|
||||
|
||||
@ -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<String, String> queryParams, Map<String, String> headerParams)
|
||||
public APIInfo[] getAllApis(Map<String, String> queryParams, Map<String, String> headerParams)
|
||||
throws APIServicesException, BadRequestException, UnexpectedResponseException {
|
||||
|
||||
StringBuilder getAPIsURL = new StringBuilder(endPointPrefix + Constants.DEV_PORTAL_API);
|
||||
|
||||
for (Map.Entry<String, String> 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<String, String> 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<Subscription> subscriptions)
|
||||
public Subscription[] createSubscriptions(List<Subscription> 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<String> 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<String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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<String, CacheWrapper> 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<String> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<APIRevisionDeployment> 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;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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";
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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<APIRevisionDeployment> 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<APIRevisionDeployment> 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<ApiScope> apiScopes, PublisherRESTAPIServices publisherRESTAPIServices,
|
||||
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo) throws BadRequestException, UnexpectedResponseException, APIServicesException {
|
||||
private void addNewSharedScope(Set<ApiScope> 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<String> 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<String> 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<String, String> 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<String, String> 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");
|
||||
|
||||
@ -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<String> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,8 +37,8 @@
|
||||
<module>io.entgra.device.mgt.core.apimgt.application.extension</module>
|
||||
<module>io.entgra.device.mgt.core.apimgt.application.extension.api</module>
|
||||
<module>io.entgra.device.mgt.core.apimgt.annotations</module>
|
||||
<module>io.entgra.device.mgt.core.apimgt.keymgt.extension</module>
|
||||
<module>io.entgra.device.mgt.core.apimgt.keymgt.extension.api</module>
|
||||
<!-- <module>io.entgra.device.mgt.core.apimgt.keymgt.extension</module>-->
|
||||
<!-- <module>io.entgra.device.mgt.core.apimgt.keymgt.extension.api</module>-->
|
||||
<module>io.entgra.device.mgt.core.apimgt.analytics.extension</module>
|
||||
<module>io.entgra.device.mgt.core.apimgt.extension.rest.api</module>
|
||||
</modules>
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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"
|
||||
);
|
||||
String adminUserName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
|
||||
.getRealmConfiguration().getAdminUserName();
|
||||
String adminPassword = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
|
||||
.getRealmConfiguration().getAdminPassword();
|
||||
|
||||
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");
|
||||
IdnAuthenticationProfile idnAuthenticationProfile = new IdnAuthenticationProfile();
|
||||
idnAuthenticationProfile.setUsername(adminUserName);
|
||||
idnAuthenticationProfile.setPassword(adminPassword);
|
||||
|
||||
APIManagementProviderService apiManagementProviderService = DeviceMgtAPIUtils.getAPIManagementService();
|
||||
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(applicationName,
|
||||
new String[] {"device_management"}, "PRODUCTION", null, false, String.valueOf(validityTime),
|
||||
null, accessTokenInfo.getAccessToken(), null, null,true);
|
||||
ApiApplicationProfile apiApplicationProfile = new ApiApplicationProfile();
|
||||
apiApplicationProfile.setApplicationName(applicationName);
|
||||
apiApplicationProfile.setTags(new String[] {"device_management"});
|
||||
apiApplicationProfile.setGrantTypes("client_credentials password refresh_token");
|
||||
|
||||
} catch (JWTClientException e) {
|
||||
String msg = "Error while generating an application tokens for Tenant Admin.";
|
||||
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);
|
||||
|
||||
@ -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<Scope> scopeList, PublisherRESTAPIServices publisherRESTAPIServices,
|
||||
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo)
|
||||
private void publishSharedScopes (List<Scope> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,25 +55,6 @@
|
||||
<send/>
|
||||
</outSequence>
|
||||
</resource>
|
||||
<resource methods="DELETE" url-mapping="/unregister" faultSequence="_api_registration_fault_">
|
||||
<inSequence>
|
||||
<property name="uri.var.portnum" expression="get-property('system','iot.core.https.port')"/>
|
||||
<property name="uri.var.hostname" expression="get-property('system','iot.core.host')"/>
|
||||
<send>
|
||||
<endpoint>
|
||||
<http uri-template="https://{uri.var.hostname}:{uri.var.portnum}/api-application-registration">
|
||||
<timeout>
|
||||
<duration>60000</duration>
|
||||
<responseAction>fault</responseAction>
|
||||
</timeout>
|
||||
</http>
|
||||
</endpoint>
|
||||
</send>
|
||||
</inSequence>
|
||||
<outSequence>
|
||||
<send/>
|
||||
</outSequence>
|
||||
</resource>
|
||||
<handlers>
|
||||
<handler class="org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerCacheExtensionHandler"/>
|
||||
<handler class="org.wso2.carbon.apimgt.gateway.handlers.common.SynapsePropertiesHandler"/>
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
<modules>
|
||||
<module>io.entgra.device.mgt.core.apimgt.webapp.publisher.feature</module>
|
||||
<module>io.entgra.device.mgt.core.apimgt.application.extension.feature</module>
|
||||
<module>io.entgra.device.mgt.core.apimgt.keymgt.extension.feature</module>
|
||||
<!-- <module>io.entgra.device.mgt.core.apimgt.keymgt.extension.feature</module>-->
|
||||
<module>io.entgra.device.mgt.core.apimgt.analytics.extension.feature</module>
|
||||
<module>io.entgra.device.mgt.core.apimgt.extension.rest.api.feature</module>
|
||||
</modules>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user