|
|
|
@ -18,7 +18,6 @@
|
|
|
|
|
package io.entgra.device.mgt.core.apimgt.webapp.publisher;
|
|
|
|
|
|
|
|
|
|
import com.google.gson.Gson;
|
|
|
|
|
import io.entgra.device.mgt.core.apimgt.annotations.Scopes;
|
|
|
|
|
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;
|
|
|
|
@ -43,7 +42,6 @@ import io.entgra.device.mgt.core.device.mgt.core.config.permission.ScopeMapping;
|
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
|
import org.json.JSONArray;
|
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
import org.wso2.carbon.CarbonConstants;
|
|
|
|
|
import org.wso2.carbon.apimgt.api.APIManagementException;
|
|
|
|
@ -80,6 +78,9 @@ import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
|
import java.util.concurrent.Executors;
|
|
|
|
|
import java.util.concurrent.Phaser;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This class represents the concrete implementation of the APIPublisherService that corresponds to providing all
|
|
|
|
@ -98,8 +99,43 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|
|
|
|
public static final String API_GLOBAL_VISIBILITY = "PUBLIC";
|
|
|
|
|
public static final String API_PRIVATE_VISIBILITY = "PRIVATE";
|
|
|
|
|
private static final String ADMIN_ROLE_KEY = "admin";
|
|
|
|
|
|
|
|
|
|
private static final ExecutorService scopeRoleExecutorService = Executors.newCachedThreadPool();
|
|
|
|
|
private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class);
|
|
|
|
|
public static class ScopeUpdaterTask implements Runnable {
|
|
|
|
|
private final Phaser phaser;
|
|
|
|
|
private final PublisherRESTAPIServices publisherRESTAPIServices;
|
|
|
|
|
private final APIApplicationKey apiApplicationKey;
|
|
|
|
|
private final AccessTokenInfo accessTokenInfo;
|
|
|
|
|
private final Scope scope;
|
|
|
|
|
public ScopeUpdaterTask(Phaser phaser, PublisherRESTAPIServices publisherRESTAPIServices,
|
|
|
|
|
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope) {
|
|
|
|
|
this.phaser = phaser;
|
|
|
|
|
this.publisherRESTAPIServices = publisherRESTAPIServices;
|
|
|
|
|
this.apiApplicationKey = apiApplicationKey;
|
|
|
|
|
this.accessTokenInfo = accessTokenInfo;
|
|
|
|
|
this.scope = scope;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
phaser.register();
|
|
|
|
|
try {
|
|
|
|
|
if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) {
|
|
|
|
|
publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
|
|
|
|
} else {
|
|
|
|
|
// todo: come to this level means, that scope is removed from API, but haven't removed from the scope-role-permission-mappings list
|
|
|
|
|
log.warn(scope.getName() + " not available as shared scope");
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.info("Error occurred while updating role scope mapping via APIM REST endpoint.", e);
|
|
|
|
|
} finally {
|
|
|
|
|
if (log.isDebugEnabled()) {
|
|
|
|
|
log.debug("Role binding is completed for scope" + scope.getName());
|
|
|
|
|
}
|
|
|
|
|
phaser.arriveAndDeregister();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void publishAPI(APIConfig apiConfig) throws APIManagerPublisherException {
|
|
|
|
@ -635,18 +671,12 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|
|
|
|
|
|
|
|
|
Map<String, String> permScopeMap = APIPublisherDataHolder.getInstance().getPermScopeMapping();
|
|
|
|
|
if (permissions.length != 0) {
|
|
|
|
|
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, permissions, permScopeMap, false);
|
|
|
|
|
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList,
|
|
|
|
|
permissions, permissions, permScopeMap, false);
|
|
|
|
|
}
|
|
|
|
|
if (removedPermissions.length != 0) {
|
|
|
|
|
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList, removedPermissions, permScopeMap, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
updatePermissions(roleName, Arrays.asList(permissions));
|
|
|
|
|
} catch (UserStoreException e) {
|
|
|
|
|
String errorMsg = "Error occurred when adding permissions to role: " + roleName;
|
|
|
|
|
log.error(errorMsg, e);
|
|
|
|
|
throw new APIManagerPublisherException(errorMsg, e);
|
|
|
|
|
updateScopes(roleName, publisherRESTAPIServices, apiApplicationKey, accessTokenInfo, scopeList,
|
|
|
|
|
removedPermissions, permissions, permScopeMap, true);
|
|
|
|
|
}
|
|
|
|
|
} catch (APIServicesException e) {
|
|
|
|
|
String errorMsg = "Error while processing Publisher REST API response";
|
|
|
|
@ -677,9 +707,11 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|
|
|
|
* @throws APIManagerPublisherException If the method receives invalid permission to update.
|
|
|
|
|
*/
|
|
|
|
|
private void updateScopes (String roleName, PublisherRESTAPIServices publisherRESTAPIServices,
|
|
|
|
|
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
|
|
|
|
|
Scope[] scopeList, String[] permissions, Map<String, String> permScopeMap, boolean removingPermissions )
|
|
|
|
|
APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope[] scopeList,
|
|
|
|
|
String[] permissions, String[] allowedPermissions,
|
|
|
|
|
Map<String, String> permScopeMap, boolean removingPermissions)
|
|
|
|
|
throws APIManagerPublisherException {
|
|
|
|
|
Phaser phaser = new Phaser(1);
|
|
|
|
|
for (String permission : permissions) {
|
|
|
|
|
String scopeValue = permScopeMap.get(permission);
|
|
|
|
|
if (scopeValue == null) {
|
|
|
|
@ -714,21 +746,21 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
scope.setBindings(existingRoleList);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) {
|
|
|
|
|
publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope);
|
|
|
|
|
} else {
|
|
|
|
|
// todo: come to this level means, that scope is removed from API, but haven't removed from the scope-role-permission-mappings list
|
|
|
|
|
log.warn(scope.getName() + " not available as shared scope");
|
|
|
|
|
}
|
|
|
|
|
} catch (APIServicesException | BadRequestException | UnexpectedResponseException e) {
|
|
|
|
|
log.error("Error occurred while updating role scope mapping via APIM REST endpoint.", e);
|
|
|
|
|
}
|
|
|
|
|
scopeRoleExecutorService.submit(new ScopeUpdaterTask(phaser, publisherRESTAPIServices,
|
|
|
|
|
apiApplicationKey, accessTokenInfo, scope));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
updatePermissions(roleName, Arrays.asList(allowedPermissions));
|
|
|
|
|
} catch (UserStoreException e) {
|
|
|
|
|
String errorMsg = "Error occurred when adding permissions to role: " + roleName;
|
|
|
|
|
log.error(errorMsg, e);
|
|
|
|
|
throw new APIManagerPublisherException(errorMsg, e);
|
|
|
|
|
}
|
|
|
|
|
phaser.arriveAndAwaitAdvance();
|
|
|
|
|
log.info("Permission and scope updating is successfully completed for role : " + roleName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void updatePermissions(String role, List<String> permissions) throws UserStoreException {
|
|
|
|
@ -741,6 +773,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
|
|
|
|
|
authorizationManager.clearRoleAuthorization(role);
|
|
|
|
|
for (String permission : permissions) {
|
|
|
|
|
authorizationManager.authorizeRole(role, permission, CarbonConstants.UI_PERMISSION_ACTION);
|
|
|
|
|
authorizationManager.refreshAllowedRolesForResource(permission);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|