Skip to content

Commit

Permalink
Merge pull request #12721 from hisanhunais/direct-api-restriction
Browse files Browse the repository at this point in the history
Improve Permission Check to Consider Publisher Access Control when Accessing an API via the DevPortal
  • Loading branch information
hisanhunais authored Dec 19, 2024
2 parents 5f795f5 + 9244211 commit 6ddd871
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2382,7 +2382,7 @@ else if (APIConstants.API_KEY_TYPE_SANDBOX.equals(tokenType)) {
} else {
throw new APIManagementException("Invalid Token Type '" + tokenType + "' requested.");
}

if (appRegistrationWorkflow == null ) {
appRegistrationWorkflow = new ApplicationRegistrationSimpleWorkflowExecutor();
}
Expand Down Expand Up @@ -3906,7 +3906,8 @@ public ApiTypeWrapper getAPIorAPIProductByUUID(String uuid, String organization)
uuid);
if (devPortalApi != null) {
checkVisibilityPermission(userNameWithoutChange, devPortalApi.getVisibility(),
devPortalApi.getVisibleRoles());
devPortalApi.getVisibleRoles(), devPortalApi.getPublisherAccessControl(),
devPortalApi.getPublisherAccessControlRoles());
if (APIConstants.API_PRODUCT.equalsIgnoreCase(devPortalApi.getType())) {
APIProduct apiProduct = APIMapper.INSTANCE.toApiProduct(devPortalApi);
apiProduct.setID(new APIProductIdentifier(devPortalApi.getProviderName(),
Expand Down Expand Up @@ -3935,7 +3936,8 @@ public ApiTypeWrapper getAPIorAPIProductByUUID(String uuid, String organization)
}
}

protected void checkVisibilityPermission(String userNameWithTenantDomain, String visibility, String visibilityRoles)
protected void checkVisibilityPermission(String userNameWithTenantDomain, String visibility, String visibilityRoles,
String publisherAccessControl, String publisherAccessControlRoles)
throws APIManagementException {

if (visibility == null || visibility.trim().isEmpty()
Expand All @@ -3945,11 +3947,39 @@ protected void checkVisibilityPermission(String userNameWithTenantDomain, String
}
return;
}
if (APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.APIM_ADMIN)
|| APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.API_CREATE)
|| APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.API_PUBLISH)) {
if (APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.APIM_ADMIN)) {
return;
}
if (APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.API_CREATE)
|| APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.API_PUBLISH)) {
if (publisherAccessControl == null || publisherAccessControl.trim().isEmpty()
|| publisherAccessControl.equalsIgnoreCase(APIConstants.NO_ACCESS_CONTROL)) {
// If the API has not been restricted with publisher access control, the API will be visible to all
// creators and publishers irrespective of devportal visibility restrictions.
return;
} else {
// If the API has been restricted with publisher access control, the API will be visible to creators
// and publishers having the roles which has been specified under publisher access control irrespective
// of devportal visibility restrictions.
if (publisherAccessControlRoles != null && !publisherAccessControlRoles.trim().isEmpty()) {
String[] accessControlRoleList = publisherAccessControlRoles.replaceAll("\\s+", "").split(",");
if (log.isDebugEnabled()) {
log.debug("API has restricted access to creators and publishers with the roles : "
+ Arrays.toString(accessControlRoleList));
}
String[] userRoleList = APIUtil.getListOfRoles(userNameWithTenantDomain);
if (log.isDebugEnabled()) {
log.debug("User " + username + " has roles " + Arrays.toString(userRoleList));
}
for (String role : accessControlRoleList) {
if (!role.equalsIgnoreCase(APIConstants.NULL_USER_ROLE_LIST)
&& APIUtil.compareRoleList(userRoleList, role)) {
return;
}
}
}
}
}

if (visibilityRoles != null && !visibilityRoles.trim().isEmpty()) {
String[] visibilityRolesList = visibilityRoles.replaceAll("\\s+", "").split(",");
Expand Down Expand Up @@ -4032,7 +4062,8 @@ public API getLightweightAPIByUUID(String uuid, String organization) throws APIM
DevPortalAPI devPortalApi = apiPersistenceInstance.getDevPortalAPI(org, uuid);
if (devPortalApi != null) {
checkVisibilityPermission(userNameWithoutChange, devPortalApi.getVisibility(),
devPortalApi.getVisibleRoles());
devPortalApi.getVisibleRoles(), devPortalApi.getPublisherAccessControl(),
devPortalApi.getPublisherAccessControlRoles());
API api = APIMapper.INSTANCE.toApi(devPortalApi);

/// populate relavant external info
Expand Down Expand Up @@ -4266,7 +4297,8 @@ protected void checkAPIVisibilityRestriction(String apiId, String organization)
try {
DevPortalAPI api = apiPersistenceInstance.getDevPortalAPI(new Organization(organization), apiId);
if (api != null) {
checkVisibilityPermission(userNameWithoutChange, api.getVisibility(), api.getVisibleRoles());
checkVisibilityPermission(userNameWithoutChange, api.getVisibility(), api.getVisibleRoles(),
api.getPublisherAccessControl(), api.getPublisherAccessControlRoles());
}
} catch (APIPersistenceException e) {
throw new APIManagementException("Error while accessing dev portal API", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public ApiTypeWrapper getAPIorAPIProductByUUID(String uuid, String organization)
public API getLightweightAPI(APIIdentifier identifier, String orgId) throws APIManagementException {
API api = super.getLightweightAPI(identifier, orgId);
checkVisibilityPermission(userNameWithoutChange, api.getVisibility(),
api.getVisibleRoles());
api.getVisibleRoles(), api.getAccessControl(), api.getAccessControlRoles());
return api;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public class DevPortalAPI extends DevPortalAPIInfo {
private String visibleRoles;
private String gatewayVendor;
private String asyncTransportProtocols;
private String publisherAccessControl;
private String publisherAccessControlRoles;

public String getContextTemplate() {
return contextTemplate;
Expand Down Expand Up @@ -390,7 +392,22 @@ public String getVisibility() {
public void setVisibility(String visibility) {
this.visibility = visibility;
}


public String getPublisherAccessControl() {
return publisherAccessControl;
}

public void setPublisherAccessControl(String publisherAccessControl) {
this.publisherAccessControl = publisherAccessControl;
}

public String getPublisherAccessControlRoles() {
return publisherAccessControlRoles;
}

public void setPublisherAccessControlRoles(String publisherAccessControlRoles) {
this.publisherAccessControlRoles = publisherAccessControlRoles;
}

/*
private String accessControl; //publisher accessControl : 'restricted', 'all' // this won't be required
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ public interface APIMapper {
//@Mapping(source = "visibleTenants", target = "visibleOrganizations")
@Mapping(source = "subscriptionAvailableTenants", target = "subscriptionAvailableOrgs")
//@Mapping(source = "environmentList", target = "environments")
@Mapping(source = "accessControl", target = "publisherAccessControl")
@Mapping(source = "accessControlRoles", target = "publisherAccessControlRoles")
DevPortalAPI toDevPortalApi(API api);

//@Mapping(source = "providerName", target = "id.providerName")
Expand Down

0 comments on commit 6ddd871

Please sign in to comment.