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