You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2018/06/19 14:13:04 UTC
[airavata] branch group-based-auth updated: Add sharing authz to
app deployment methods
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch group-based-auth
in repository https://gitbox.apache.org/repos/asf/airavata.git
The following commit(s) were added to refs/heads/group-based-auth by this push:
new bb94eb5 Add sharing authz to app deployment methods
bb94eb5 is described below
commit bb94eb5f54e8accc4aa1f1d153499cbb4afacc49
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Tue Jun 19 10:12:34 2018 -0400
Add sharing authz to app deployment methods
---
.../api/server/handler/AiravataServerHandler.java | 71 +++++++++++++++-------
.../service/security/KeyCloakSecurityManager.java | 6 +-
.../security/KeyCloakSecurityManagerTest.java | 35 +++++------
3 files changed, 69 insertions(+), 43 deletions(-)
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
index cc81dfd..cb26637 100644
--- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
+++ b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
@@ -2389,9 +2389,17 @@ public class AiravataServerHandler implements Airavata.Iface {
public ApplicationDeploymentDescription getApplicationDeployment(AuthzToken authzToken, String appDeploymentId)
throws InvalidRequestException, AiravataClientException, AiravataSystemException, AuthorizationException, TException {
RegistryService.Client regClient = registryClientPool.getResource();
+ SharingRegistryService.Client sharingClient = sharingClientPool.getResource();
try {
+ if (ServerSettings.isEnableSharing()) {
+ final boolean hasAccess = userHasAccessInternal(sharingClient, authzToken, appDeploymentId, ResourcePermissionType.READ);
+ if (!hasAccess) {
+ throw new AuthorizationException("User does not have access to application deployment " + appDeploymentId);
+ }
+ }
ApplicationDeploymentDescription result = regClient.getApplicationDeployment(appDeploymentId);
registryClientPool.returnResource(regClient);
+ sharingClientPool.returnResource(sharingClient);
return result;
} catch (Exception e) {
logger.error(appDeploymentId, "Error while retrieving application deployment...", e);
@@ -2399,6 +2407,7 @@ public class AiravataServerHandler implements Airavata.Iface {
exception.setAiravataErrorType(AiravataErrorType.INTERNAL_ERROR);
exception.setMessage("Error while retrieving application deployment. More info : " + e.getMessage());
registryClientPool.returnBrokenResource(regClient);
+ sharingClientPool.returnBrokenResource(sharingClient);
throw exception;
}
}
@@ -2417,9 +2426,17 @@ public class AiravataServerHandler implements Airavata.Iface {
ApplicationDeploymentDescription applicationDeployment)
throws InvalidRequestException, AiravataClientException, AiravataSystemException, AuthorizationException, TException {
RegistryService.Client regClient = registryClientPool.getResource();
+ SharingRegistryService.Client sharingClient = sharingClientPool.getResource();
try {
+ if (ServerSettings.isEnableSharing()) {
+ final boolean hasAccess = userHasAccessInternal(sharingClient, authzToken, appDeploymentId, ResourcePermissionType.WRITE);
+ if (!hasAccess) {
+ throw new AuthorizationException("User does not have WRITE access to application deployment " + appDeploymentId);
+ }
+ }
boolean result = regClient.updateApplicationDeployment(appDeploymentId, applicationDeployment);
registryClientPool.returnResource(regClient);
+ sharingClientPool.returnResource(sharingClient);
return result;
} catch (Exception e) {
logger.error(appDeploymentId, "Error while updating application deployment...", e);
@@ -2427,6 +2444,7 @@ public class AiravataServerHandler implements Airavata.Iface {
exception.setAiravataErrorType(AiravataErrorType.INTERNAL_ERROR);
exception.setMessage("Error while updating application deployment. More info : " + e.getMessage());
registryClientPool.returnBrokenResource(regClient);
+ sharingClientPool.returnBrokenResource(sharingClient);
throw exception;
}
}
@@ -2443,9 +2461,17 @@ public class AiravataServerHandler implements Airavata.Iface {
public boolean deleteApplicationDeployment(AuthzToken authzToken, String appDeploymentId) throws InvalidRequestException,
AiravataClientException, AiravataSystemException, AuthorizationException, TException {
RegistryService.Client regClient = registryClientPool.getResource();
+ SharingRegistryService.Client sharingClient = sharingClientPool.getResource();
try {
+ if (ServerSettings.isEnableSharing()) {
+ final boolean hasAccess = userHasAccessInternal(sharingClient, authzToken, appDeploymentId, ResourcePermissionType.WRITE);
+ if (!hasAccess) {
+ throw new AuthorizationException("User does not have WRITE access to application deployment " + appDeploymentId);
+ }
+ }
boolean result = regClient.deleteApplicationDeployment(appDeploymentId);
registryClientPool.returnResource(regClient);
+ sharingClientPool.returnResource(sharingClient);
return result;
} catch (Exception e) {
logger.error(appDeploymentId, "Error while deleting application deployment...", e);
@@ -2453,6 +2479,7 @@ public class AiravataServerHandler implements Airavata.Iface {
exception.setAiravataErrorType(AiravataErrorType.INTERNAL_ERROR);
exception.setMessage("Error while deleting application deployment. More info : " + e.getMessage());
registryClientPool.returnBrokenResource(regClient);
+ sharingClientPool.returnBrokenResource(sharingClient);
throw exception;
}
}
@@ -2467,19 +2494,7 @@ public class AiravataServerHandler implements Airavata.Iface {
@SecurityCheck
public List<ApplicationDeploymentDescription> getAllApplicationDeployments(AuthzToken authzToken, String gatewayId)
throws InvalidRequestException, AiravataClientException, AiravataSystemException, AuthorizationException, TException {
- RegistryService.Client regClient = registryClientPool.getResource();
- try {
- List<ApplicationDeploymentDescription> result = regClient.getAllApplicationDeployments(gatewayId);
- registryClientPool.returnResource(regClient);
- return result;
- } catch (Exception e) {
- logger.error("Error while retrieving application deployments...", e);
- AiravataSystemException exception = new AiravataSystemException();
- exception.setAiravataErrorType(AiravataErrorType.INTERNAL_ERROR);
- exception.setMessage("Error while retrieving application deployments. More info : " + e.getMessage());
- registryClientPool.returnBrokenResource(regClient);
- throw exception;
- }
+ return getAccessibleApplicationDeployments(authzToken, gatewayId, ResourcePermissionType.READ);
}
@@ -2549,6 +2564,7 @@ public class AiravataServerHandler implements Airavata.Iface {
AiravataClientException, AiravataSystemException, AuthorizationException, TException {
RegistryService.Client regClient = registryClientPool.getResource();
try {
+ // TODO: restrict to only application deployments that are accessible to user
List<String> result = regClient.getAppModuleDeployedResources(appModuleId);
registryClientPool.returnResource(regClient);
return result;
@@ -5179,15 +5195,7 @@ public class AiravataServerHandler implements Airavata.Iface {
final String userId = authzToken.getClaimsMap().get(Constants.USER_NAME) + "@" + domainId;
SharingRegistryService.Client sharingClient = sharingClientPool.getResource();
try {
- final boolean hasOwnerAccess = sharingClient.userHasAccess(domainId, userId, resourceId, domainId + ":" + ResourcePermissionType.OWNER);
- boolean hasAccess = false;
- if (permissionType.equals(ResourcePermissionType.WRITE)) {
- hasAccess = hasOwnerAccess || sharingClient.userHasAccess(domainId, userId, resourceId, domainId + ":" + ResourcePermissionType.WRITE);
- } else if (permissionType.equals(ResourcePermissionType.READ)) {
- hasAccess = hasOwnerAccess || sharingClient.userHasAccess(domainId, userId, resourceId, domainId + ":" + ResourcePermissionType.READ);
- } else if (permissionType.equals(ResourcePermissionType.OWNER)) {
- hasAccess = hasOwnerAccess;
- }
+ final boolean hasAccess = userHasAccessInternal(sharingClient, authzToken, resourceId, permissionType);
sharingClientPool.returnResource(sharingClient);
return hasAccess;
} catch (Exception e) {
@@ -5707,6 +5715,25 @@ public class AiravataServerHandler implements Airavata.Iface {
sharingClient.shareEntityWithGroups(domainId, entity.getEntityId(), Arrays.asList(gatewayGroups.getAdminsGroupId(), gatewayGroups.getReadOnlyAdminsGroupId()), domainId + ":READ", true);
}
+ private boolean userHasAccessInternal(SharingRegistryService.Client sharingClient, AuthzToken authzToken, String entityId, ResourcePermissionType permissionType) {
+ final String domainId = authzToken.getClaimsMap().get(Constants.GATEWAY_ID);
+ final String userId = authzToken.getClaimsMap().get(Constants.USER_NAME) + "@" + domainId;
+ try {
+ final boolean hasOwnerAccess = sharingClient.userHasAccess(domainId, userId, entityId, domainId + ":" + ResourcePermissionType.OWNER);
+ boolean hasAccess = false;
+ if (permissionType.equals(ResourcePermissionType.WRITE)) {
+ hasAccess = hasOwnerAccess || sharingClient.userHasAccess(domainId, userId, entityId, domainId + ":" + ResourcePermissionType.WRITE);
+ } else if (permissionType.equals(ResourcePermissionType.READ)) {
+ hasAccess = hasOwnerAccess || sharingClient.userHasAccess(domainId, userId, entityId, domainId + ":" + ResourcePermissionType.READ);
+ } else if (permissionType.equals(ResourcePermissionType.OWNER)) {
+ hasAccess = hasOwnerAccess;
+ }
+ return hasAccess;
+ } catch (Exception e) {
+ throw new RuntimeException("Unable to check if user has access", e);
+ }
+ }
+
private GatewayGroups retrieveGatewayGroups(RegistryService.Client regClient, String gatewayId) throws TException {
if (regClient.isGatewayGroupsExists(gatewayId)) {
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/KeyCloakSecurityManager.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/KeyCloakSecurityManager.java
index 08e4a6d..22bfe5f 100644
--- a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/KeyCloakSecurityManager.java
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/KeyCloakSecurityManager.java
@@ -87,6 +87,10 @@ public class KeyCloakSecurityManager implements AiravataSecurityManager {
"|/airavata/getGroupComputeResourcePreference|/airavata/getGroupComputeResourcePolicy" +
"|/airavata/getBatchQueueResourcePolicy|/airavata/getGroupComputeResourcePrefList" +
"|/airavata/getGroupBatchQueueResourcePolicyList|/airavata/getGroupComputeResourcePolicyList";
+ // These methods are protected by sharing registry authorization
+ private final static String APPLICATION_DEPLOYMENT_METHODS =
+ "/airavata/registerApplicationDeployment|/airavata/getApplicationDeployment|/airavata/updateApplicationDeployment" +
+ "|/airavata/deleteApplicationDeployment|/airavata/getAllApplicationDeployments|/airavata/getAccessibleApplicationDeployments";
// Misc. other methods needed for group based authorization
private final static String GROUP_BASED_AUTH_METHODS = "/airavata/getGatewayGroups";
@@ -159,7 +163,7 @@ public class KeyCloakSecurityManager implements AiravataSecurityManager {
"/airavata/getDataProduct|/airavata/registerReplicaLocation|/airavata/getParentDataProduct|/airavata/getChildDataProducts|" +
"/airavata/getAllAccessibleUsers|/airavata/getAllApplicationDeployments|/airavata/getAllAppModules|/airavata/getApplicationModule|" + USER_RESOURCE_PROFILE_USER_METHODS + "|" +
SHARING_RESOURCE_METHODS + "|" + SSH_ACCOUNT_PROVISIONER_METHODS + "|" + GROUP_RESOURCE_PROFILE_METHODS +
- "|" + GROUP_BASED_AUTH_METHODS);
+ "|" + APPLICATION_DEPLOYMENT_METHODS + "|" + GROUP_BASED_AUTH_METHODS);
initializeSecurityInfra();
}
diff --git a/airavata-services/services-security/src/test/java/org/apache/airavata/service/security/KeyCloakSecurityManagerTest.java b/airavata-services/services-security/src/test/java/org/apache/airavata/service/security/KeyCloakSecurityManagerTest.java
index d630161..bbb5d4d 100644
--- a/airavata-services/services-security/src/test/java/org/apache/airavata/service/security/KeyCloakSecurityManagerTest.java
+++ b/airavata-services/services-security/src/test/java/org/apache/airavata/service/security/KeyCloakSecurityManagerTest.java
@@ -90,50 +90,45 @@ public class KeyCloakSecurityManagerTest {
@Test
public void testDisallowedGatewayUserMethod(@Mocked URL anyURL, @Mocked HttpURLConnection openidConfigHttpURLConnection, @Mocked HttpURLConnection userinfoHttpURLConnection) throws AiravataSecurityException, ApplicationSettingsException, IOException, TException {
- createExpectationsForTokenVerification(openidConfigHttpURLConnection, userinfoHttpURLConnection);
- createExpectationsForAuthzCacheDisabled();
- createExpectationsForGatewayGroupsMembership(false, false);
- runIsUserAuthorizedTest("getAllGatewaySSHPubKeys", false);
+ runGatewayUserMethodTest(openidConfigHttpURLConnection, userinfoHttpURLConnection, "getAllGatewaySSHPubKeys", false);
}
@Test
public void testAllowedGatewayUserMethod(@Mocked URL anyURL, @Mocked HttpURLConnection openidConfigHttpURLConnection, @Mocked HttpURLConnection userinfoHttpURLConnection) throws AiravataSecurityException, ApplicationSettingsException, IOException, TException {
- createExpectationsForTokenVerification(openidConfigHttpURLConnection, userinfoHttpURLConnection);
- createExpectationsForAuthzCacheDisabled();
- createExpectationsForGatewayGroupsMembership(false, false);
-
- runIsUserAuthorizedTest("createProject", true);
+ runGatewayUserMethodTest(openidConfigHttpURLConnection, userinfoHttpURLConnection, "createProject", true);
}
@Test
public void testAllowedGatewayUserMethod2(@Mocked URL anyURL, @Mocked HttpURLConnection openidConfigHttpURLConnection, @Mocked HttpURLConnection userinfoHttpURLConnection) throws AiravataSecurityException, ApplicationSettingsException, IOException, TException {
- createExpectationsForTokenVerification(openidConfigHttpURLConnection, userinfoHttpURLConnection);
- createExpectationsForAuthzCacheDisabled();
- createExpectationsForGatewayGroupsMembership(false, false);
-
- runIsUserAuthorizedTest("userHasAccess", true);
+ runGatewayUserMethodTest(openidConfigHttpURLConnection, userinfoHttpURLConnection, "userHasAccess", true);
}
@Test
public void testAllowedGatewayUserMethod3(@Mocked URL anyURL, @Mocked HttpURLConnection openidConfigHttpURLConnection, @Mocked HttpURLConnection userinfoHttpURLConnection) throws AiravataSecurityException, ApplicationSettingsException, IOException, TException {
- createExpectationsForTokenVerification(openidConfigHttpURLConnection, userinfoHttpURLConnection);
- createExpectationsForAuthzCacheDisabled();
- createExpectationsForGatewayGroupsMembership(false, false);
-
- runIsUserAuthorizedTest("getGroupResourceList", true);
+ runGatewayUserMethodTest(openidConfigHttpURLConnection, userinfoHttpURLConnection, "getGroupResourceList", true);
}
@Test
public void testAllowedGatewayUserMethod4(@Mocked URL anyURL, @Mocked HttpURLConnection openidConfigHttpURLConnection, @Mocked HttpURLConnection userinfoHttpURLConnection) throws AiravataSecurityException, ApplicationSettingsException, IOException, TException {
+ runGatewayUserMethodTest(openidConfigHttpURLConnection, userinfoHttpURLConnection, "revokeSharingOfResourceFromGroups", true);
+ }
+
+ @Test
+ public void testAllowedGatewayUserMethod5(@Mocked URL anyURL, @Mocked HttpURLConnection openidConfigHttpURLConnection, @Mocked HttpURLConnection userinfoHttpURLConnection) throws AiravataSecurityException, ApplicationSettingsException, IOException, TException {
+
+ runGatewayUserMethodTest(openidConfigHttpURLConnection, userinfoHttpURLConnection, "getApplicationDeployment", true);
+ }
+
+ private void runGatewayUserMethodTest(@Mocked HttpURLConnection openidConfigHttpURLConnection, @Mocked HttpURLConnection userinfoHttpURLConnection, String methodName, boolean expectedAuthorization) throws IOException, ApplicationSettingsException, AiravataSecurityException, TException {
createExpectationsForTokenVerification(openidConfigHttpURLConnection, userinfoHttpURLConnection);
createExpectationsForAuthzCacheDisabled();
createExpectationsForGatewayGroupsMembership(false, false);
- runIsUserAuthorizedTest("revokeSharingOfResourceFromGroups", true);
+ runIsUserAuthorizedTest(methodName, expectedAuthorization);
}
@Test