mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Add eidp login support for multi tenant level
This commit is contained in:
parent
5f94113adf
commit
0f1781beb5
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 - 2023, 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.dto.APIApplicationKey;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException;
|
|
||||||
|
|
||||||
public interface APIApplicationServices {
|
|
||||||
|
|
||||||
APIApplicationKey createAndRetrieveApplicationCredentials() throws APIServicesException;
|
|
||||||
|
|
||||||
AccessTokenInfo generateAccessTokenFromRegisteredApplication(String clientId, String clientSecret) throws APIServicesException;
|
|
||||||
|
|
||||||
AccessTokenInfo generateAccessTokenFromRefreshToken(String refreshToken, String clientId, String clientSecret) throws APIServicesException;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 - 2023, 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 org.json.JSONObject;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.util.HttpsTrustManagerUtils;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey;
|
|
||||||
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.exceptions.APIServicesException;
|
|
||||||
import okhttp3.MediaType;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.Response;
|
|
||||||
import okhttp3.RequestBody;
|
|
||||||
import okhttp3.Credentials;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.wso2.carbon.apimgt.impl.APIConstants;
|
|
||||||
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
|
|
||||||
import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder;
|
|
||||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class APIApplicationServicesImpl implements APIApplicationServices {
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(APIApplicationServicesImpl.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");
|
|
||||||
String msg = null;
|
|
||||||
APIManagerConfiguration config = ServiceReferenceHolder.getInstance().
|
|
||||||
getAPIManagerConfigurationService().getAPIManagerConfiguration();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public APIApplicationKey createAndRetrieveApplicationCredentials() throws APIServicesException {
|
|
||||||
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
|
||||||
String serverUser = getScopePublishUserName(tenantDomain);
|
|
||||||
String serverPassword = getScopePublishUserPassword(tenantDomain);
|
|
||||||
|
|
||||||
String applicationEndpoint = config.getFirstProperty(Constants.DCR_END_POINT);
|
|
||||||
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
jsonObject.put("callbackUrl", Constants.EMPTY_STRING);
|
|
||||||
jsonObject.put("clientName", Constants.CLIENT_NAME);
|
|
||||||
jsonObject.put("grantType", Constants.GRANT_TYPE);
|
|
||||||
jsonObject.put("owner", serverUser);
|
|
||||||
jsonObject.put("saasApp", true);
|
|
||||||
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(jsonObject.toString(), JSON);
|
|
||||||
Request request = new Request.Builder()
|
|
||||||
.url(applicationEndpoint)
|
|
||||||
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Credentials.basic(serverUser, serverPassword))
|
|
||||||
.post(requestBody)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
try {
|
|
||||||
try (Response response = client.newCall(request).execute()) {
|
|
||||||
return gson.fromJson(response.body().string(), APIApplicationKey.class);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
msg = "Error occurred while processing the response";
|
|
||||||
log.error(msg, e);
|
|
||||||
throw new APIServicesException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessTokenInfo generateAccessTokenFromRegisteredApplication(String consumerKey, String consumerSecret)
|
|
||||||
throws APIServicesException {
|
|
||||||
|
|
||||||
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
|
||||||
String userName = getScopePublishUserName(tenantDomain);
|
|
||||||
String userPassword = getScopePublishUserPassword(tenantDomain);
|
|
||||||
|
|
||||||
JSONObject params = new JSONObject();
|
|
||||||
params.put(Constants.GRANT_TYPE_PARAM_NAME, Constants.PASSWORD_GRANT_TYPE);
|
|
||||||
params.put(Constants.PASSWORD_GRANT_TYPE_USERNAME, userName);
|
|
||||||
params.put(Constants.PASSWORD_GRANT_TYPE_PASSWORD, userPassword);
|
|
||||||
params.put(Constants.SCOPE_PARAM_NAME, Constants.SCOPES);
|
|
||||||
return getToken(params, consumerKey, consumerSecret);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessTokenInfo generateAccessTokenFromRefreshToken(String refreshToken, String consumerKey,
|
|
||||||
String consumerSecret) throws APIServicesException {
|
|
||||||
JSONObject params = new JSONObject();
|
|
||||||
params.put(Constants.GRANT_TYPE_PARAM_NAME, Constants.REFRESH_TOKEN_GRANT_TYPE);
|
|
||||||
params.put(Constants.REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME, refreshToken);
|
|
||||||
params.put(Constants.SCOPE_PARAM_NAME, Constants.SCOPES);
|
|
||||||
return getToken(params, consumerKey, consumerSecret);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccessTokenInfo getToken(JSONObject nameValuePairs, String clientId, String clientSecret)
|
|
||||||
throws APIServicesException {
|
|
||||||
|
|
||||||
String tokenEndPoint = config.getFirstProperty(Constants.TOKE_END_POINT);
|
|
||||||
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(nameValuePairs.toString(), JSON);
|
|
||||||
Request request = new Request.Builder()
|
|
||||||
.url(tokenEndPoint)
|
|
||||||
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Credentials.basic(clientId, clientSecret))
|
|
||||||
.post(requestBody)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
try {
|
|
||||||
Response response = client.newCall(request).execute();
|
|
||||||
return gson.fromJson(response.body().string(), AccessTokenInfo.class);
|
|
||||||
} catch (IOException e) {
|
|
||||||
msg = "Error occurred while processing the response";
|
|
||||||
log.error(msg, e);
|
|
||||||
throw new APIServicesException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getScopePublishUserName(String tenantDomain) {
|
|
||||||
if(APIConstants.SUPER_TENANT_DOMAIN.equals(tenantDomain)) {
|
|
||||||
return config.getFirstProperty(Constants.SERVER_USER);
|
|
||||||
} else {
|
|
||||||
return Constants.SCOPE_PUBLISH_RESERVED_USER_NAME + "@" + tenantDomain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getScopePublishUserPassword(String tenantDomain) {
|
|
||||||
if(APIConstants.SUPER_TENANT_DOMAIN.equals(tenantDomain)) {
|
|
||||||
return config.getFirstProperty(Constants.SERVER_PASSWORD);
|
|
||||||
} else {
|
|
||||||
return Constants.SCOPE_PUBLISH_RESERVED_USER_PASSWORD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -18,98 +18,77 @@
|
|||||||
|
|
||||||
package io.entgra.device.mgt.core.apimgt.extension.rest.api;
|
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.APIInfo.*;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException;
|
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.BadRequestException;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface PublisherRESTAPIServices {
|
public interface PublisherRESTAPIServices {
|
||||||
|
|
||||||
Scope[] getScopes(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo)
|
Scope[] getScopes() throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean isSharedScopeNameExists(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String key)
|
boolean isSharedScopeNameExists(String key) throws APIServicesException, BadRequestException,
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
UnexpectedResponseException;
|
||||||
|
|
||||||
boolean addNewSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope)
|
boolean addNewSharedScope(Scope scope) throws APIServicesException, BadRequestException,
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
UnexpectedResponseException;
|
||||||
|
|
||||||
boolean updateSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope)
|
boolean updateSharedScope(Scope scope) throws APIServicesException, BadRequestException,
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
UnexpectedResponseException;
|
||||||
|
|
||||||
boolean deleteSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope)
|
boolean deleteSharedScope(Scope scope) throws APIServicesException, BadRequestException,
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
UnexpectedResponseException;
|
||||||
|
|
||||||
APIInfo getApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String apiUuid)
|
APIInfo getApi(String apiUuid) throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
APIInfo[] getApis(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo)
|
APIInfo[] getApis() throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
APIInfo addAPI(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIInfo api)
|
APIInfo addAPI(APIInfo api) throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean updateApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIInfo api)
|
boolean updateApi(APIInfo api) throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean saveAsyncApiDefinition(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid,
|
boolean saveAsyncApiDefinition(String uuid, String asyncApiDefinition) throws APIServicesException,
|
||||||
String asyncApiDefinition)
|
BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
MediationPolicy[] getAllApiSpecificMediationPolicies(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
MediationPolicy[] getAllApiSpecificMediationPolicies(String apiUuid) throws APIServicesException,
|
||||||
String apiUuid)
|
BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean addApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
boolean addApiSpecificMediationPolicy(String uuid, Mediation mediation) throws APIServicesException,
|
||||||
String uuid, Mediation mediation)
|
BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean deleteApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
boolean deleteApiSpecificMediationPolicy(String uuid, Mediation mediation) throws APIServicesException,
|
||||||
String uuid, Mediation mediation)
|
BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean changeLifeCycleStatus(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
boolean changeLifeCycleStatus(String uuid, String action) throws APIServicesException, BadRequestException,
|
||||||
String uuid, String action)
|
UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
APIRevision[] getAPIRevisions(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid,
|
APIRevision[] getAPIRevisions(String uuid, Boolean deploymentStatus) throws APIServicesException,
|
||||||
Boolean deploymentStatus)
|
BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
APIRevision addAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
APIRevision addAPIRevision(APIRevision apiRevision) throws APIServicesException, BadRequestException,
|
||||||
APIRevision apiRevision)
|
UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean deployAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String uuid,
|
boolean deployAPIRevision(String uuid, String apiRevisionId,
|
||||||
String apiRevisionId, List<APIRevisionDeployment> apiRevisionDeploymentList)
|
List<APIRevisionDeployment> apiRevisionDeploymentList) throws APIServicesException,
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
BadRequestException, UnexpectedResponseException;
|
||||||
|
|
||||||
boolean undeployAPIRevisionDeployment(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
boolean undeployAPIRevisionDeployment(APIRevision apiRevisionDeployment, String uuid) throws APIServicesException
|
||||||
APIRevision apiRevisionDeployment, String uuid)
|
, BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean deleteAPIRevision(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
boolean deleteAPIRevision(APIRevision apiRevision, String uuid) throws APIServicesException, BadRequestException,
|
||||||
APIRevision apiRevision, String uuid)
|
UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
Documentation[] getDocumentations(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
Documentation[] getDocumentations(String uuid) throws APIServicesException, BadRequestException,
|
||||||
String uuid)
|
UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean deleteDocumentations(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
boolean deleteDocumentations(String uuid, String documentID) throws APIServicesException, BadRequestException,
|
||||||
String uuid, String documentID)
|
UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
Documentation addDocumentation(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
Documentation addDocumentation(String uuid, Documentation documentation) throws APIServicesException,
|
||||||
String uuid, Documentation documentation)
|
BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
|
|
||||||
boolean addDocumentationContent(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
boolean addDocumentationContent(String apiUuid, String docId, String docContent) throws APIServicesException,
|
||||||
String apiUuid, String docId, String docContent)
|
BadRequestException, UnexpectedResponseException;
|
||||||
throws APIServicesException, BadRequestException, UnexpectedResponseException;
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey;
|
||||||
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo;
|
||||||
|
|
||||||
|
public class PublisherOauthApp {
|
||||||
|
private final APIApplicationKey apiApplicationKey;
|
||||||
|
private final AccessTokenInfo accessTokenInfo;
|
||||||
|
|
||||||
|
public PublisherOauthApp(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo) {
|
||||||
|
this.apiApplicationKey = apiApplicationKey;
|
||||||
|
this.accessTokenInfo = accessTokenInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccessTokenInfo getAccessTokenInfo() {
|
||||||
|
return accessTokenInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public APIApplicationKey getApiApplicationKey() {
|
||||||
|
return apiApplicationKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 PublisherRESTAPIClientResponse {
|
||||||
|
private final int code;
|
||||||
|
private final String body;
|
||||||
|
private final boolean isSuccessful;
|
||||||
|
|
||||||
|
public PublisherRESTAPIClientResponse(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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 PublisherRESTAPIOauthClientException extends Exception {
|
||||||
|
private static final long serialVersionUID = -896103750774855894L;
|
||||||
|
|
||||||
|
public PublisherRESTAPIOauthClientException(String errorMessage) {
|
||||||
|
super(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublisherRESTAPIOauthClientException(String errorMessage, Throwable t) {
|
||||||
|
super(errorMessage, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
package io.entgra.device.mgt.core.apimgt.extension.rest.api.internal;
|
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.APIApplicationServicesImpl;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServicesImpl;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServicesImpl;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@ -48,11 +46,6 @@ public class APIManagerServiceComponent {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
BundleContext bundleContext = componentContext.getBundleContext();
|
BundleContext bundleContext = componentContext.getBundleContext();
|
||||||
|
|
||||||
APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl();
|
|
||||||
bundleContext.registerService(APIApplicationServices.class.getName(), apiApplicationServices, null);
|
|
||||||
APIManagerServiceDataHolder.getInstance().setApiApplicationServices(apiApplicationServices);
|
|
||||||
|
|
||||||
PublisherRESTAPIServices publisherRESTAPIServices = new PublisherRESTAPIServicesImpl();
|
PublisherRESTAPIServices publisherRESTAPIServices = new PublisherRESTAPIServicesImpl();
|
||||||
bundleContext.registerService(PublisherRESTAPIServices.class.getName(), publisherRESTAPIServices, null);
|
bundleContext.registerService(PublisherRESTAPIServices.class.getName(), publisherRESTAPIServices, null);
|
||||||
APIManagerServiceDataHolder.getInstance().setPublisherRESTAPIServices(publisherRESTAPIServices);
|
APIManagerServiceDataHolder.getInstance().setPublisherRESTAPIServices(publisherRESTAPIServices);
|
||||||
|
|||||||
@ -18,15 +18,12 @@
|
|||||||
|
|
||||||
package io.entgra.device.mgt.core.apimgt.extension.rest.api.internal;
|
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.PublisherRESTAPIServices;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
||||||
import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService;
|
import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService;
|
||||||
import org.wso2.carbon.user.core.service.RealmService;
|
import org.wso2.carbon.user.core.service.RealmService;
|
||||||
import org.wso2.carbon.user.core.tenant.TenantManager;
|
import org.wso2.carbon.user.core.tenant.TenantManager;
|
||||||
|
|
||||||
public class APIManagerServiceDataHolder {
|
public class APIManagerServiceDataHolder {
|
||||||
|
|
||||||
private APIApplicationServices apiApplicationServices;
|
|
||||||
private APIManagerConfigurationService apiManagerConfigurationService;
|
private APIManagerConfigurationService apiManagerConfigurationService;
|
||||||
private PublisherRESTAPIServices publisherRESTAPIServices;
|
private PublisherRESTAPIServices publisherRESTAPIServices;
|
||||||
private RealmService realmService;
|
private RealmService realmService;
|
||||||
@ -37,18 +34,10 @@ public class APIManagerServiceDataHolder {
|
|||||||
private APIManagerServiceDataHolder() {
|
private APIManagerServiceDataHolder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static APIManagerServiceDataHolder getInstance() {
|
public static APIManagerServiceDataHolder getInstance() {
|
||||||
return thisInstance;
|
return thisInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public APIApplicationServices getApiApplicationServices() {
|
|
||||||
return apiApplicationServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApiApplicationServices(APIApplicationServices apiApplicationServices) {
|
|
||||||
this.apiApplicationServices = apiApplicationServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAPIManagerConfiguration(APIManagerConfigurationService apiManagerConfigurationService) {
|
public void setAPIManagerConfiguration(APIManagerConfigurationService apiManagerConfigurationService) {
|
||||||
this.apiManagerConfigurationService = apiManagerConfigurationService;
|
this.apiManagerConfigurationService = apiManagerConfigurationService;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.PublisherOauthApp;
|
||||||
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.bean.PublisherRESTAPIClientResponse;
|
||||||
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
|
||||||
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey;
|
||||||
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo;
|
||||||
|
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.PublisherRESTAPIOauthClientException;
|
||||||
|
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.httpclient.HttpStatus;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.wso2.carbon.apimgt.impl.APIConstants;
|
||||||
|
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
|
||||||
|
import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder;
|
||||||
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class PublisherRESTAPIOauthClient {
|
||||||
|
private static final Log log = LogFactory.getLog(PublisherRESTAPIOauthClient.class);
|
||||||
|
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||||
|
private static final Gson gson = new Gson();
|
||||||
|
private static final OkHttpClient client = new OkHttpClient(HttpsTrustManagerUtils.getSSLClient().newBuilder());
|
||||||
|
private static final Map<String, PublisherOauthApp> publisherOauthAppCache = new ConcurrentHashMap<>();
|
||||||
|
private static final APIManagerConfiguration config = ServiceReferenceHolder.getInstance().
|
||||||
|
getAPIManagerConfigurationService().getAPIManagerConfiguration();
|
||||||
|
private static final int MAX_RETRY_ATTEMPT = 2;
|
||||||
|
|
||||||
|
public static PublisherRESTAPIClientResponse execute(Request request) throws PublisherRESTAPIOauthClientException
|
||||||
|
, BadRequestException,
|
||||||
|
UnexpectedResponseException {
|
||||||
|
int currentRetryAttempt = 0;
|
||||||
|
PublisherRESTAPIClientResponse publisherRESTAPIClientResponse;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
request = addAuthorizationHeader(request);
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
publisherRESTAPIClientResponse = map(response);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.code() == HttpStatus.SC_NOT_FOUND) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.info("Resource not found for the request [ " + request.url() + " ]");
|
||||||
|
}
|
||||||
|
publisherRESTAPIClientResponse = map(response);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// entering to the retrying phase, so increment the counter
|
||||||
|
currentRetryAttempt++;
|
||||||
|
if (response.code() == HttpStatus.SC_UNAUTHORIZED) {
|
||||||
|
if (currentRetryAttempt <= MAX_RETRY_ATTEMPT) {
|
||||||
|
updateCacheWithNewToken();
|
||||||
|
} 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 PublisherRESTAPIOauthClientException(msg, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return publisherRESTAPIClientResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static APIApplicationKey createOauthApplication() throws IOException {
|
||||||
|
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
||||||
|
String serverUser = getScopePublishUserName(tenantDomain);
|
||||||
|
String serverPassword = getScopePublishUserPassword(tenantDomain);
|
||||||
|
String applicationEndpoint = config.getFirstProperty(Constants.DCR_END_POINT);
|
||||||
|
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("callbackUrl", Constants.EMPTY_STRING);
|
||||||
|
jsonObject.put("clientName", Constants.CLIENT_NAME + "_for_" + tenantDomain);
|
||||||
|
jsonObject.put("grantType", Constants.GRANT_TYPE);
|
||||||
|
jsonObject.put("owner", serverUser);
|
||||||
|
jsonObject.put("saasApp", true);
|
||||||
|
|
||||||
|
RequestBody requestBody = RequestBody.Companion.create(jsonObject.toString(), JSON);
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(applicationEndpoint)
|
||||||
|
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Credentials.basic(serverUser, serverPassword))
|
||||||
|
.post(requestBody)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
return gson.fromJson(response.body() != null ? response.body().string() : null, APIApplicationKey.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AccessTokenInfo getAccessToken() throws IOException {
|
||||||
|
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
||||||
|
APIApplicationKey apiApplicationKey = createOauthApplication();
|
||||||
|
String userName = getScopePublishUserName(tenantDomain);
|
||||||
|
String userPassword = getScopePublishUserPassword(tenantDomain);
|
||||||
|
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put(Constants.GRANT_TYPE_PARAM_NAME, Constants.PASSWORD_GRANT_TYPE);
|
||||||
|
params.put(Constants.PASSWORD_GRANT_TYPE_USERNAME, userName);
|
||||||
|
params.put(Constants.PASSWORD_GRANT_TYPE_PASSWORD, userPassword);
|
||||||
|
params.put(Constants.SCOPE_PARAM_NAME, Constants.SCOPES);
|
||||||
|
return getToken(params, apiApplicationKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateCacheWithNewToken() throws IOException {
|
||||||
|
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
||||||
|
publisherOauthAppCache.computeIfPresent(tenantDomain, (key, value) -> {
|
||||||
|
PublisherOauthApp publisherOauthApp = value;
|
||||||
|
try {
|
||||||
|
APIApplicationKey apiApplicationKey = value.getApiApplicationKey();
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put(Constants.GRANT_TYPE_PARAM_NAME, Constants.REFRESH_TOKEN_GRANT_TYPE);
|
||||||
|
params.put(Constants.REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME,
|
||||||
|
value.getAccessTokenInfo().getRefresh_token());
|
||||||
|
params.put(Constants.SCOPE_PARAM_NAME, Constants.SCOPES);
|
||||||
|
AccessTokenInfo accessTokenInfo = getToken(params, apiApplicationKey);
|
||||||
|
publisherOauthApp = new PublisherOauthApp(apiApplicationKey, accessTokenInfo);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error encountered while creating publisher OAuth application", e);
|
||||||
|
}
|
||||||
|
return publisherOauthApp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AccessTokenInfo getToken(JSONObject params, APIApplicationKey apiApplicationKey) throws IOException {
|
||||||
|
String tokenEndPoint = config.getFirstProperty(Constants.TOKE_END_POINT);
|
||||||
|
RequestBody requestBody = RequestBody.Companion.create(params.toString(), JSON);
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(tokenEndPoint)
|
||||||
|
.addHeader(Constants.AUTHORIZATION_HEADER_NAME,
|
||||||
|
Credentials.basic(apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret()))
|
||||||
|
.post(requestBody)
|
||||||
|
.build();
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
return gson.fromJson(response.body() != null ? response.body().string() : null, AccessTokenInfo.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PublisherOauthApp getOauthApp() {
|
||||||
|
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
||||||
|
return publisherOauthAppCache.computeIfAbsent(tenantDomain, key -> {
|
||||||
|
PublisherOauthApp publisherOauthApp = null;
|
||||||
|
try {
|
||||||
|
APIApplicationKey apiApplicationKey = createOauthApplication();
|
||||||
|
AccessTokenInfo accessTokenInfo = getAccessToken();
|
||||||
|
publisherOauthApp = new PublisherOauthApp(apiApplicationKey, accessTokenInfo);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error encountered while creating publisher OAuth application", e);
|
||||||
|
}
|
||||||
|
return publisherOauthApp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Request addAuthorizationHeader(Request request) throws IOException {
|
||||||
|
return request.newBuilder().addHeader(Constants.AUTHORIZATION_HEADER_NAME,
|
||||||
|
Constants.AUTHORIZATION_HEADER_PREFIX_BEARER + getOauthApp().getAccessTokenInfo().
|
||||||
|
getAccess_token()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getScopePublishUserName(String tenantDomain) throws IOException {
|
||||||
|
if (APIConstants.SUPER_TENANT_DOMAIN.equals(tenantDomain)) {
|
||||||
|
return config.getFirstProperty(Constants.SERVER_USER);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain);
|
||||||
|
} catch (APIServicesException e) {
|
||||||
|
throw new IOException("Failed to create user for api publishing in sub tenant : " + tenantDomain);
|
||||||
|
}
|
||||||
|
return Constants.SCOPE_PUBLISH_RESERVED_USER_NAME + "@" + tenantDomain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getScopePublishUserPassword(String tenantDomain) {
|
||||||
|
if (APIConstants.SUPER_TENANT_DOMAIN.equals(tenantDomain)) {
|
||||||
|
return config.getFirstProperty(Constants.SERVER_PASSWORD);
|
||||||
|
} else {
|
||||||
|
return Constants.SCOPE_PUBLISH_RESERVED_USER_PASSWORD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PublisherRESTAPIClientResponse map(Response response) throws IOException {
|
||||||
|
return new PublisherRESTAPIClientResponse(response.code(),
|
||||||
|
response.body() != null ? response.body().string() : null, response.isSuccessful());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,10 +18,8 @@
|
|||||||
package io.entgra.device.mgt.core.apimgt.webapp.publisher;
|
package io.entgra.device.mgt.core.apimgt.webapp.publisher;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIInfo;
|
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.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.APIRevisionDeployment;
|
||||||
@ -31,7 +29,6 @@ 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.MediationPolicy;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Operations;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Operations;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException;
|
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.BadRequestException;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
|
||||||
@ -68,8 +65,6 @@ import org.wso2.carbon.user.core.tenant.Tenant;
|
|||||||
import org.wso2.carbon.user.core.tenant.TenantSearchResult;
|
import org.wso2.carbon.user.core.tenant.TenantSearchResult;
|
||||||
import org.wso2.carbon.utils.CarbonUtils;
|
import org.wso2.carbon.utils.CarbonUtils;
|
||||||
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
|
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
|
||||||
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
|
|
||||||
import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionUtils;
|
|
||||||
import io.entgra.device.mgt.core.device.mgt.common.permission.mgt.PermissionManagementException;
|
import io.entgra.device.mgt.core.device.mgt.common.permission.mgt.PermissionManagementException;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@ -117,11 +112,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
tenants.addAll(config.getTenants().getTenant());
|
tenants.addAll(config.getTenants().getTenant());
|
||||||
RealmService realmService = (RealmService) PrivilegedCarbonContext.getThreadLocalCarbonContext()
|
RealmService realmService = (RealmService) PrivilegedCarbonContext.getThreadLocalCarbonContext()
|
||||||
.getOSGiService(RealmService.class, null);
|
.getOSGiService(RealmService.class, null);
|
||||||
|
|
||||||
APIApplicationServices apiApplicationServices = APIPublisherDataHolder.getInstance().getApiApplicationServices();
|
|
||||||
PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices();
|
PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices();
|
||||||
APIApplicationKey apiApplicationKey;
|
|
||||||
AccessTokenInfo accessTokenInfo;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean tenantFound = false;
|
boolean tenantFound = false;
|
||||||
@ -156,17 +147,6 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(apiConfig.getOwner());
|
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(apiConfig.getOwner());
|
||||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||||
|
|
||||||
try {
|
|
||||||
APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain);
|
|
||||||
apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials();
|
|
||||||
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 {
|
try {
|
||||||
apiConfig.setOwner(APIUtil.getTenantAdminUserName(tenantDomain));
|
apiConfig.setOwner(APIUtil.getTenantAdminUserName(tenantDomain));
|
||||||
apiConfig.setTenantDomain(tenantDomain);
|
apiConfig.setTenantDomain(tenantDomain);
|
||||||
@ -174,7 +154,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
APIIdentifier apiIdentifier = new APIIdentifier(APIUtil.replaceEmailDomain(apiConfig.getOwner()),
|
APIIdentifier apiIdentifier = new APIIdentifier(APIUtil.replaceEmailDomain(apiConfig.getOwner()),
|
||||||
apiConfig.getName(), apiConfig.getVersion());
|
apiConfig.getName(), apiConfig.getVersion());
|
||||||
|
|
||||||
APIInfo[] apiList = publisherRESTAPIServices.getApis(apiApplicationKey, accessTokenInfo);
|
APIInfo[] apiList = publisherRESTAPIServices.getApis();
|
||||||
boolean apiFound = false;
|
boolean apiFound = false;
|
||||||
for (int i = 0; i < apiList.length; i++) {
|
for (int i = 0; i < apiList.length; i++) {
|
||||||
APIInfo apiObj = apiList[i];
|
APIInfo apiObj = apiList[i];
|
||||||
@ -189,8 +169,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
if (!apiFound) {
|
if (!apiFound) {
|
||||||
// add new scopes as shared scopes
|
// add new scopes as shared scopes
|
||||||
for (ApiScope apiScope : apiConfig.getScopes()) {
|
for (ApiScope apiScope : apiConfig.getScopes()) {
|
||||||
if (!publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo,
|
if (!publisherRESTAPIServices.isSharedScopeNameExists(apiScope.getKey())) {
|
||||||
apiScope.getKey())) {
|
|
||||||
Scope scope = new Scope();
|
Scope scope = new Scope();
|
||||||
scope.setDisplayName(apiScope.getName());
|
scope.setDisplayName(apiScope.getName());
|
||||||
scope.setDescription(apiScope.getDescription());
|
scope.setDescription(apiScope.getDescription());
|
||||||
@ -198,15 +177,14 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
List<String> bindings = new ArrayList<>(apiScope.getRoles());
|
List<String> bindings = new ArrayList<>(apiScope.getRoles());
|
||||||
bindings.add(ADMIN_ROLE_KEY);
|
bindings.add(ADMIN_ROLE_KEY);
|
||||||
scope.setBindings(bindings);
|
scope.setBindings(bindings);
|
||||||
publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
publisherRESTAPIServices.addNewSharedScope(scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
APIInfo api = getAPI(apiConfig, true);
|
APIInfo api = getAPI(apiConfig, true);
|
||||||
APIInfo createdAPI = publisherRESTAPIServices.addAPI(apiApplicationKey, accessTokenInfo, api);
|
APIInfo createdAPI = publisherRESTAPIServices.addAPI(api);
|
||||||
apiUuid = createdAPI.getId();
|
apiUuid = createdAPI.getId();
|
||||||
if (apiConfig.getEndpointType() != null && "WS".equals(apiConfig.getEndpointType())) {
|
if (apiConfig.getEndpointType() != null && "WS".equals(apiConfig.getEndpointType())) {
|
||||||
publisherRESTAPIServices.saveAsyncApiDefinition(apiApplicationKey, accessTokenInfo,
|
publisherRESTAPIServices.saveAsyncApiDefinition(apiUuid, apiConfig.getAsyncApiDefinition());
|
||||||
apiUuid, apiConfig.getAsyncApiDefinition());
|
|
||||||
}
|
}
|
||||||
if (CREATED_STATUS.equals(createdAPI.getLifeCycleStatus())) {
|
if (CREATED_STATUS.equals(createdAPI.getLifeCycleStatus())) {
|
||||||
// if endpoint type "dynamic" and then add in sequence
|
// if endpoint type "dynamic" and then add in sequence
|
||||||
@ -216,17 +194,14 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
mediation.setConfig(apiConfig.getInSequenceConfig());
|
mediation.setConfig(apiConfig.getInSequenceConfig());
|
||||||
mediation.setType("in");
|
mediation.setType("in");
|
||||||
mediation.setGlobal(false);
|
mediation.setGlobal(false);
|
||||||
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey,
|
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiUuid, mediation);
|
||||||
accessTokenInfo, apiUuid, mediation);
|
|
||||||
}
|
}
|
||||||
publisherRESTAPIServices.changeLifeCycleStatus(apiApplicationKey, accessTokenInfo,
|
publisherRESTAPIServices.changeLifeCycleStatus(apiUuid, PUBLISH_ACTION);
|
||||||
apiUuid, PUBLISH_ACTION);
|
|
||||||
|
|
||||||
APIRevision apiRevision = new APIRevision();
|
APIRevision apiRevision = new APIRevision();
|
||||||
apiRevision.setApiUUID(apiUuid);
|
apiRevision.setApiUUID(apiUuid);
|
||||||
apiRevision.setDescription("Initial Revision");
|
apiRevision.setDescription("Initial Revision");
|
||||||
String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiApplicationKey,
|
String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiRevision).getId();
|
||||||
accessTokenInfo, apiRevision).getId();
|
|
||||||
|
|
||||||
APIRevisionDeployment apiRevisionDeployment = new APIRevisionDeployment();
|
APIRevisionDeployment apiRevisionDeployment = new APIRevisionDeployment();
|
||||||
apiRevisionDeployment.setName(API_PUBLISH_ENVIRONMENT);
|
apiRevisionDeployment.setName(API_PUBLISH_ENVIRONMENT);
|
||||||
@ -235,8 +210,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
|
|
||||||
List<APIRevisionDeployment> apiRevisionDeploymentList = new ArrayList<>();
|
List<APIRevisionDeployment> apiRevisionDeploymentList = new ArrayList<>();
|
||||||
apiRevisionDeploymentList.add(apiRevisionDeployment);
|
apiRevisionDeploymentList.add(apiRevisionDeployment);
|
||||||
publisherRESTAPIServices.deployAPIRevision(apiApplicationKey, accessTokenInfo,
|
publisherRESTAPIServices.deployAPIRevision(apiUuid, apiRevisionId, apiRevisionDeploymentList);
|
||||||
apiUuid, apiRevisionId, apiRevisionDeploymentList);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (WebappPublisherConfig.getInstance().isEnabledUpdateApi()) {
|
if (WebappPublisherConfig.getInstance().isEnabledUpdateApi()) {
|
||||||
@ -259,8 +233,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
for (ApiScope apiScope : apiConfig.getScopes()) {
|
for (ApiScope apiScope : apiConfig.getScopes()) {
|
||||||
// if the scope is not available as shared scope, and it is assigned to an API as a local scope
|
// if the scope is not available as shared scope, and it is assigned to an API as a local scope
|
||||||
// need remove the local scope and add as a shared scope
|
// need remove the local scope and add as a shared scope
|
||||||
if (!publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo,
|
if (!publisherRESTAPIServices.isSharedScopeNameExists(apiScope.getKey())) {
|
||||||
apiScope.getKey())) {
|
|
||||||
if (apiProvider.isScopeKeyAssignedLocally(apiIdentifier, apiScope.getKey(), tenantId)) {
|
if (apiProvider.isScopeKeyAssignedLocally(apiIdentifier, apiScope.getKey(), tenantId)) {
|
||||||
// collect scope to move as shared scopes
|
// collect scope to move as shared scopes
|
||||||
scopesToMoveAsSharedScopes.add(apiScope);
|
scopesToMoveAsSharedScopes.add(apiScope);
|
||||||
@ -273,20 +246,19 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
List<String> bindings = new ArrayList<>(apiScope.getRoles());
|
List<String> bindings = new ArrayList<>(apiScope.getRoles());
|
||||||
bindings.add(ADMIN_ROLE_KEY);
|
bindings.add(ADMIN_ROLE_KEY);
|
||||||
scope.setBindings(bindings);
|
scope.setBindings(bindings);
|
||||||
publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
publisherRESTAPIServices.addNewSharedScope(scope);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get existing API
|
// Get existing API
|
||||||
APIInfo existingAPI = publisherRESTAPIServices.getApi(apiApplicationKey, accessTokenInfo,
|
APIInfo existingAPI = publisherRESTAPIServices.getApi(apiUuid);
|
||||||
apiUuid);
|
|
||||||
if (scopesToMoveAsSharedScopes.size() > 0) {
|
if (scopesToMoveAsSharedScopes.size() > 0) {
|
||||||
// update API to remove local scopes
|
// update API to remove local scopes
|
||||||
APIInfo api = getAPI(apiConfig, false);
|
APIInfo api = getAPI(apiConfig, false);
|
||||||
api.setLifeCycleStatus(existingAPI.getLifeCycleStatus());
|
api.setLifeCycleStatus(existingAPI.getLifeCycleStatus());
|
||||||
publisherRESTAPIServices.updateApi(apiApplicationKey, accessTokenInfo, api);
|
publisherRESTAPIServices.updateApi(api);
|
||||||
|
|
||||||
for (ApiScope apiScope : scopesToMoveAsSharedScopes) {
|
for (ApiScope apiScope : scopesToMoveAsSharedScopes) {
|
||||||
Scope scope = new Scope();
|
Scope scope = new Scope();
|
||||||
@ -296,19 +268,18 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
List<String> bindings = new ArrayList<>(apiScope.getRoles());
|
List<String> bindings = new ArrayList<>(apiScope.getRoles());
|
||||||
bindings.add(ADMIN_ROLE_KEY);
|
bindings.add(ADMIN_ROLE_KEY);
|
||||||
scope.setBindings(bindings);
|
scope.setBindings(bindings);
|
||||||
publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
publisherRESTAPIServices.addNewSharedScope(scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
existingAPI = publisherRESTAPIServices.getApi(apiApplicationKey, accessTokenInfo, apiUuid);
|
existingAPI = publisherRESTAPIServices.getApi(apiUuid);
|
||||||
APIInfo api = getAPI(apiConfig, true);
|
APIInfo api = getAPI(apiConfig, true);
|
||||||
api.setLifeCycleStatus(existingAPI.getLifeCycleStatus());
|
api.setLifeCycleStatus(existingAPI.getLifeCycleStatus());
|
||||||
api.setId(apiUuid);
|
api.setId(apiUuid);
|
||||||
publisherRESTAPIServices.updateApi(apiApplicationKey, accessTokenInfo, api);
|
publisherRESTAPIServices.updateApi(api);
|
||||||
|
|
||||||
if (apiConfig.getEndpointType() != null && "WS".equals(apiConfig.getEndpointType())) {
|
if (apiConfig.getEndpointType() != null && "WS".equals(apiConfig.getEndpointType())) {
|
||||||
publisherRESTAPIServices.saveAsyncApiDefinition(apiApplicationKey, accessTokenInfo,
|
publisherRESTAPIServices.saveAsyncApiDefinition(apiUuid, apiConfig.getAsyncApiDefinition());
|
||||||
apiUuid, apiConfig.getAsyncApiDefinition());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if endpoint type "dynamic" and then add /update in sequence
|
// if endpoint type "dynamic" and then add /update in sequence
|
||||||
@ -320,45 +291,37 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
mediation.setGlobal(false);
|
mediation.setGlobal(false);
|
||||||
|
|
||||||
MediationPolicy[] mediationList = publisherRESTAPIServices
|
MediationPolicy[] mediationList = publisherRESTAPIServices
|
||||||
.getAllApiSpecificMediationPolicies(apiApplicationKey, accessTokenInfo, apiUuid);
|
.getAllApiSpecificMediationPolicies(apiUuid);
|
||||||
|
|
||||||
boolean isMediationPolicyFound = false;
|
boolean isMediationPolicyFound = false;
|
||||||
for (int i = 0; i < mediationList.length; i++) {
|
for (int i = 0; i < mediationList.length; i++) {
|
||||||
MediationPolicy mediationPolicy = mediationList[i];
|
MediationPolicy mediationPolicy = mediationList[i];
|
||||||
if (apiConfig.getInSequenceName().equals(mediationPolicy.getName())) {
|
if (apiConfig.getInSequenceName().equals(mediationPolicy.getName())) {
|
||||||
mediation.setUuid(mediationPolicy.getId());
|
mediation.setUuid(mediationPolicy.getId());
|
||||||
publisherRESTAPIServices.deleteApiSpecificMediationPolicy(apiApplicationKey,
|
publisherRESTAPIServices.deleteApiSpecificMediationPolicy(apiUuid, mediation);
|
||||||
accessTokenInfo, apiUuid, mediation);
|
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiUuid, mediation);
|
||||||
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey,
|
|
||||||
accessTokenInfo, apiUuid, mediation);
|
|
||||||
isMediationPolicyFound = true;
|
isMediationPolicyFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isMediationPolicyFound) {
|
if (!isMediationPolicyFound) {
|
||||||
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey,
|
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiUuid, mediation);
|
||||||
accessTokenInfo, apiUuid, mediation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int apiRevisionCount = publisherRESTAPIServices.getAPIRevisions(apiApplicationKey,
|
int apiRevisionCount = publisherRESTAPIServices.getAPIRevisions(apiUuid, null).length;
|
||||||
accessTokenInfo, apiUuid, null).length;
|
|
||||||
if (apiRevisionCount >= 5) {
|
if (apiRevisionCount >= 5) {
|
||||||
// This will retrieve the deployed revision
|
// This will retrieve the deployed revision
|
||||||
APIRevision[] revisionDeploymentList = publisherRESTAPIServices.getAPIRevisions(
|
APIRevision[] revisionDeploymentList = publisherRESTAPIServices.getAPIRevisions(apiUuid, true);
|
||||||
apiApplicationKey, accessTokenInfo, apiUuid, true);
|
|
||||||
if (revisionDeploymentList.length > 0) {
|
if (revisionDeploymentList.length > 0) {
|
||||||
APIRevision latestRevisionDeployment = revisionDeploymentList[0];
|
APIRevision latestRevisionDeployment = revisionDeploymentList[0];
|
||||||
publisherRESTAPIServices.undeployAPIRevisionDeployment(apiApplicationKey,
|
publisherRESTAPIServices.undeployAPIRevisionDeployment(latestRevisionDeployment, apiUuid);
|
||||||
accessTokenInfo, latestRevisionDeployment, apiUuid);
|
|
||||||
}
|
}
|
||||||
// This will retrieve the undeployed revision list
|
// This will retrieve the undeployed revision list
|
||||||
APIRevision[] undeployedRevisionList = publisherRESTAPIServices.getAPIRevisions(apiApplicationKey,
|
APIRevision[] undeployedRevisionList = publisherRESTAPIServices.getAPIRevisions(apiUuid, false);
|
||||||
accessTokenInfo, apiUuid, false);
|
|
||||||
if (undeployedRevisionList.length > 0) {
|
if (undeployedRevisionList.length > 0) {
|
||||||
APIRevision earliestUndeployRevision = undeployedRevisionList[0];
|
APIRevision earliestUndeployRevision = undeployedRevisionList[0];
|
||||||
publisherRESTAPIServices.deleteAPIRevision(apiApplicationKey, accessTokenInfo,
|
publisherRESTAPIServices.deleteAPIRevision(earliestUndeployRevision, apiUuid);
|
||||||
earliestUndeployRevision, apiUuid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,8 +329,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
APIRevision apiRevision = new APIRevision();
|
APIRevision apiRevision = new APIRevision();
|
||||||
apiRevision.setApiUUID(apiUuid);
|
apiRevision.setApiUUID(apiUuid);
|
||||||
apiRevision.setDescription("Updated Revision");
|
apiRevision.setDescription("Updated Revision");
|
||||||
String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiApplicationKey,
|
String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiRevision).getId();
|
||||||
accessTokenInfo, apiRevision).getId();
|
|
||||||
|
|
||||||
APIRevisionDeployment apiRevisionDeployment = new APIRevisionDeployment();
|
APIRevisionDeployment apiRevisionDeployment = new APIRevisionDeployment();
|
||||||
apiRevisionDeployment.setName(API_PUBLISH_ENVIRONMENT);
|
apiRevisionDeployment.setName(API_PUBLISH_ENVIRONMENT);
|
||||||
@ -377,12 +339,10 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
List<APIRevisionDeployment> apiRevisionDeploymentList = new ArrayList<>();
|
List<APIRevisionDeployment> apiRevisionDeploymentList = new ArrayList<>();
|
||||||
apiRevisionDeploymentList.add(apiRevisionDeployment);
|
apiRevisionDeploymentList.add(apiRevisionDeployment);
|
||||||
|
|
||||||
publisherRESTAPIServices.deployAPIRevision(apiApplicationKey, accessTokenInfo,
|
publisherRESTAPIServices.deployAPIRevision(apiUuid, apiRevisionId, apiRevisionDeploymentList);
|
||||||
apiUuid, apiRevisionId, apiRevisionDeploymentList);
|
|
||||||
|
|
||||||
if (CREATED_STATUS.equals(existingAPI.getLifeCycleStatus())) {
|
if (CREATED_STATUS.equals(existingAPI.getLifeCycleStatus())) {
|
||||||
publisherRESTAPIServices.changeLifeCycleStatus(apiApplicationKey, accessTokenInfo,
|
publisherRESTAPIServices.changeLifeCycleStatus(apiUuid, PUBLISH_ACTION);
|
||||||
apiUuid, PUBLISH_ACTION);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,26 +372,23 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
apiDocumentation.setSummary(apiConfig.getApiDocumentationSummary());
|
apiDocumentation.setSummary(apiConfig.getApiDocumentationSummary());
|
||||||
apiDocumentation.setOtherTypeName(null);
|
apiDocumentation.setOtherTypeName(null);
|
||||||
|
|
||||||
Documentation[] documentList = publisherRESTAPIServices.getDocumentations(apiApplicationKey,
|
Documentation[] documentList = publisherRESTAPIServices.getDocumentations(apiUuid);
|
||||||
accessTokenInfo, apiUuid);
|
|
||||||
|
|
||||||
if (documentList.length > 0) {
|
if (documentList.length > 0) {
|
||||||
for (int i = 0; i < documentList.length; i++) {
|
for (int i = 0; i < documentList.length; i++) {
|
||||||
Documentation existingDoc = documentList[i];
|
Documentation existingDoc = documentList[i];
|
||||||
if (existingDoc.getName().equals(apiConfig.getApiDocumentationName())
|
if (existingDoc.getName().equals(apiConfig.getApiDocumentationName())
|
||||||
&& existingDoc.getType().equals(Documentation.DocumentationType.HOWTO.name())) {
|
&& existingDoc.getType().equals(Documentation.DocumentationType.HOWTO.name())) {
|
||||||
publisherRESTAPIServices.deleteDocumentations(apiApplicationKey, accessTokenInfo,
|
publisherRESTAPIServices.deleteDocumentations(apiUuid, existingDoc.getDocumentId());
|
||||||
apiUuid, existingDoc.getDocumentId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.info("There is no any existing api documentation.");
|
log.info("There is no any existing api documentation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Documentation createdDoc = publisherRESTAPIServices.addDocumentation(apiApplicationKey, accessTokenInfo,
|
Documentation createdDoc = publisherRESTAPIServices.addDocumentation(apiUuid, apiDocumentation);
|
||||||
apiUuid, apiDocumentation);
|
|
||||||
|
|
||||||
publisherRESTAPIServices.addDocumentationContent(apiApplicationKey, accessTokenInfo, apiUuid,
|
publisherRESTAPIServices.addDocumentationContent(apiUuid,
|
||||||
createdDoc.getDocumentId(), docContent);
|
createdDoc.getDocumentId(), docContent);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -441,7 +398,6 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
log.error(msg, e);
|
log.error(msg, e);
|
||||||
throw new APIManagerPublisherException(e);
|
throw new APIManagerPublisherException(e);
|
||||||
} finally {
|
} finally {
|
||||||
APIPublisherUtils.removeScopePublishUserIfExists(tenantDomain);
|
|
||||||
PrivilegedCarbonContext.endTenantFlow();
|
PrivilegedCarbonContext.endTenantFlow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -461,7 +417,6 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
|
|
||||||
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
|
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
|
||||||
DefaultPermissions defaultPermissions = deviceManagementConfig.getDefaultPermissions();
|
DefaultPermissions defaultPermissions = deviceManagementConfig.getDefaultPermissions();
|
||||||
APIApplicationServices apiApplicationServices = APIPublisherDataHolder.getInstance().getApiApplicationServices();
|
|
||||||
PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices();
|
PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices();
|
||||||
|
|
||||||
for (String tenantDomain : tenants) {
|
for (String tenantDomain : tenants) {
|
||||||
@ -469,17 +424,9 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
PrivilegedCarbonContext.startTenantFlow();
|
PrivilegedCarbonContext.startTenantFlow();
|
||||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
|
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
|
||||||
|
|
||||||
APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain);
|
|
||||||
APIApplicationKey apiApplicationKey =
|
|
||||||
apiApplicationServices.createAndRetrieveApplicationCredentials();
|
|
||||||
AccessTokenInfo accessTokenInfo =
|
|
||||||
apiApplicationServices.generateAccessTokenFromRegisteredApplication(
|
|
||||||
apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret());
|
|
||||||
|
|
||||||
Scope scope = new Scope();
|
Scope scope = new Scope();
|
||||||
for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) {
|
for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) {
|
||||||
if (!publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo,
|
if (!publisherRESTAPIServices.isSharedScopeNameExists(defaultPermission.getScopeMapping().getKey())) {
|
||||||
defaultPermission.getScopeMapping().getKey())) {
|
|
||||||
ScopeMapping scopeMapping = defaultPermission.getScopeMapping();
|
ScopeMapping scopeMapping = defaultPermission.getScopeMapping();
|
||||||
|
|
||||||
List<String> bindings = new ArrayList<>(
|
List<String> bindings = new ArrayList<>(
|
||||||
@ -489,7 +436,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
scope.setDescription(scopeMapping.getName());
|
scope.setDescription(scopeMapping.getName());
|
||||||
scope.setDisplayName(scopeMapping.getName());
|
scope.setDisplayName(scopeMapping.getName());
|
||||||
scope.setBindings(bindings);
|
scope.setBindings(bindings);
|
||||||
publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
publisherRESTAPIServices.addNewSharedScope(scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (BadRequestException | UnexpectedResponseException | APIServicesException e) {
|
} catch (BadRequestException | UnexpectedResponseException | APIServicesException e) {
|
||||||
@ -497,7 +444,6 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
log.error(errorMsg, e);
|
log.error(errorMsg, e);
|
||||||
throw new APIManagerPublisherException(e);
|
throw new APIManagerPublisherException(e);
|
||||||
} finally {
|
} finally {
|
||||||
APIPublisherUtils.removeScopePublishUserIfExists(tenantDomain);
|
|
||||||
PrivilegedCarbonContext.endTenantFlow();
|
PrivilegedCarbonContext.endTenantFlow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,12 +457,8 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
WebappPublisherConfig config = WebappPublisherConfig.getInstance();
|
WebappPublisherConfig config = WebappPublisherConfig.getInstance();
|
||||||
List<String> tenants = new ArrayList<>(Collections.singletonList(APIConstants.SUPER_TENANT_DOMAIN));
|
List<String> tenants = new ArrayList<>(Collections.singletonList(APIConstants.SUPER_TENANT_DOMAIN));
|
||||||
tenants.addAll(config.getTenants().getTenant());
|
tenants.addAll(config.getTenants().getTenant());
|
||||||
|
|
||||||
APIApplicationServices apiApplicationServices = APIPublisherDataHolder.getInstance().getApiApplicationServices();
|
|
||||||
PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices();
|
PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices();
|
||||||
|
|
||||||
APIApplicationKey apiApplicationKey;
|
|
||||||
AccessTokenInfo accessTokenInfo;
|
|
||||||
UserStoreManager userStoreManager;
|
UserStoreManager userStoreManager;
|
||||||
String fileName = null;
|
String fileName = null;
|
||||||
|
|
||||||
@ -524,16 +466,6 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
try {
|
try {
|
||||||
PrivilegedCarbonContext.startTenantFlow();
|
PrivilegedCarbonContext.startTenantFlow();
|
||||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
|
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
|
||||||
try {
|
|
||||||
APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain);
|
|
||||||
apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials();
|
|
||||||
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 {
|
try {
|
||||||
fileName =
|
fileName =
|
||||||
@ -599,7 +531,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Set scope details which related to the scope key
|
//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++) {
|
for (int i = 0; i < scopes.length; i++) {
|
||||||
Scope relatedScope = scopes[i];
|
Scope relatedScope = scopes[i];
|
||||||
if (relatedScope.getName().equals(scopeMapping[2].toString())) {
|
if (relatedScope.getName().equals(scopeMapping[2].toString())) {
|
||||||
@ -611,13 +543,13 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
}
|
}
|
||||||
scope.setBindings(rolesList);
|
scope.setBindings(rolesList);
|
||||||
|
|
||||||
if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) {
|
if (publisherRESTAPIServices.isSharedScopeNameExists(scope.getName())) {
|
||||||
publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
publisherRESTAPIServices.updateSharedScope(scope);
|
||||||
// todo: permission changed in update path, is not handled yet.
|
// todo: permission changed in update path, is not handled yet.
|
||||||
} else {
|
} else {
|
||||||
// This scope doesn't have an api attached.
|
// This scope doesn't have an api attached.
|
||||||
log.warn(scope.getName() + " not available as shared, add as new scope");
|
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
|
// add permission if not exist
|
||||||
try {
|
try {
|
||||||
PermissionUtils.putPermission(permission);
|
PermissionUtils.putPermission(permission);
|
||||||
@ -652,7 +584,6 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
log.error(errorMsg, e);
|
log.error(errorMsg, e);
|
||||||
throw new APIManagerPublisherException(e);
|
throw new APIManagerPublisherException(e);
|
||||||
} finally {
|
} finally {
|
||||||
APIPublisherUtils.removeScopePublishUserIfExists(tenantDomain);
|
|
||||||
PrivilegedCarbonContext.endTenantFlow();
|
PrivilegedCarbonContext.endTenantFlow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -661,31 +592,18 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
@Override
|
@Override
|
||||||
public void updateScopeRoleMapping(String roleName, String[] permissions, String[] removedPermissions) throws APIManagerPublisherException {
|
public void updateScopeRoleMapping(String roleName, String[] permissions, String[] removedPermissions) throws APIManagerPublisherException {
|
||||||
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
||||||
APIApplicationServices apiApplicationServices = APIPublisherDataHolder.getInstance().getApiApplicationServices();
|
|
||||||
PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices();
|
PublisherRESTAPIServices publisherRESTAPIServices = APIPublisherDataHolder.getInstance().getPublisherRESTAPIServices();
|
||||||
APIApplicationKey apiApplicationKey;
|
|
||||||
AccessTokenInfo accessTokenInfo;
|
|
||||||
try {
|
|
||||||
APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain);
|
|
||||||
apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials();
|
|
||||||
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 {
|
try {
|
||||||
|
|
||||||
Scope[] scopeList = publisherRESTAPIServices.getScopes(apiApplicationKey, accessTokenInfo);
|
Scope[] scopeList = publisherRESTAPIServices.getScopes();
|
||||||
|
|
||||||
Map<String, String> permScopeMap = APIPublisherDataHolder.getInstance().getPermScopeMapping();
|
Map<String, String> permScopeMap = APIPublisherDataHolder.getInstance().getPermScopeMapping();
|
||||||
if (permissions.length != 0) {
|
if (permissions.length != 0) {
|
||||||
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, permissions, permScopeMap, false);
|
updateScopes(roleName, publisherRESTAPIServices, scopeList, permissions, permScopeMap, false);
|
||||||
}
|
}
|
||||||
if (removedPermissions.length != 0) {
|
if (removedPermissions.length != 0) {
|
||||||
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, removedPermissions, permScopeMap, true);
|
updateScopes(roleName, publisherRESTAPIServices, scopeList, removedPermissions, permScopeMap, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -707,8 +625,6 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
String errorMsg = "Unexpected response from the server";
|
String errorMsg = "Unexpected response from the server";
|
||||||
log.error(errorMsg, e);
|
log.error(errorMsg, e);
|
||||||
throw new APIManagerPublisherException(errorMsg, e);
|
throw new APIManagerPublisherException(errorMsg, e);
|
||||||
} finally {
|
|
||||||
APIPublisherUtils.removeScopePublishUserIfExists(tenantDomain);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,17 +633,13 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
*
|
*
|
||||||
* @param roleName Role Name
|
* @param roleName Role Name
|
||||||
* @param publisherRESTAPIServices {@link PublisherRESTAPIServices}
|
* @param publisherRESTAPIServices {@link PublisherRESTAPIServices}
|
||||||
* @param apiApplicationKey {@link APIApplicationKey}
|
|
||||||
* @param accessTokenInfo {@link AccessTokenInfo}
|
|
||||||
* @param scopeList scope list returning from APIM
|
* @param scopeList scope list returning from APIM
|
||||||
* @param permissions List of permissions
|
* @param permissions List of permissions
|
||||||
* @param permScopeMap Permission Scope map
|
* @param permScopeMap Permission Scope map
|
||||||
* @param removingPermissions if list of permissions has to be removed from the role send true, otherwise sends false.
|
* @param removingPermissions if list of permissions has to be removed from the role send true, otherwise sends false.
|
||||||
* @throws APIManagerPublisherException If the method receives invalid permission to update.
|
* @throws APIManagerPublisherException If the method receives invalid permission to update.
|
||||||
*/
|
*/
|
||||||
private void updateScopes (String roleName, PublisherRESTAPIServices publisherRESTAPIServices,
|
private void updateScopes (String roleName, PublisherRESTAPIServices publisherRESTAPIServices, Scope[] scopeList, String[] permissions, Map<String, String> permScopeMap, boolean removingPermissions )
|
||||||
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
|
||||||
Scope[] scopeList, String[] permissions, Map<String, String> permScopeMap, boolean removingPermissions )
|
|
||||||
throws APIManagerPublisherException {
|
throws APIManagerPublisherException {
|
||||||
for (String permission : permissions) {
|
for (String permission : permissions) {
|
||||||
String scopeValue = permScopeMap.get(permission);
|
String scopeValue = permScopeMap.get(permission);
|
||||||
@ -765,8 +677,8 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|||||||
scope.setBindings(existingRoleList);
|
scope.setBindings(existingRoleList);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) {
|
if (publisherRESTAPIServices.isSharedScopeNameExists(scope.getName())) {
|
||||||
publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
publisherRESTAPIServices.updateSharedScope(scope);
|
||||||
} else {
|
} else {
|
||||||
// todo: come to this level means, that scope is removed from API, but haven't removed from the scope-role-permission-mappings list
|
// 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");
|
log.warn(scope.getName() + " not available as shared scope");
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package io.entgra.device.mgt.core.apimgt.webapp.publisher.internal;
|
package io.entgra.device.mgt.core.apimgt.webapp.publisher.internal;
|
||||||
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
||||||
import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIConfig;
|
import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIConfig;
|
||||||
import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIPublisherService;
|
import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIPublisherService;
|
||||||
@ -49,7 +48,6 @@ public class APIPublisherDataHolder {
|
|||||||
private boolean isServerStarted;
|
private boolean isServerStarted;
|
||||||
private Stack<APIConfig> unpublishedApis = new Stack<>();
|
private Stack<APIConfig> unpublishedApis = new Stack<>();
|
||||||
private Map<String, String> permScopeMapping;
|
private Map<String, String> permScopeMapping;
|
||||||
private APIApplicationServices apiApplicationServices;
|
|
||||||
private PublisherRESTAPIServices publisherRESTAPIServices;
|
private PublisherRESTAPIServices publisherRESTAPIServices;
|
||||||
private MetadataManagementService metadataManagementService;
|
private MetadataManagementService metadataManagementService;
|
||||||
|
|
||||||
@ -160,14 +158,6 @@ public class APIPublisherDataHolder {
|
|||||||
this.permScopeMapping = permScopeMapping;
|
this.permScopeMapping = permScopeMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public APIApplicationServices getApiApplicationServices() {
|
|
||||||
return apiApplicationServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApiApplicationServices(APIApplicationServices apiApplicationServices) {
|
|
||||||
this.apiApplicationServices = apiApplicationServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PublisherRESTAPIServices getPublisherRESTAPIServices() {
|
public PublisherRESTAPIServices getPublisherRESTAPIServices() {
|
||||||
return publisherRESTAPIServices;
|
return publisherRESTAPIServices;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package io.entgra.device.mgt.core.apimgt.webapp.publisher.internal;
|
package io.entgra.device.mgt.core.apimgt.webapp.publisher.internal;
|
||||||
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
||||||
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
|
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
|
||||||
import io.entgra.device.mgt.core.apimgt.webapp.publisher.PostApiPublishingObsever;
|
import io.entgra.device.mgt.core.apimgt.webapp.publisher.PostApiPublishingObsever;
|
||||||
@ -49,12 +48,6 @@ import java.util.HashMap;
|
|||||||
* policy="dynamic"
|
* policy="dynamic"
|
||||||
* bind="setRegistryService"
|
* bind="setRegistryService"
|
||||||
* unbind="unsetRegistryService"
|
* unbind="unsetRegistryService"
|
||||||
* @scr.reference name="APIM.application.service"
|
|
||||||
* interface="io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices"
|
|
||||||
* cardinality="1..1"
|
|
||||||
* policy="dynamic"
|
|
||||||
* bind="setAPIApplicationServices"
|
|
||||||
* unbind="unsetAPIApplicationServices"
|
|
||||||
* @scr.reference name="APIM.publisher.service"
|
* @scr.reference name="APIM.publisher.service"
|
||||||
* interface="io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices"
|
* interface="io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices"
|
||||||
* cardinality="1..1"
|
* cardinality="1..1"
|
||||||
@ -144,20 +137,6 @@ public class APIPublisherServiceComponent {
|
|||||||
APIPublisherDataHolder.getInstance().setRegistryService(null);
|
APIPublisherDataHolder.getInstance().setRegistryService(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setAPIApplicationServices(APIApplicationServices apiApplicationServices) {
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Setting DCR REST API Service");
|
|
||||||
}
|
|
||||||
APIPublisherDataHolder.getInstance().setApiApplicationServices(apiApplicationServices);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void unsetAPIApplicationServices(APIApplicationServices apiApplicationServices) {
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Unsetting DCR REST API Service");
|
|
||||||
}
|
|
||||||
APIPublisherDataHolder.getInstance().setApiApplicationServices(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setPublisherRESTAPIServices(PublisherRESTAPIServices publisherRESTAPIServices) {
|
protected void setPublisherRESTAPIServices(PublisherRESTAPIServices publisherRESTAPIServices) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Setting APIM Publisher REST API Service");
|
log.debug("Setting APIM Publisher REST API Service");
|
||||||
|
|||||||
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.device.mgt.core.config.ui;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement(name = "ExtraQueryParam")
|
||||||
|
public class ExtraQueryParam {
|
||||||
|
private String queryParam;
|
||||||
|
private String paramValue;
|
||||||
|
|
||||||
|
@XmlElement(name = "QueryParam")
|
||||||
|
public String getQueryParam() {
|
||||||
|
return queryParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQueryParam(String queryParam) {
|
||||||
|
this.queryParam = queryParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlElement(name = "ParamValue")
|
||||||
|
public String getParamValue() {
|
||||||
|
return paramValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParamValue(String paramValue) {
|
||||||
|
this.paramValue = paramValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.device.mgt.core.config.ui;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@XmlRootElement(name = "SSOConfiguration")
|
||||||
|
public class SSOConfiguration {
|
||||||
|
private List<ExtraQueryParam> authEndpointExtraQueryParam;
|
||||||
|
|
||||||
|
@XmlElementWrapper(name = "AuthEndpointExtraQueryParams")
|
||||||
|
@XmlElement(name = "ExtraQueryParam")
|
||||||
|
public List<ExtraQueryParam> getAuthEndpointExtraQueryParam() {
|
||||||
|
return authEndpointExtraQueryParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthEndpointExtraQueryParam(List<ExtraQueryParam> authEndpointExtraQueryParam) {
|
||||||
|
this.authEndpointExtraQueryParam = authEndpointExtraQueryParam;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -35,6 +35,7 @@ public class UIConfiguration {
|
|||||||
private int loginCacheCapacity;
|
private int loginCacheCapacity;
|
||||||
private Billing billing;
|
private Billing billing;
|
||||||
private HubspotChat hubspotChat;
|
private HubspotChat hubspotChat;
|
||||||
|
private SSOConfiguration ssoConfiguration;
|
||||||
|
|
||||||
private DeviceInfoConfigurations deviceInfoConfigurations;
|
private DeviceInfoConfigurations deviceInfoConfigurations;
|
||||||
|
|
||||||
@ -121,4 +122,13 @@ public class UIConfiguration {
|
|||||||
public void setDeviceStatusConfigurations(DeviceStatusConfigurations deviceStatusConfigurations) {
|
public void setDeviceStatusConfigurations(DeviceStatusConfigurations deviceStatusConfigurations) {
|
||||||
this.deviceStatusConfigurations = deviceStatusConfigurations;
|
this.deviceStatusConfigurations = deviceStatusConfigurations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@XmlElement(name = "SSOConfiguration", required = true)
|
||||||
|
public SSOConfiguration getSsoConfiguration() {
|
||||||
|
return ssoConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSsoConfiguration(SSOConfiguration ssoConfiguration) {
|
||||||
|
this.ssoConfiguration = ssoConfiguration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
package io.entgra.device.mgt.core.device.mgt.core.internal;
|
package io.entgra.device.mgt.core.device.mgt.core.internal;
|
||||||
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
||||||
import io.entgra.device.mgt.core.device.mgt.common.authorization.GroupAccessAuthorizationService;
|
import io.entgra.device.mgt.core.device.mgt.common.authorization.GroupAccessAuthorizationService;
|
||||||
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService;
|
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService;
|
||||||
@ -98,7 +97,6 @@ public class DeviceManagementDataHolder {
|
|||||||
private WhiteLabelManagementService whiteLabelManagementService;
|
private WhiteLabelManagementService whiteLabelManagementService;
|
||||||
private TraccarManagementService traccarManagementService;
|
private TraccarManagementService traccarManagementService;
|
||||||
private DeviceStatusManagementService deviceStatusManagementService;
|
private DeviceStatusManagementService deviceStatusManagementService;
|
||||||
private APIApplicationServices apiApplicationServices;
|
|
||||||
private PublisherRESTAPIServices publisherRESTAPIServices;
|
private PublisherRESTAPIServices publisherRESTAPIServices;
|
||||||
|
|
||||||
private final Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
|
private final Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
|
||||||
@ -416,23 +414,6 @@ public class DeviceManagementDataHolder {
|
|||||||
this.traccarManagementService = traccarManagementService;
|
this.traccarManagementService = traccarManagementService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the Dynamic Client Registration REST API Service instance from OSGI service context.
|
|
||||||
* @return {@link APIApplicationServices} Dynamic Client Registration REST API Service
|
|
||||||
*/
|
|
||||||
public APIApplicationServices getApiApplicationServices() {
|
|
||||||
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
|
||||||
apiApplicationServices = (APIApplicationServices) ctx.getOSGiService(APIApplicationServices.class, null);
|
|
||||||
if (apiApplicationServices == null) {
|
|
||||||
throw new IllegalStateException("Dynamic Client Registration REST API Service was not initialized.");
|
|
||||||
}
|
|
||||||
return apiApplicationServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApiApplicationServices(APIApplicationServices apiApplicationServices) {
|
|
||||||
this.apiApplicationServices = apiApplicationServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the API Manager Publisher REST API Service instance from OSGI service context.
|
* Retrieves the API Manager Publisher REST API Service instance from OSGI service context.
|
||||||
* @return {@link PublisherRESTAPIServices} API Manager Publisher REST API Service
|
* @return {@link PublisherRESTAPIServices} API Manager Publisher REST API Service
|
||||||
|
|||||||
@ -18,12 +18,9 @@
|
|||||||
package io.entgra.device.mgt.core.device.mgt.core.internal;
|
package io.entgra.device.mgt.core.device.mgt.core.internal;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo;
|
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException;
|
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.BadRequestException;
|
||||||
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
|
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
|
||||||
@ -46,7 +43,6 @@ import org.wso2.carbon.user.api.UserStoreException;
|
|||||||
import org.wso2.carbon.user.api.UserStoreManager;
|
import org.wso2.carbon.user.api.UserStoreManager;
|
||||||
import org.wso2.carbon.utils.AbstractAxis2ConfigurationContextObserver;
|
import org.wso2.carbon.utils.AbstractAxis2ConfigurationContextObserver;
|
||||||
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
|
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
|
||||||
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -163,34 +159,16 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
APIApplicationServices apiApplicationServices = DeviceManagementDataHolder.getInstance().getApiApplicationServices();
|
|
||||||
APIApplicationKey apiApplicationKey;
|
|
||||||
AccessTokenInfo accessTokenInfo;
|
|
||||||
|
|
||||||
try {
|
|
||||||
PrivilegedCarbonContext.startTenantFlow();
|
|
||||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
|
|
||||||
|
|
||||||
APIPublisherUtils.createScopePublishUserIfNotExists(tenantDomain);
|
|
||||||
apiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials();
|
|
||||||
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 {
|
try {
|
||||||
PublisherRESTAPIServices publisherRESTAPIServices = DeviceManagementDataHolder.getInstance().getPublisherRESTAPIServices();
|
PublisherRESTAPIServices publisherRESTAPIServices = DeviceManagementDataHolder.getInstance().getPublisherRESTAPIServices();
|
||||||
Scope[] superTenantScopes = getAllScopesFromSuperTenant(apiApplicationServices, publisherRESTAPIServices);
|
Scope[] superTenantScopes = getAllScopesFromSuperTenant(publisherRESTAPIServices);
|
||||||
|
|
||||||
if (superTenantScopes != null) {
|
if (superTenantScopes != null) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Number of super tenant scopes already published - " + superTenantScopes.length);
|
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 (subTenantScopes.length > 0) {
|
||||||
// If there is already existing scopes on the sub tenant space then do a comparison with the
|
// If there is already existing scopes on the sub tenant space then do a comparison with the
|
||||||
@ -230,8 +208,7 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
|
|||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Starting to add new/updated shared scopes to the tenant: '" + tenantDomain + "'.");
|
log.debug("Starting to add new/updated shared scopes to the tenant: '" + tenantDomain + "'.");
|
||||||
}
|
}
|
||||||
publishSharedScopes(missingScopes, publisherRESTAPIServices, apiApplicationKey,
|
publishSharedScopes(missingScopes, publisherRESTAPIServices);
|
||||||
accessTokenInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Scope subTenantScope : subTenantScopes) {
|
for (Scope subTenantScope : subTenantScopes) {
|
||||||
@ -261,10 +238,9 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
|
|||||||
log.debug("Starting to delete shared scopes from the tenant: '" + tenantDomain + "'.");
|
log.debug("Starting to delete shared scopes from the tenant: '" + tenantDomain + "'.");
|
||||||
}
|
}
|
||||||
for (Scope deletedScope : deletedScopes) {
|
for (Scope deletedScope : deletedScopes) {
|
||||||
if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo,
|
if (publisherRESTAPIServices.isSharedScopeNameExists(deletedScope.getName())) {
|
||||||
deletedScope.getName())) {
|
|
||||||
Scope scope = createScopeObject(deletedScope);
|
Scope scope = createScopeObject(deletedScope);
|
||||||
publisherRESTAPIServices.deleteSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
publisherRESTAPIServices.deleteSharedScope(scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,8 +253,7 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
|
|||||||
log.debug("Starting to publish shared scopes to newly created tenant: '" + tenantDomain + "'.");
|
log.debug("Starting to publish shared scopes to newly created tenant: '" + tenantDomain + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
publishSharedScopes(Arrays.asList(superTenantScopes), publisherRESTAPIServices,
|
publishSharedScopes(Arrays.asList(superTenantScopes), publisherRESTAPIServices);
|
||||||
apiApplicationKey, accessTokenInfo);
|
|
||||||
updatePermScopeMetaData(superTenantPermScopeMapping, metadataManagementService);
|
updatePermScopeMetaData(superTenantPermScopeMapping, metadataManagementService);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -308,7 +283,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
|
|||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new TenantManagementException(msg);
|
throw new TenantManagementException(msg);
|
||||||
} finally {
|
} finally {
|
||||||
APIPublisherUtils.removeScopePublishUserIfExists(tenantDomain);
|
|
||||||
PrivilegedCarbonContext.endTenantFlow();
|
PrivilegedCarbonContext.endTenantFlow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,15 +341,13 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the scopes from the super tenant space
|
* 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
|
* @param publisherRESTAPIServices {@link PublisherRESTAPIServices} is used to get all scopes under a given tenant using client credentials
|
||||||
* @return array of {@link Scope}
|
* @return array of {@link Scope}
|
||||||
* @throws BadRequestException if an invalid request is sent to the API Manager Publisher REST API Service
|
* @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 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
|
* @throws TenantManagementException if an error occurred while processing the request sent to API Manager Publisher REST API Service
|
||||||
*/
|
*/
|
||||||
private Scope[] getAllScopesFromSuperTenant(APIApplicationServices apiApplicationServices,
|
private Scope[] getAllScopesFromSuperTenant(PublisherRESTAPIServices publisherRESTAPIServices) throws BadRequestException,
|
||||||
PublisherRESTAPIServices publisherRESTAPIServices) throws BadRequestException,
|
|
||||||
UnexpectedResponseException, TenantManagementException {
|
UnexpectedResponseException, TenantManagementException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -383,10 +355,7 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
|
|||||||
// in order to see if any new scopes were added or deleted
|
// in order to see if any new scopes were added or deleted
|
||||||
PrivilegedCarbonContext.startTenantFlow();
|
PrivilegedCarbonContext.startTenantFlow();
|
||||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
|
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
|
||||||
APIApplicationKey superTenantApiApplicationKey = apiApplicationServices.createAndRetrieveApplicationCredentials();
|
return publisherRESTAPIServices.getScopes();
|
||||||
AccessTokenInfo superTenantAccessToken = apiApplicationServices.generateAccessTokenFromRegisteredApplication(
|
|
||||||
superTenantApiApplicationKey.getClientId(), superTenantApiApplicationKey.getClientSecret());
|
|
||||||
return publisherRESTAPIServices.getScopes(superTenantApiApplicationKey, superTenantAccessToken);
|
|
||||||
} catch (APIServicesException e) {
|
} catch (APIServicesException e) {
|
||||||
msg = "Error occurred while retrieving access token from super tenant";
|
msg = "Error occurred while retrieving access token from super tenant";
|
||||||
log.error(msg, e);
|
log.error(msg, e);
|
||||||
@ -399,22 +368,18 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
|
|||||||
/**
|
/**
|
||||||
* Add shared scopes to the tenant space.
|
* Add shared scopes to the tenant space.
|
||||||
* @param scopeList {@link List} of {@link Scope}
|
* @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 publisherRESTAPIServices {@link PublisherRESTAPIServices} is used to add shared scopes to a given tenant using client credential
|
||||||
* @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 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 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
|
* @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,
|
private void publishSharedScopes (List<Scope> scopeList, PublisherRESTAPIServices publisherRESTAPIServices)
|
||||||
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo)
|
|
||||||
throws BadRequestException, UnexpectedResponseException, APIServicesException {
|
throws BadRequestException, UnexpectedResponseException, APIServicesException {
|
||||||
|
|
||||||
for (Scope tenantScope : scopeList) {
|
for (Scope tenantScope : scopeList) {
|
||||||
if (!publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo,
|
if (!publisherRESTAPIServices.isSharedScopeNameExists(tenantScope.getName())) {
|
||||||
tenantScope.getName())) {
|
|
||||||
Scope scope = createScopeObject(tenantScope);
|
Scope scope = createScopeObject(tenantScope);
|
||||||
publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
publisherRESTAPIServices.addNewSharedScope(scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -216,11 +216,24 @@ public class InvokerHandler extends HttpServlet {
|
|||||||
*/
|
*/
|
||||||
private static boolean validateRequest(HttpServletRequest req, HttpServletResponse resp)
|
private static boolean validateRequest(HttpServletRequest req, HttpServletResponse resp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
HttpSession session = req.getSession(false);
|
||||||
|
if (session == null) {
|
||||||
|
log.error("Unauthorized, You are not logged in. Please log in to the portal");
|
||||||
|
HandlerUtil.handleError(resp, HttpStatus.SC_UNAUTHORIZED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
apiEndpoint = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
|
apiEndpoint = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
|
||||||
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
|
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
|
||||||
|
|
||||||
kmManagerUrl = HandlerUtil.getKeyManagerUrl(req.getScheme());
|
kmManagerUrl = HandlerUtil.getKeyManagerUrl(req.getScheme());
|
||||||
|
|
||||||
|
if (session.getAttribute(HandlerConstants.API_DOMAIN_PREFIX) != null) {
|
||||||
|
String apiDomainPrefix = session.getAttribute(HandlerConstants.API_DOMAIN_PREFIX).toString();
|
||||||
|
if (!StringUtils.isEmpty(apiDomainPrefix)) {
|
||||||
|
apiEndpoint = apiEndpoint + apiDomainPrefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (HandlerConstants.REPORTS.equalsIgnoreCase(req.getHeader(HandlerConstants.APP_NAME))){
|
if (HandlerConstants.REPORTS.equalsIgnoreCase(req.getHeader(HandlerConstants.APP_NAME))){
|
||||||
apiEndpoint = System.getProperty("iot.reporting.webapp.host");
|
apiEndpoint = System.getProperty("iot.reporting.webapp.host");
|
||||||
if (StringUtils.isBlank(apiEndpoint)){
|
if (StringUtils.isBlank(apiEndpoint)){
|
||||||
@ -230,13 +243,6 @@ public class InvokerHandler extends HttpServlet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpSession session = req.getSession(false);
|
|
||||||
if (session == null) {
|
|
||||||
log.error("Unauthorized, You are not logged in. Please log in to the portal");
|
|
||||||
HandlerUtil.handleError(resp, HttpStatus.SC_UNAUTHORIZED);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
authData = (AuthData) session.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY);
|
authData = (AuthData) session.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY);
|
||||||
if (authData == null) {
|
if (authData == null) {
|
||||||
log.error("Unauthorized, Access token not found in the current session");
|
log.error("Unauthorized, Access token not found in the current session");
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
package io.entgra.device.mgt.core.ui.request.interceptor;
|
package io.entgra.device.mgt.core.ui.request.interceptor;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
@ -53,7 +52,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
|||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@WebServlet(
|
@WebServlet(
|
||||||
@ -65,25 +63,26 @@ import java.util.Objects;
|
|||||||
)
|
)
|
||||||
public class JITEnrollmentCallbackHandler extends HttpServlet {
|
public class JITEnrollmentCallbackHandler extends HttpServlet {
|
||||||
private static final Log log = LogFactory.getLog(JITEnrollmentCallbackHandler.class);
|
private static final Log log = LogFactory.getLog(JITEnrollmentCallbackHandler.class);
|
||||||
private String gatewayUrl;
|
|
||||||
private String keyManagerUrl;
|
private String keyManagerUrl;
|
||||||
|
private String JITProvisionCallbackUrl;
|
||||||
private JITData JITInfo;
|
private JITData JITInfo;
|
||||||
private String encodedClientCredentials;
|
|
||||||
private String applicationName;
|
|
||||||
private String clientId;
|
|
||||||
private String clientSecret;
|
|
||||||
private String scope;
|
private String scope;
|
||||||
private String JITConfigurationPath;
|
private String JITConfigurationPath;
|
||||||
private JITEnrollmentData JITEnrollmentInfo;
|
private JITEnrollmentData JITEnrollmentInfo;
|
||||||
|
private String code;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
||||||
gatewayUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
|
||||||
+ System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
|
|
||||||
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(request.getScheme());
|
|
||||||
keyManagerUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
keyManagerUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
+ System.getProperty(HandlerConstants.IOT_KM_HOST_ENV_VAR)
|
+ System.getProperty(HandlerConstants.IOT_KM_HOST_ENV_VAR)
|
||||||
+ HandlerConstants.COLON + HandlerUtil.getKeyManagerPort(request.getScheme());
|
+ HandlerConstants.COLON + HandlerUtil.getKeyManagerPort(request.getScheme());
|
||||||
|
JITProvisionCallbackUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
|
+ System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
|
||||||
|
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
||||||
|
+ request.getContextPath()
|
||||||
|
+ HandlerConstants.JIT_PROVISION_CALLBACK_URL;
|
||||||
JITConfigurationPath = CarbonUtils.getCarbonConfigDirPath() + File.separator + "jit-config.xml";
|
JITConfigurationPath = CarbonUtils.getCarbonConfigDirPath() + File.separator + "jit-config.xml";
|
||||||
|
|
||||||
HttpSession session = request.getSession(false);
|
HttpSession session = request.getSession(false);
|
||||||
try {
|
try {
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
@ -91,6 +90,14 @@ public class JITEnrollmentCallbackHandler extends HttpServlet {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String state = request.getParameter("state");
|
||||||
|
if (state == null || !Objects.equals(state, session.getAttribute("state").toString())) {
|
||||||
|
response.sendError(org.apache.http.HttpStatus.SC_BAD_REQUEST, "MismatchingStateError: CSRF Warning! " +
|
||||||
|
"State not equal in request and response");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = request.getParameter("code");
|
||||||
JITInfo = (JITData) session.getAttribute(HandlerConstants.SESSION_JIT_DATA_KEY);
|
JITInfo = (JITData) session.getAttribute(HandlerConstants.SESSION_JIT_DATA_KEY);
|
||||||
if (JITInfo == null) {
|
if (JITInfo == null) {
|
||||||
response.sendError(HttpStatus.SC_UNAUTHORIZED);
|
response.sendError(HttpStatus.SC_UNAUTHORIZED);
|
||||||
@ -103,10 +110,8 @@ public class JITEnrollmentCallbackHandler extends HttpServlet {
|
|||||||
response.sendError(HttpStatus.SC_UNAUTHORIZED);
|
response.sendError(HttpStatus.SC_UNAUTHORIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
applicationName = request.getContextPath().substring(1,
|
|
||||||
request.getContextPath().indexOf("-ui-request-handler"));
|
|
||||||
initializeJITEnrollmentConfigurations();
|
initializeJITEnrollmentConfigurations();
|
||||||
populateApplicationData(registerApplication());
|
|
||||||
persistAuthData(session, getToken());
|
persistAuthData(session, getToken());
|
||||||
response.sendRedirect(JITEnrollmentInfo.getRedirectUrl() + "?ownershipType=" +
|
response.sendRedirect(JITEnrollmentInfo.getRedirectUrl() + "?ownershipType=" +
|
||||||
JITEnrollmentInfo.getOwnershipType() + "&os=" + JITEnrollmentInfo.getOs() + "&username=" +
|
JITEnrollmentInfo.getOwnershipType() + "&os=" + JITEnrollmentInfo.getOs() + "&username=" +
|
||||||
@ -177,55 +182,6 @@ public class JITEnrollmentCallbackHandler extends HttpServlet {
|
|||||||
throw new JITEnrollmentException("Unexpected response body return");
|
throw new JITEnrollmentException("Unexpected response body return");
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
|
||||||
* Build application registration request
|
|
||||||
* @return {@link HttpPost} Application registration request
|
|
||||||
*/
|
|
||||||
private HttpPost buildApplicationRegistrationRequest() {
|
|
||||||
HttpPost applicationRegistrationRequest = new HttpPost(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT);
|
|
||||||
applicationRegistrationRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC
|
|
||||||
+ JITInfo.getEncodedClientCredentials());
|
|
||||||
applicationRegistrationRequest.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
|
|
||||||
JsonArray tags = new JsonArray();
|
|
||||||
tags.add("device_management");
|
|
||||||
JsonObject payload = new JsonObject();
|
|
||||||
payload.addProperty("applicationName", applicationName);
|
|
||||||
payload.add("tags", tags);
|
|
||||||
payload.addProperty("allowedToAllDomains", false);
|
|
||||||
payload.addProperty("mappingAnExistingOAuthApp", false);
|
|
||||||
applicationRegistrationRequest.setEntity(new StringEntity(payload.toString(), ContentType.APPLICATION_JSON));
|
|
||||||
return applicationRegistrationRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Populate dynamic client's data
|
|
||||||
* @param application - application data receiving from dcr request
|
|
||||||
*/
|
|
||||||
private void populateApplicationData(JsonObject application) {
|
|
||||||
clientId = application.get("client_id").getAsString();
|
|
||||||
clientSecret = application.get("client_secret").getAsString();
|
|
||||||
String headerValue = clientId+ ':' + clientSecret;
|
|
||||||
encodedClientCredentials = Base64.getEncoder().encodeToString(headerValue.getBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Register client application
|
|
||||||
* @return {@link JsonObject} Json object contain registered application data
|
|
||||||
* @throws JITEnrollmentException throws when error occurred while application registration
|
|
||||||
*/
|
|
||||||
private JsonObject registerApplication() throws JITEnrollmentException {
|
|
||||||
try {
|
|
||||||
ProxyResponse proxyResponse = HandlerUtil.execute(buildApplicationRegistrationRequest());
|
|
||||||
if (proxyResponse.getCode() == HttpStatus.SC_CREATED ||
|
|
||||||
proxyResponse.getCode() == HttpStatus.SC_OK) {
|
|
||||||
return parseResponseData(proxyResponse.getData());
|
|
||||||
}
|
|
||||||
throw new JITEnrollmentException("Unexpected response status return for application registration request");
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new JITEnrollmentException("Error occurred while executing application registration request", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Acquire token
|
* Acquire token
|
||||||
* @return {@link JsonObject} Json object containing token data
|
* @return {@link JsonObject} Json object containing token data
|
||||||
@ -250,11 +206,11 @@ public class JITEnrollmentCallbackHandler extends HttpServlet {
|
|||||||
*/
|
*/
|
||||||
private HttpPost buildTokenAcquireRequest() {
|
private HttpPost buildTokenAcquireRequest() {
|
||||||
HttpPost tokenAcquiringRequest = new HttpPost(keyManagerUrl + HandlerConstants.OAUTH2_TOKEN_ENDPOINT);
|
HttpPost tokenAcquiringRequest = new HttpPost(keyManagerUrl + HandlerConstants.OAUTH2_TOKEN_ENDPOINT);
|
||||||
|
tokenAcquiringRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + JITInfo.getEncodedClientCredentials());
|
||||||
tokenAcquiringRequest.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
|
tokenAcquiringRequest.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
|
||||||
tokenAcquiringRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC
|
|
||||||
+ encodedClientCredentials);
|
|
||||||
StringEntity payload = new StringEntity(
|
StringEntity payload = new StringEntity(
|
||||||
"grant_type=" + HandlerConstants.CLIENT_CREDENTIAL_GRANT_TYPE + "&scope=" + scope,
|
"grant_type=" + HandlerConstants.CODE_GRANT_TYPE + "&code=" + code + "&scope=" + scope +
|
||||||
|
"&redirect_uri=" + JITProvisionCallbackUrl,
|
||||||
ContentType.APPLICATION_FORM_URLENCODED);
|
ContentType.APPLICATION_FORM_URLENCODED);
|
||||||
tokenAcquiringRequest.setEntity(payload);
|
tokenAcquiringRequest.setEntity(payload);
|
||||||
return tokenAcquiringRequest;
|
return tokenAcquiringRequest;
|
||||||
@ -268,9 +224,10 @@ public class JITEnrollmentCallbackHandler extends HttpServlet {
|
|||||||
private void persistAuthData(HttpSession session, JsonObject token) {
|
private void persistAuthData(HttpSession session, JsonObject token) {
|
||||||
AuthData authData = new AuthData();
|
AuthData authData = new AuthData();
|
||||||
authData.setAccessToken(token.get("access_token").getAsString());
|
authData.setAccessToken(token.get("access_token").getAsString());
|
||||||
authData.setClientId(clientId);
|
authData.setRefreshToken(token.get("refresh_token").getAsString());
|
||||||
authData.setClientSecret(clientSecret);
|
authData.setClientId(JITInfo.getClientId());
|
||||||
authData.setEncodedClientApp(encodedClientCredentials);
|
authData.setClientSecret(JITInfo.getClientSecret());
|
||||||
|
authData.setEncodedClientApp(JITInfo.getEncodedClientCredentials());
|
||||||
authData.setScope(token.get("scope").getAsString());
|
authData.setScope(token.get("scope").getAsString());
|
||||||
session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData);
|
session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,6 +49,8 @@ public class JITEnrollmentHandler extends HttpServlet {
|
|||||||
private String os;
|
private String os;
|
||||||
private String redirectUrl;
|
private String redirectUrl;
|
||||||
private String tenantDomain;
|
private String tenantDomain;
|
||||||
|
private String state;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
||||||
try {
|
try {
|
||||||
@ -58,11 +60,12 @@ public class JITEnrollmentHandler extends HttpServlet {
|
|||||||
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
||||||
+ request.getContextPath()
|
+ request.getContextPath()
|
||||||
+ HandlerConstants.JIT_PROVISION_HANDLER;
|
+ HandlerConstants.JIT_PROVISION_HANDLER;
|
||||||
String onCompletionUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
String JITEnrollmentCallbackUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
+ System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
|
+ System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
|
||||||
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
||||||
+ request.getContextPath()
|
+ request.getContextPath()
|
||||||
+ "/jit-enrollment-callback";
|
+ "/jit-enrollment-callback";
|
||||||
|
state = HandlerUtil.generateStateToken();
|
||||||
username = request.getParameter("username");
|
username = request.getParameter("username");
|
||||||
ownershipType = request.getParameter("ownershipType");
|
ownershipType = request.getParameter("ownershipType");
|
||||||
os = request.getParameter("os");
|
os = request.getParameter("os");
|
||||||
@ -71,7 +74,7 @@ public class JITEnrollmentHandler extends HttpServlet {
|
|||||||
String sp = request.getParameter("sp");
|
String sp = request.getParameter("sp");
|
||||||
persistJITData(session);
|
persistJITData(session);
|
||||||
response.sendRedirect(JITProvisionHandlerUrl + "?tenantDomain=" + tenantDomain
|
response.sendRedirect(JITProvisionHandlerUrl + "?tenantDomain=" + tenantDomain
|
||||||
+ "&sp=" + sp + "&redirectUrl=" + onCompletionUrl);
|
+ "&sp=" + sp + "&redirectUrl=" + JITEnrollmentCallbackUrl);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
log.error("Error occurred while handling JIT enrollment request");
|
log.error("Error occurred while handling JIT enrollment request");
|
||||||
}
|
}
|
||||||
@ -88,6 +91,7 @@ public class JITEnrollmentHandler extends HttpServlet {
|
|||||||
JITEnrollmentInfo.setUsername(username);
|
JITEnrollmentInfo.setUsername(username);
|
||||||
JITEnrollmentInfo.setRedirectUrl(redirectUrl);
|
JITEnrollmentInfo.setRedirectUrl(redirectUrl);
|
||||||
JITEnrollmentInfo.setTenantDomain(tenantDomain);
|
JITEnrollmentInfo.setTenantDomain(tenantDomain);
|
||||||
|
session.setAttribute("state", state);
|
||||||
session.setAttribute(HandlerConstants.SESSION_JIT_ENROLLMENT_DATA_KEY, JITEnrollmentInfo);
|
session.setAttribute(HandlerConstants.SESSION_JIT_ENROLLMENT_DATA_KEY, JITEnrollmentInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,13 +18,22 @@
|
|||||||
|
|
||||||
package io.entgra.device.mgt.core.ui.request.interceptor;
|
package io.entgra.device.mgt.core.ui.request.interceptor;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import io.entgra.device.mgt.core.ui.request.interceptor.beans.AuthData;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.beans.JITData;
|
import io.entgra.device.mgt.core.ui.request.interceptor.beans.JITData;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.beans.JITEnrollmentData;
|
import io.entgra.device.mgt.core.ui.request.interceptor.beans.ProxyResponse;
|
||||||
|
import io.entgra.device.mgt.core.ui.request.interceptor.exceptions.JITProvisionException;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerConstants;
|
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerConstants;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerUtil;
|
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerUtil;
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.http.HttpHeaders;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.entity.ContentType;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
@ -43,38 +52,129 @@ import java.util.Objects;
|
|||||||
)
|
)
|
||||||
public class JITProvisionCallbackHandler extends HttpServlet {
|
public class JITProvisionCallbackHandler extends HttpServlet {
|
||||||
private static final Log log = LogFactory.getLog(JITProvisionCallbackHandler.class);
|
private static final Log log = LogFactory.getLog(JITProvisionCallbackHandler.class);
|
||||||
|
private String keyManagerUrl;
|
||||||
|
private String JITProvisionCallbackUrl;
|
||||||
|
private String scope;
|
||||||
|
private String code;
|
||||||
|
private JITData JITInfo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
||||||
String state = request.getParameter("state");
|
JITProvisionCallbackUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
HttpSession session = request.getSession(false);
|
|
||||||
String JITProvisionCallbackURL = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
|
||||||
+ System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
|
+ System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
|
||||||
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
||||||
+ request.getContextPath()
|
+ request.getContextPath()
|
||||||
+ HandlerConstants.JIT_PROVISION_CALLBACK_URL;
|
+ HandlerConstants.JIT_PROVISION_CALLBACK_URL;
|
||||||
|
|
||||||
|
HttpSession session = request.getSession(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
response.sendError(HttpStatus.SC_UNAUTHORIZED);
|
response.sendError(HttpStatus.SC_UNAUTHORIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String state = request.getParameter("state");
|
||||||
if (state == null || !Objects.equals(state, session.getAttribute("state").toString())) {
|
if (state == null || !Objects.equals(state, session.getAttribute("state").toString())) {
|
||||||
response.sendError(org.apache.http.HttpStatus.SC_BAD_REQUEST, "MismatchingStateError: CSRF Warning! " +
|
response.sendError(org.apache.http.HttpStatus.SC_BAD_REQUEST, "MismatchingStateError: CSRF Warning! " +
|
||||||
"State not equal in request and response");
|
"State not equal in request and response");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JITData JITInfo = (JITData) session.getAttribute(HandlerConstants.SESSION_JIT_DATA_KEY);
|
code = request.getParameter("code");
|
||||||
|
JITInfo = (JITData) session.getAttribute(HandlerConstants.SESSION_JIT_DATA_KEY);
|
||||||
if (JITInfo == null) {
|
if (JITInfo == null) {
|
||||||
response.sendError(HttpStatus.SC_UNAUTHORIZED);
|
response.sendError(HttpStatus.SC_UNAUTHORIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.sendRedirect(JITInfo.getRedirectUrl() + "?code=" + request.getParameter("code")
|
if (JITInfo.getApplicationUrl() != null) {
|
||||||
+ "&redirectUrl=" + JITProvisionCallbackURL);
|
handleApplicationLogin(request, response, session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.sendRedirect(JITInfo.getRedirectUrl() + "?code=" + request.getParameter("code") + "&state=" + state);
|
||||||
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
log.error("Error occurred while processing JIT provisioning callback request", ex);
|
log.error("Error occurred while processing JIT provisioning callback request", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleApplicationLogin(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
|
||||||
|
keyManagerUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
|
+ System.getProperty(HandlerConstants.IOT_KM_HOST_ENV_VAR)
|
||||||
|
+ HandlerConstants.COLON + HandlerUtil.getKeyManagerPort(request.getScheme());
|
||||||
|
try {
|
||||||
|
scope = session.getAttribute("scope").toString();
|
||||||
|
persistAuthData(session, getToken());
|
||||||
|
response.sendRedirect(JITInfo.getApplicationUrl());
|
||||||
|
} catch (JITProvisionException | IOException ex) {
|
||||||
|
log.error("Error encountered while handling login request for " + JITInfo.getApplicationUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Parse string data and build json object
|
||||||
|
* @param data - Json string
|
||||||
|
* @return {@link JsonObject} Json object corresponding to provided json string
|
||||||
|
* @throws JITProvisionException throws when error occurred while parsing
|
||||||
|
*/
|
||||||
|
private JsonObject parseResponseData(String data) throws JITProvisionException {
|
||||||
|
JsonParser parser = new JsonParser();
|
||||||
|
JsonElement responseData = parser.parse(data);
|
||||||
|
if (responseData.isJsonObject()) {
|
||||||
|
return responseData.getAsJsonObject();
|
||||||
|
}
|
||||||
|
throw new JITProvisionException("Unexpected response body return");
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Acquire token
|
||||||
|
* @return {@link JsonObject} Json object containing token data
|
||||||
|
* @throws JITProvisionException throws when error occurred while acquiring token
|
||||||
|
*/
|
||||||
|
private JsonObject getToken() throws JITProvisionException {
|
||||||
|
try {
|
||||||
|
ProxyResponse proxyResponse = HandlerUtil.execute(buildTokenAcquireRequest());
|
||||||
|
if (proxyResponse.getCode() == org.apache.http.HttpStatus.SC_CREATED ||
|
||||||
|
proxyResponse.getCode() == org.apache.http.HttpStatus.SC_OK) {
|
||||||
|
return parseResponseData(proxyResponse.getData());
|
||||||
|
}
|
||||||
|
throw new JITProvisionException("Unexpected response status return for token acquiring request");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new JITProvisionException("Error occurred while executing token acquiring request", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Build token acquire request
|
||||||
|
* @return {@link HttpPost} Token acquire request
|
||||||
|
*/
|
||||||
|
private HttpPost buildTokenAcquireRequest() {
|
||||||
|
HttpPost tokenAcquiringRequest = new HttpPost(keyManagerUrl + HandlerConstants.OAUTH2_TOKEN_ENDPOINT);
|
||||||
|
tokenAcquiringRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + JITInfo.getEncodedClientCredentials());
|
||||||
|
tokenAcquiringRequest.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
|
||||||
|
StringEntity payload = new StringEntity(
|
||||||
|
"grant_type=" + HandlerConstants.CODE_GRANT_TYPE + "&code=" + code + "&scope=" + scope +
|
||||||
|
"&redirect_uri=" + JITProvisionCallbackUrl,
|
||||||
|
ContentType.APPLICATION_FORM_URLENCODED);
|
||||||
|
tokenAcquiringRequest.setEntity(payload);
|
||||||
|
return tokenAcquiringRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Persists auth data in session
|
||||||
|
* @param session {@link HttpSession}
|
||||||
|
* @param token Json object containing token data
|
||||||
|
*/
|
||||||
|
private void persistAuthData(HttpSession session, JsonObject token) {
|
||||||
|
AuthData authData = new AuthData();
|
||||||
|
authData.setAccessToken(token.get("access_token").getAsString());
|
||||||
|
authData.setRefreshToken(token.get("refresh_token").getAsString());
|
||||||
|
authData.setClientId(JITInfo.getClientId());
|
||||||
|
authData.setClientSecret(JITInfo.getClientSecret());
|
||||||
|
authData.setEncodedClientApp(JITInfo.getEncodedClientCredentials());
|
||||||
|
authData.setScope(token.get("scope").getAsString());
|
||||||
|
session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,22 +18,18 @@
|
|||||||
|
|
||||||
package io.entgra.device.mgt.core.ui.request.interceptor;
|
package io.entgra.device.mgt.core.ui.request.interceptor;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.beans.JITData;
|
import io.entgra.device.mgt.core.ui.request.interceptor.beans.JITData;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.beans.ProxyResponse;
|
import io.entgra.device.mgt.core.ui.request.interceptor.beans.ProxyResponse;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.exceptions.JITEnrollmentException;
|
import io.entgra.device.mgt.core.ui.request.interceptor.beans.ServiceProvider;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.exceptions.JITProvisionException;
|
import io.entgra.device.mgt.core.ui.request.interceptor.exceptions.JITProvisionException;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerConstants;
|
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerConstants;
|
||||||
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerUtil;
|
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerUtil;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.http.HttpHeaders;
|
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.entity.ContentType;
|
|
||||||
import org.apache.http.entity.StringEntity;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
@ -52,9 +48,11 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.HashMap;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@WebServlet(
|
@WebServlet(
|
||||||
@ -66,53 +64,104 @@ import java.util.Objects;
|
|||||||
)
|
)
|
||||||
public class JITProvisionHandler extends HttpServlet {
|
public class JITProvisionHandler extends HttpServlet {
|
||||||
private static final Log log = LogFactory.getLog(JITProvisionHandler.class);
|
private static final Log log = LogFactory.getLog(JITProvisionHandler.class);
|
||||||
|
private static final String JITConfigurationPath = CarbonUtils.getCarbonConfigDirPath() + File.separator + "jit-config.xml";
|
||||||
|
private static final Gson gson = new Gson();
|
||||||
|
private static Map<String, ServiceProvider> serviceProviders;
|
||||||
private String tenantDomain;
|
private String tenantDomain;
|
||||||
private String clientId;
|
private String clientId;
|
||||||
|
private String clientSecret;
|
||||||
private String JITServiceProviderName;
|
private String JITServiceProviderName;
|
||||||
private String encodedClientCredentials;
|
private String encodedClientCredentials;
|
||||||
private String JITConfigurationPath;
|
|
||||||
private String redirectUrl;
|
private String redirectUrl;
|
||||||
|
private String applicationUrl;
|
||||||
private String state;
|
private String state;
|
||||||
private static final Map<String, Element> tenantConfigs = new HashMap<>();
|
private String scope;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
||||||
String keyManagerUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
String keyManagerUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
+ System.getProperty(HandlerConstants.IOT_KM_HOST_ENV_VAR)
|
+ System.getProperty(HandlerConstants.IOT_KM_HOST_ENV_VAR)
|
||||||
+ HandlerConstants.COLON + HandlerUtil.getKeyManagerPort(request.getScheme());
|
+ HandlerConstants.COLON + HandlerUtil.getKeyManagerPort(request.getScheme());
|
||||||
|
String iotCoreUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
|
+ System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
|
||||||
|
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme());
|
||||||
|
String gatewayUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
|
+ System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
|
||||||
|
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(request.getScheme());
|
||||||
String JITCallbackUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
String JITCallbackUrl = request.getScheme() + HandlerConstants.SCHEME_SEPARATOR
|
||||||
+ System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
|
+ System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
|
||||||
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
+ HandlerConstants.COLON + HandlerUtil.getCorePort(request.getScheme())
|
||||||
+ request.getContextPath()
|
+ request.getContextPath()
|
||||||
+ HandlerConstants.JIT_PROVISION_CALLBACK_URL;
|
+ HandlerConstants.JIT_PROVISION_CALLBACK_URL;
|
||||||
JITConfigurationPath = CarbonUtils.getCarbonConfigDirPath() + File.separator + "jit-config.xml";
|
String uiConfigUrl = iotCoreUrl + HandlerConstants.UI_CONFIG_ENDPOINT;
|
||||||
String scope = "openid";
|
|
||||||
|
HttpSession session = request.getSession(true);
|
||||||
state = HandlerUtil.generateStateToken();
|
state = HandlerUtil.generateStateToken();
|
||||||
tenantDomain = request.getParameter("tenantDomain");
|
tenantDomain = request.getParameter("tenantDomain");
|
||||||
redirectUrl = request.getParameter("redirectUrl");
|
redirectUrl = request.getParameter("redirectUrl");
|
||||||
JITServiceProviderName = request.getParameter("sp");
|
JITServiceProviderName = request.getParameter("sp");
|
||||||
|
applicationUrl = request.getParameter("applicationUrl");
|
||||||
try {
|
try {
|
||||||
|
JsonObject uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, session, response);
|
||||||
|
JsonArray scopeJson = uiConfigJsonObject.get("scopes").getAsJsonArray();
|
||||||
|
JsonObject ssoConfigurations = uiConfigJsonObject.getAsJsonObject("ssoConfiguration");
|
||||||
|
JsonArray authEndpointExtraQueryParam = ssoConfigurations.getAsJsonArray("authEndpointExtraQueryParam");
|
||||||
|
String extraParamString = HandlerUtil.getAuthEndpointExtraQueryParamString(authEndpointExtraQueryParam);
|
||||||
|
scope = "openid " + HandlerUtil.getScopeString(scopeJson);
|
||||||
|
|
||||||
if (tenantDomain == null || JITServiceProviderName == null) {
|
if (tenantDomain == null || JITServiceProviderName == null) {
|
||||||
HandlerUtil.handleError(response, HttpStatus.SC_BAD_REQUEST);
|
HandlerUtil.handleError(response, HttpStatus.SC_BAD_REQUEST);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (serviceProviders == null) {
|
||||||
|
loadServiceProviders();
|
||||||
|
}
|
||||||
|
|
||||||
if (!initializeJITConfigurations()) {
|
if (!initializeJITConfigurations()) {
|
||||||
HandlerUtil.handleError(response, HttpStatus.SC_SERVICE_UNAVAILABLE);
|
HandlerUtil.handleError(response, HttpStatus.SC_SERVICE_UNAVAILABLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
persistJITData(request.getSession(true));
|
persistJITData(session);
|
||||||
response.sendRedirect(keyManagerUrl + HandlerConstants.AUTHORIZATION_ENDPOINT +
|
response.sendRedirect(keyManagerUrl + HandlerConstants.AUTHORIZATION_ENDPOINT +
|
||||||
"?response_type=code" +
|
"?response_type=code" +
|
||||||
"&client_id=" + clientId +
|
"&client_id=" + clientId +
|
||||||
"&state=" + state +
|
"&state=" + state +
|
||||||
"&scope=" + scope +
|
"&scope=" + scope +
|
||||||
"&redirect_uri=" + JITCallbackUrl);
|
"&redirect_uri=" + JITCallbackUrl +
|
||||||
|
extraParamString);
|
||||||
} catch (JITProvisionException | IOException ex) {
|
} catch (JITProvisionException | IOException ex) {
|
||||||
log.error("Error occurred while processing JIT provisioning request", ex);
|
log.error("Error occurred while processing JIT provisioning request", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
tenantDomain = request.getParameter("tenantDomain");
|
||||||
|
try {
|
||||||
|
if (tenantDomain == null) {
|
||||||
|
HandlerUtil.handleError(response, HttpStatus.SC_BAD_REQUEST);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serviceProviders == null) {
|
||||||
|
loadServiceProviders();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ServiceProvider.WhiteLabel> supportingServiceProviders = serviceProviders.values().stream().
|
||||||
|
filter(serviceProvider -> Objects.equals(tenantDomain,
|
||||||
|
serviceProvider.getTenantDomain())).map(ServiceProvider::getWhiteLabel).collect(Collectors.toList());
|
||||||
|
ProxyResponse proxyResponse = new ProxyResponse();
|
||||||
|
proxyResponse.setData(gson.toJson(supportingServiceProviders));
|
||||||
|
proxyResponse.setStatus(ProxyResponse.Status.SUCCESS);
|
||||||
|
proxyResponse.setCode(HttpStatus.SC_OK);
|
||||||
|
HandlerUtil.handleSuccess(response, proxyResponse);
|
||||||
|
} catch (JITProvisionException | IOException ex) {
|
||||||
|
log.error("Error occurred while processing request", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Retrieve JIT data from current session if session exists, otherwise build and return
|
* Retrieve JIT data from current session if session exists, otherwise build and return
|
||||||
* @param session - {@link HttpSession}
|
* @param session - {@link HttpSession}
|
||||||
@ -130,60 +179,52 @@ public class JITProvisionHandler extends HttpServlet {
|
|||||||
private void persistJITData(HttpSession session) {
|
private void persistJITData(HttpSession session) {
|
||||||
JITData JITInfo = getJITData(session);
|
JITData JITInfo = getJITData(session);
|
||||||
JITInfo.setEncodedClientCredentials(encodedClientCredentials);
|
JITInfo.setEncodedClientCredentials(encodedClientCredentials);
|
||||||
|
JITInfo.setClientId(clientId);
|
||||||
|
JITInfo.setClientSecret(clientSecret);
|
||||||
JITInfo.setTenantDomain(tenantDomain);
|
JITInfo.setTenantDomain(tenantDomain);
|
||||||
JITInfo.setRedirectUrl(redirectUrl);
|
JITInfo.setRedirectUrl(redirectUrl);
|
||||||
JITInfo.setSp(JITServiceProviderName);
|
JITInfo.setSp(JITServiceProviderName);
|
||||||
|
JITInfo.setApplicationUrl(applicationUrl);
|
||||||
session.setMaxInactiveInterval(3600);
|
session.setMaxInactiveInterval(3600);
|
||||||
session.setAttribute("state", state);
|
session.setAttribute("state", state);
|
||||||
|
session.setAttribute("scope", scope);
|
||||||
|
if (!Objects.equals(tenantDomain, "carbon.super")) {
|
||||||
|
session.setAttribute(HandlerConstants.API_DOMAIN_PREFIX, "/t/" + tenantDomain);
|
||||||
|
}
|
||||||
session.setAttribute(HandlerConstants.SESSION_JIT_DATA_KEY, JITInfo);
|
session.setAttribute(HandlerConstants.SESSION_JIT_DATA_KEY, JITInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
private void loadServiceProviders() throws JITProvisionException {
|
||||||
* Find the tenant based configurations and return
|
serviceProviders = new ConcurrentHashMap<>();
|
||||||
* @param tenantDomain - Domain of the tenant
|
try {
|
||||||
* @param document - Config doc
|
File JITConfigurationFile = new File(JITConfigurationPath);
|
||||||
* @return {@link Element} If config found return configuration element, otherwise null
|
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||||
*/
|
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||||
private Element findServiceProvider(String tenantDomain, Document document) {
|
Document JITConfigurationDoc = documentBuilder.parse(JITConfigurationFile);
|
||||||
NodeList serviceProviderConfiguration = document.getElementsByTagName("ServiceProvider");
|
JITConfigurationDoc.getDocumentElement().normalize();
|
||||||
for (int idx = 0; idx < serviceProviderConfiguration.getLength(); idx++) {
|
NodeList serviceProviderConfiguration = JITConfigurationDoc.getElementsByTagName("ServiceProvider");
|
||||||
Node configNode = serviceProviderConfiguration.item(idx);
|
for (int idx = 0; idx < serviceProviderConfiguration.getLength(); idx++) {
|
||||||
if (configNode.getNodeType() == Node.ELEMENT_NODE) {
|
Node configNode = serviceProviderConfiguration.item(idx);
|
||||||
Element configElement = (Element) configNode;
|
if (configNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
if (Objects.equals(configElement.getAttributes().
|
Element configElement = (Element) configNode;
|
||||||
getNamedItem("tenantDomain").getNodeValue(), tenantDomain) &&
|
ServiceProvider serviceProvider = new ServiceProvider();
|
||||||
Objects.equals(configElement.getAttributes().getNamedItem("name").getNodeValue(),
|
serviceProvider.setTenantDomain(configElement.getAttributes().getNamedItem("tenantDomain").
|
||||||
JITServiceProviderName)) {
|
getNodeValue());
|
||||||
return configElement;
|
serviceProvider.setName(configElement.getAttributes().getNamedItem("name").getNodeValue());
|
||||||
|
serviceProvider.setClientId(configElement.getElementsByTagName("ClientId").item(0).
|
||||||
|
getTextContent());
|
||||||
|
serviceProvider.setClientSecret(configElement.getElementsByTagName("ClientSecret").item(0).
|
||||||
|
getTextContent());
|
||||||
|
ServiceProvider.WhiteLabel whiteLabel = new ServiceProvider.WhiteLabel(configElement.getElementsByTagName("DisplayName").item(0).
|
||||||
|
getTextContent(), configElement.getElementsByTagName("IconUrl").item(0).
|
||||||
|
getTextContent());
|
||||||
|
whiteLabel.setTenantDomain(serviceProvider.getTenantDomain());
|
||||||
|
whiteLabel.setName(serviceProvider.getName());
|
||||||
|
serviceProvider.setWhiteLabel(whiteLabel);
|
||||||
|
String spKey = serviceProvider.getName() + "@" + serviceProvider.getTenantDomain();
|
||||||
|
serviceProviders.putIfAbsent(spKey, serviceProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Initialize JIT configurations
|
|
||||||
* @return boolean true when successful initialization, otherwise false
|
|
||||||
* @throws JITProvisionException throws when error occurred
|
|
||||||
*/
|
|
||||||
private boolean initializeJITConfigurations() throws JITProvisionException {
|
|
||||||
try {
|
|
||||||
Element serviceProvider = tenantConfigs.get(tenantDomain);
|
|
||||||
if (serviceProvider == null) {
|
|
||||||
File JITConfigurationFile = new File(JITConfigurationPath);
|
|
||||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
|
||||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
|
||||||
Document JITConfigurationDoc = documentBuilder.parse(JITConfigurationFile);
|
|
||||||
JITConfigurationDoc.getDocumentElement().normalize();
|
|
||||||
serviceProvider = findServiceProvider(tenantDomain, JITConfigurationDoc);
|
|
||||||
if (serviceProvider == null) return false;
|
|
||||||
tenantConfigs.put(tenantDomain, serviceProvider);
|
|
||||||
}
|
|
||||||
clientId = serviceProvider.getElementsByTagName("ClientId").item(0).getTextContent();
|
|
||||||
String clientSecret = serviceProvider.getElementsByTagName("ClientSecret").item(0).getTextContent();
|
|
||||||
String headerValue = clientId + ":" + clientSecret;
|
|
||||||
encodedClientCredentials = Base64.getEncoder().encodeToString(headerValue.getBytes());
|
|
||||||
return true;
|
|
||||||
} catch (ParserConfigurationException ex) {
|
} catch (ParserConfigurationException ex) {
|
||||||
String msg = "Error occurred when document builder creating the file configuration";
|
String msg = "Error occurred when document builder creating the file configuration";
|
||||||
throw new JITProvisionException(msg, ex);
|
throw new JITProvisionException(msg, ex);
|
||||||
@ -195,4 +236,20 @@ public class JITProvisionHandler extends HttpServlet {
|
|||||||
throw new JITProvisionException(msg, ex);
|
throw new JITProvisionException(msg, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Initialize JIT configurations
|
||||||
|
* @return boolean true when successful initialization, otherwise false
|
||||||
|
*/
|
||||||
|
private boolean initializeJITConfigurations() {
|
||||||
|
ServiceProvider serviceProvider = serviceProviders.get(JITServiceProviderName + "@" + tenantDomain);
|
||||||
|
if (serviceProvider == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
clientId = serviceProvider.getClientId();
|
||||||
|
clientSecret = serviceProvider.getClientSecret();
|
||||||
|
String headerValue = clientId + ":" + clientSecret;
|
||||||
|
encodedClientCredentials = Base64.getEncoder().encodeToString(headerValue.getBytes());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,12 +130,16 @@ public class SsoLoginHandler extends HttpServlet {
|
|||||||
String loginCallbackUrl = iotsCoreUrl + baseContextPath + HandlerConstants.SSO_LOGIN_CALLBACK;
|
String loginCallbackUrl = iotsCoreUrl + baseContextPath + HandlerConstants.SSO_LOGIN_CALLBACK;
|
||||||
persistAuthSessionData(req, oAuthApp.getClientId(), oAuthApp.getClientSecret(),
|
persistAuthSessionData(req, oAuthApp.getClientId(), oAuthApp.getClientSecret(),
|
||||||
oAuthApp.getEncodedClientApp(), scopesSsoString, state);
|
oAuthApp.getEncodedClientApp(), scopesSsoString, state);
|
||||||
|
JsonObject ssoConfigurations = uiConfigJsonObject.getAsJsonObject("ssoConfiguration");
|
||||||
|
JsonArray authEndpointExtraQueryParam = ssoConfigurations.getAsJsonArray("authEndpointExtraQueryParam");
|
||||||
|
String extraParamString = HandlerUtil.getAuthEndpointExtraQueryParamString(authEndpointExtraQueryParam);
|
||||||
resp.sendRedirect(keyManagerUrl + HandlerConstants.AUTHORIZATION_ENDPOINT +
|
resp.sendRedirect(keyManagerUrl + HandlerConstants.AUTHORIZATION_ENDPOINT +
|
||||||
"?response_type=code" +
|
"?response_type=code" +
|
||||||
"&state=" + state +
|
"&state=" + state +
|
||||||
"&client_id=" + clientId +
|
"&client_id=" + clientId +
|
||||||
"&scope=openid " + scopesSsoString +
|
"&scope=openid " + scopesSsoString +
|
||||||
"&redirect_uri=" + loginCallbackUrl);
|
"&redirect_uri=" + loginCallbackUrl +
|
||||||
|
extraParamString);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Error occurred while sending the response into the socket. ", e);
|
log.error("Error occurred while sending the response into the socket. ", e);
|
||||||
} catch (JsonSyntaxException e) {
|
} catch (JsonSyntaxException e) {
|
||||||
|
|||||||
@ -25,6 +25,9 @@ public class JITData {
|
|||||||
private String redirectUrl;
|
private String redirectUrl;
|
||||||
private String sp;
|
private String sp;
|
||||||
private String encodedClientCredentials;
|
private String encodedClientCredentials;
|
||||||
|
private String clientId;
|
||||||
|
private String clientSecret;
|
||||||
|
private String applicationUrl;
|
||||||
|
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return username;
|
||||||
@ -65,4 +68,28 @@ public class JITData {
|
|||||||
public void setEncodedClientCredentials(String encodedClientCredentials) {
|
public void setEncodedClientCredentials(String encodedClientCredentials) {
|
||||||
this.encodedClientCredentials = encodedClientCredentials;
|
this.encodedClientCredentials = encodedClientCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientSecret() {
|
||||||
|
return clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientSecret(String clientSecret) {
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApplicationUrl() {
|
||||||
|
return applicationUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationUrl(String applicationUrl) {
|
||||||
|
this.applicationUrl = applicationUrl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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.ui.request.interceptor.beans;
|
||||||
|
|
||||||
|
public class ServiceProvider {
|
||||||
|
private String tenantDomain;
|
||||||
|
private String name;
|
||||||
|
private String clientId;
|
||||||
|
private String clientSecret;
|
||||||
|
private WhiteLabel whiteLabel;
|
||||||
|
|
||||||
|
public String getTenantDomain() {
|
||||||
|
return tenantDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenantDomain(String tenantDomain) {
|
||||||
|
this.tenantDomain = tenantDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientSecret() {
|
||||||
|
return clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientSecret(String clientSecret) {
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WhiteLabel getWhiteLabel() {
|
||||||
|
return whiteLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWhiteLabel(WhiteLabel whiteLabel) {
|
||||||
|
this.whiteLabel = whiteLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WhiteLabel {
|
||||||
|
private String displayName;
|
||||||
|
private String iconUrl;
|
||||||
|
private String tenantDomain;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public WhiteLabel(String displayName, String iconUrl) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.iconUrl = iconUrl;
|
||||||
|
}
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIconUrl() {
|
||||||
|
return iconUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIconUrl(String iconUrl) {
|
||||||
|
this.iconUrl = iconUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTenantDomain() {
|
||||||
|
return tenantDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenantDomain(String tenantDomain) {
|
||||||
|
this.tenantDomain = tenantDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -108,6 +108,7 @@ public class HandlerConstants {
|
|||||||
public static final String USER_SCOPES = "userScopes";
|
public static final String USER_SCOPES = "userScopes";
|
||||||
public static final String HUBSPOT_CHAT_URL = "api.hubapi.com";
|
public static final String HUBSPOT_CHAT_URL = "api.hubapi.com";
|
||||||
public static final String USERNAME_WITH_DOMAIN = "usernameWithDomain";
|
public static final String USERNAME_WITH_DOMAIN = "usernameWithDomain";
|
||||||
|
public static final String API_DOMAIN_PREFIX = "apiDomainPrefix";
|
||||||
public static final String JIT_PROVISION_CALLBACK_URL = "/jit-provision-callback";
|
public static final String JIT_PROVISION_CALLBACK_URL = "/jit-provision-callback";
|
||||||
public static final String JIT_ENROLLMENT_HANDLER_CALLBACK_URL = "/jit-enrollment-callback";
|
public static final String JIT_ENROLLMENT_HANDLER_CALLBACK_URL = "/jit-enrollment-callback";
|
||||||
public static final String DCR_URL = "/client-registration/v0.17/register";
|
public static final String DCR_URL = "/client-registration/v0.17/register";
|
||||||
|
|||||||
@ -799,4 +799,18 @@ public class HandlerUtil {
|
|||||||
public static String generateStateToken() {
|
public static String generateStateToken() {
|
||||||
return new BigInteger(130, new SecureRandom()).toString(32);
|
return new BigInteger(130, new SecureRandom()).toString(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getAuthEndpointExtraQueryParamString(JsonArray extraQueryParams) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
if (extraQueryParams != null && extraQueryParams.size() > 0) {
|
||||||
|
for (JsonElement param : extraQueryParams) {
|
||||||
|
if (param.isJsonObject()) {
|
||||||
|
JsonObject paramObj = param.getAsJsonObject();
|
||||||
|
stringBuilder.append("&").append(paramObj.get("queryParam").getAsString()).append("=").
|
||||||
|
append(paramObj.get("paramValue").getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,8 @@
|
|||||||
<!--<ServiceProvider tenantDomain="" name="">
|
<!--<ServiceProvider tenantDomain="" name="">
|
||||||
<ClientId></ClientId>
|
<ClientId></ClientId>
|
||||||
<ClientSecret></ClientSecret>
|
<ClientSecret></ClientSecret>
|
||||||
|
<DisplayName></DisplayName>
|
||||||
|
<IconUrl></IconUrl>
|
||||||
</ServiceProvider>-->
|
</ServiceProvider>-->
|
||||||
</ServiceProviderConfiguration>
|
</ServiceProviderConfiguration>
|
||||||
</JITConfiguration>
|
</JITConfiguration>
|
||||||
@ -429,6 +429,16 @@
|
|||||||
</Scopes>
|
</Scopes>
|
||||||
<SSOConfiguration>
|
<SSOConfiguration>
|
||||||
<Issuer>device-mgt</Issuer>
|
<Issuer>device-mgt</Issuer>
|
||||||
|
<AuthEndpointExtraQueryParams>
|
||||||
|
<ExtraQueryParam>
|
||||||
|
<QueryParam>idpAvailability</QueryParam>
|
||||||
|
<ParamValue>false</ParamValue>
|
||||||
|
</ExtraQueryParam>
|
||||||
|
<ExtraQueryParam>
|
||||||
|
<QueryParam>idpLoginProviderEndpoint</QueryParam>
|
||||||
|
<ParamValue>https://localhost:9443/enroll-web-agent/idp/login</ParamValue>
|
||||||
|
</ExtraQueryParam>
|
||||||
|
</AuthEndpointExtraQueryParams>
|
||||||
</SSOConfiguration>
|
</SSOConfiguration>
|
||||||
</UIConfiguration>
|
</UIConfiguration>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user