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 <[email protected]>
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

Reply via email to