Skip to content

Commit

Permalink
Handle console API authorization and admin role permission assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
ThaminduR committed Feb 7, 2024
1 parent d893b37 commit 2f3ea60
Show file tree
Hide file tree
Showing 15 changed files with 1,012 additions and 364 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,9 @@ public List<Scope> getScopesByTenantId(Integer tenantId, List<ExpressionNode> ex
resultSet.getString(SQLConstants.ID_COLUMN_NAME),
resultSet.getString(SQLConstants.NAME_COLUMN_NAME),
resultSet.getString(SQLConstants.DISPLAY_NAME_COLUMN_NAME),
resultSet.getString(SQLConstants.DESCRIPTION_COLUMN_NAME)
resultSet.getString(SQLConstants.DESCRIPTION_COLUMN_NAME),
resultSet.getString("API_ID"),
resultSet.getString(SQLConstants.TENANT_ID_COLUMN_NAME)
));
}
return scopesList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@
import javax.xml.stream.XMLStreamReader;

/**
* Config builder class for organization management related configs in organization-mgt.xml file.
* Config builder class for system API resource configs in system-api-resource.xml file.
*/
public class APIResourceManagementConfigBuilder {

private static final Log LOG = LogFactory.getLog(APIResourceManagementConfigBuilder.class);
private static final Map<String, APIResource> apiResourceMgtConfigurations = new HashMap<>();
private static final Map<String, APIResource> duplicateAPIResourceConfigs = new HashMap<>();
private static final APIResourceManagementConfigBuilder apiResourceManagementConfigBuilder =
new APIResourceManagementConfigBuilder();

Expand All @@ -67,15 +68,25 @@ private APIResourceManagementConfigBuilder() {
}

/**
* Get organization management related configs.
* Get system API resource configs.
*
* @return Map of org mgt configs.
* @return Map of API resource configs.
*/
public Map<String, APIResource> getAPIResourceMgtConfigurations() {

return apiResourceMgtConfigurations;
}

/**
* Get duplicate system API resource configs.
*
* @return Map of duplicate API resource configs.
*/
public Map<String, APIResource> getDuplicateAPIResourceConfigs() {

return duplicateAPIResourceConfigs;
}

/**
* Read the system-api-resource.xml file and build the configuration map.
*/
Expand Down Expand Up @@ -140,6 +151,17 @@ private void buildAPIResourceConfig() {
apiResourceObj.setScopes(scopeList);
}
}
/* If an API resource with the same identifier already exists in the config map, add the second one
to the duplicate list. During API resource registration, diff will be applied as a patch to the existing
API resource. API resource in the duplicate config map will be considered as the original API resource.
*/
if (apiResourceMgtConfigurations.containsKey(apiResourceObj.getIdentifier())) {
if (LOG.isDebugEnabled()) {
LOG.debug("API resource with duplicate identifier: " + apiResourceObj.getIdentifier() + " found.");
}
duplicateAPIResourceConfigs.put(apiResourceObj.getIdentifier(), apiResourceObj);
continue;
}
apiResourceMgtConfigurations.put(apiResourceObj.getIdentifier(), apiResourceObj);
}
}
Expand All @@ -148,13 +170,6 @@ private APIResource buildAPIResource(OMElement element) {

String apiResourceIdentifier = element.getAttributeValue(
new QName(APIResourceConfigBuilderConstants.IDENTIFIER));
if (apiResourceMgtConfigurations.containsKey(apiResourceIdentifier)) {
if (LOG.isDebugEnabled()) {
LOG.debug("API resource with identifier: " + apiResourceIdentifier + " already exists.");
}
return null;
}

String type = APIResourceConfigBuilderConstants.TENANT_ADMIN_TYPE;
if (element.getAttributeValue(new QName(APIResourceConfigBuilderConstants.TYPE)) != null) {
type = element.getAttributeValue(new QName(APIResourceConfigBuilderConstants.TYPE));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@
import org.wso2.carbon.identity.api.resource.mgt.APIResourceMgtServerException;
import org.wso2.carbon.identity.api.resource.mgt.constant.APIResourceManagementConstants;
import org.wso2.carbon.identity.application.common.model.APIResource;
import org.wso2.carbon.identity.application.common.model.Scope;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* Utility class for API Resource Management.
Expand Down Expand Up @@ -87,22 +90,48 @@ public static void addSystemAPIs() {
String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
Map<String, APIResource> configs = APIResourceManagementConfigBuilder.getInstance()
.getAPIResourceMgtConfigurations();
Map<String, APIResource> duplicateConfigs = APIResourceManagementConfigBuilder.getInstance()
.getDuplicateAPIResourceConfigs();
if (!isSystemAPIExist(tenantDomain)) {
LOG.debug("Registering system API resources in the server.");
registerAPIResources(new ArrayList<>(configs.values()), tenantDomain);
} else {
LOG.debug("System APIs are already registered in the server. Applying the latest configurations.");
// Remove the existing system APIs from the configs.
// Existing system APIs will be evaluated using the identifier.
HashMap<String, APIResource> tempConfigs = new HashMap<>(configs);
List<APIResource> systemAPIs = getSystemAPIs(tenantDomain);
for (APIResource systemAPI : systemAPIs) {
if (configs.containsKey(systemAPI.getIdentifier())) {
configs.remove(systemAPI.getIdentifier());
if (tempConfigs.containsKey(systemAPI.getIdentifier())) {
tempConfigs.remove(systemAPI.getIdentifier());
} else {
String apiId = APIResourceManagerImpl.getInstance().getAPIResourceByIdentifier(
systemAPI.getIdentifier(), tenantDomain).getId();
APIResourceManagerImpl.getInstance().deleteAPIResourceById(apiId, tenantDomain);
}
}
registerAPIResources(new ArrayList<>(configs.values()), tenantDomain);
// Register the new system APIs.
registerAPIResources(new ArrayList<>(tempConfigs.values()), tenantDomain);

// Handle duplicate system APIs.
for (APIResource oldAPIResource : duplicateConfigs.values()) {
// Get the existing API resource from the DB.
APIResource apiResourceFromDB = APIResourceManagerImpl.getInstance().getAPIResourceByIdentifier(
oldAPIResource.getIdentifier(), tenantDomain);
// Get the updated API resource from the configs.
APIResource updatedAPIResource = configs.get(oldAPIResource.getIdentifier());
// Get the scopes which are not in the existing API resource.
List<Scope> addedScopes = updatedAPIResource.getScopes().stream()
.filter(scope1 -> apiResourceFromDB.getScopes().stream()
.noneMatch(scope2 -> scope2.getName().equals(scope1.getName())))
.collect(Collectors.toList());
if (addedScopes.isEmpty()) {
continue;
}
// If there are scopes which are not in the existing API resource, update the API resource.
APIResourceManagerImpl.getInstance().updateAPIResource(apiResourceFromDB, addedScopes,
new ArrayList<>(), tenantDomain);
}
}

LOG.debug("System APIs successfully registered in tenant domain: " + tenantDomain);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,21 @@ public String getAppId() {
return appId;
}

public void setAppId(String appId) {

this.appId = appId;
}

public String getAPIId() {

return apiId;
}

public void setAPIId(String apiId) {

this.apiId = apiId;
}

public String getAPIIdentifier() {

return apiIdentifier;
Expand All @@ -81,6 +91,11 @@ public String getPolicyId() {
return policyId;
}

public void setPolicyId(String policyId) {

this.policyId = policyId;
}

public List<Scope> getScopes() {

return scopes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,13 @@
version="${org.wso2.carbon.identity.organization.management.core.version.range}",
org.wso2.carbon.identity.api.resource.mgt.model; version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.api.resource.mgt.util; version="${carbon.identity.package.import.version.range}",
*;resolution:=optional
</Import-Package>
<Export-Package>
!org.wso2.carbon.identity.application.mgt.internal,
org.wso2.carbon.identity.application.mgt.*; version="${carbon.identity.package.export.version}"
</Export-Package>
<DynamicImport-Package>*</DynamicImport-Package>
</instructions>
</configuration>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@
import org.wso2.carbon.identity.application.mgt.dao.impl.AuthorizedAPIDAOImpl;
import org.wso2.carbon.identity.application.mgt.dao.impl.CacheBackedAuthorizedAPIDAOImpl;
import org.wso2.carbon.identity.application.mgt.internal.ApplicationManagementServiceComponentHolder;
import org.wso2.carbon.identity.application.mgt.internal.ApplicationMgtListenerServiceComponent;
import org.wso2.carbon.identity.application.mgt.listener.AuthorizedAPIManagementListener;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Error.INVALID_REQUEST;
Expand All @@ -51,6 +54,11 @@ public class AuthorizedAPIManagementServiceImpl implements AuthorizedAPIManageme
public void addAuthorizedAPI(String applicationId, AuthorizedAPI authorizedAPI, String tenantDomain)
throws IdentityApplicationManagementException {

Collection<AuthorizedAPIManagementListener> listeners = ApplicationMgtListenerServiceComponent
.getAuthorizedAPIManagementListeners();
for (AuthorizedAPIManagementListener listener : listeners) {
listener.preAddAuthorizedAPI(applicationId, authorizedAPI, tenantDomain);
}
// Check if the application is a main application. If not, throw a client error.
ApplicationManagementService applicationManagementService = ApplicationManagementServiceImpl.getInstance();
String mainAppId = applicationManagementService.getMainAppId(applicationId);
Expand All @@ -59,20 +67,36 @@ public void addAuthorizedAPI(String applicationId, AuthorizedAPI authorizedAPI,
}
authorizedAPIDAO.addAuthorizedAPI(applicationId, authorizedAPI.getAPIId(),
authorizedAPI.getPolicyId(), authorizedAPI.getScopes(), IdentityTenantUtil.getTenantId(tenantDomain));
for (AuthorizedAPIManagementListener listener : listeners) {
listener.postAddAuthorizedAPI(applicationId, authorizedAPI, tenantDomain);
}
}

@Override
public void deleteAuthorizedAPI(String appId, String apiId, String tenantDomain)
throws IdentityApplicationManagementException {

Collection<AuthorizedAPIManagementListener> listeners = ApplicationMgtListenerServiceComponent
.getAuthorizedAPIManagementListeners();
for (AuthorizedAPIManagementListener listener : listeners) {
listener.preDeleteAuthorizedAPI(appId, apiId, tenantDomain);
}
authorizedAPIDAO.deleteAuthorizedAPI(appId, apiId, IdentityTenantUtil.getTenantId(tenantDomain));
for (AuthorizedAPIManagementListener listener : listeners) {
listener.postDeleteAuthorizedAPI(appId, apiId, tenantDomain);
}
}

@Override
public List<AuthorizedAPI> getAuthorizedAPIs(String applicationId, String tenantDomain)
throws IdentityApplicationManagementException {

try {
Collection<AuthorizedAPIManagementListener> listeners = ApplicationMgtListenerServiceComponent
.getAuthorizedAPIManagementListeners();
for (AuthorizedAPIManagementListener listener : listeners) {
listener.preGetAuthorizedAPIs(applicationId, tenantDomain);
}
// Check if the application is a main application else get the main application id and main tenant id.
ApplicationManagementService applicationManagementService = ApplicationManagementServiceImpl.getInstance();
String mainAppId = applicationManagementService.getMainAppId(applicationId);
Expand Down Expand Up @@ -102,6 +126,9 @@ public List<AuthorizedAPI> getAuthorizedAPIs(String applicationId, String tenant
}
authorizedAPI.setScopes(scopeList);
}
for (AuthorizedAPIManagementListener listener : listeners) {
listener.postGetAuthorizedAPIs(authorizedAPIs, applicationId, tenantDomain);
}
return authorizedAPIs;
} catch (APIResourceMgtException e) {
throw buildServerException("Error while retrieving authorized APIs.", e);
Expand All @@ -113,14 +140,27 @@ public void patchAuthorizedAPI(String appId, String apiId, List<String> addedSco
List<String> removedScopes, String tenantDomain)
throws IdentityApplicationManagementException {

Collection<AuthorizedAPIManagementListener> listeners = ApplicationMgtListenerServiceComponent
.getAuthorizedAPIManagementListeners();
for (AuthorizedAPIManagementListener listener : listeners) {
listener.prePatchAuthorizedAPI(appId, apiId, addedScopes, removedScopes, tenantDomain);
}
authorizedAPIDAO.patchAuthorizedAPI(appId, apiId, addedScopes, removedScopes,
IdentityTenantUtil.getTenantId(tenantDomain));
for (AuthorizedAPIManagementListener listener : listeners) {
listener.postPatchAuthorizedAPI(appId, apiId, addedScopes, removedScopes, tenantDomain);
}
}

@Override
public List<AuthorizedScopes> getAuthorizedScopes(String appId, String tenantDomain)
throws IdentityApplicationManagementException {

Collection<AuthorizedAPIManagementListener> listeners = ApplicationMgtListenerServiceComponent
.getAuthorizedAPIManagementListeners();
for (AuthorizedAPIManagementListener listener : listeners) {
listener.preGetAuthorizedScopes(appId, tenantDomain);
}
// Check if the application is a main application else get the main application id and main tenant id.
ApplicationManagementService applicationManagementService = ApplicationManagementServiceImpl.getInstance();
String mainAppId = applicationManagementService.getMainAppId(appId);
Expand All @@ -129,14 +169,24 @@ public List<AuthorizedScopes> getAuthorizedScopes(String appId, String tenantDom
int tenantId = applicationManagementService.getTenantIdByApp(mainAppId);
tenantDomain = IdentityTenantUtil.getTenantDomain(tenantId);
}
return authorizedAPIDAO.getAuthorizedScopes(appId, IdentityTenantUtil.getTenantId(tenantDomain));
List<AuthorizedScopes> authorizedScopes = authorizedAPIDAO.getAuthorizedScopes(appId,
IdentityTenantUtil.getTenantId(tenantDomain));
for (AuthorizedAPIManagementListener listener : listeners) {
listener.postGetAuthorizedScopes(authorizedScopes, appId, tenantDomain);
}
return authorizedScopes;
}

@Override
public AuthorizedAPI getAuthorizedAPI(String appId, String apiId, String tenantDomain)
throws IdentityApplicationManagementException {

try {
Collection<AuthorizedAPIManagementListener> listeners = ApplicationMgtListenerServiceComponent
.getAuthorizedAPIManagementListeners();
for (AuthorizedAPIManagementListener listener : listeners) {
listener.preGetAuthorizedAPI(appId, apiId, tenantDomain);
}
// Check if the application is a main application else get the main application id and main tenant id.
ApplicationManagementService applicationManagementService = ApplicationManagementServiceImpl.getInstance();
String mainAppId = applicationManagementService.getMainAppId(appId);
Expand All @@ -148,22 +198,24 @@ public AuthorizedAPI getAuthorizedAPI(String appId, String apiId, String tenantD

AuthorizedAPI authorizedAPI = authorizedAPIDAO.getAuthorizedAPI(appId, apiId,
IdentityTenantUtil.getTenantId(tenantDomain));
if (authorizedAPI == null) {
return null;
}
APIResource apiResource = ApplicationManagementServiceComponentHolder.getInstance()
.getAPIResourceManager().getAPIResourceById(authorizedAPI.getAPIId(), tenantDomain);
authorizedAPI.setAPIIdentifier(apiResource.getIdentifier());
authorizedAPI.setAPIName(apiResource.getName());
if (authorizedAPI.getScopes() != null) {
// Get Scope data from OSGi service.
List<Scope> scopeList = new ArrayList<>();
for (Scope scope : authorizedAPI.getScopes()) {
Scope scopeWithMetadata = ApplicationManagementServiceComponentHolder.getInstance()
.getAPIResourceManager().getScopeByName(scope.getName(), tenantDomain);
scopeList.add(scopeWithMetadata);
if (authorizedAPI != null) {
APIResource apiResource = ApplicationManagementServiceComponentHolder.getInstance()
.getAPIResourceManager().getAPIResourceById(authorizedAPI.getAPIId(), tenantDomain);
authorizedAPI.setAPIIdentifier(apiResource.getIdentifier());
authorizedAPI.setAPIName(apiResource.getName());
if (authorizedAPI.getScopes() != null) {
// Get Scope data from OSGi service.
List<Scope> scopeList = new ArrayList<>();
for (Scope scope : authorizedAPI.getScopes()) {
Scope scopeWithMetadata = ApplicationManagementServiceComponentHolder.getInstance()
.getAPIResourceManager().getScopeByName(scope.getName(), tenantDomain);
scopeList.add(scopeWithMetadata);
}
authorizedAPI.setScopes(scopeList);
}
authorizedAPI.setScopes(scopeList);
}
for (AuthorizedAPIManagementListener listener : listeners) {
authorizedAPI = listener.postGetAuthorizedAPI(authorizedAPI, appId, apiId, tenantDomain);
}
return authorizedAPI;
} catch (APIResourceMgtException e) {
Expand Down
Loading

0 comments on commit 2f3ea60

Please sign in to comment.