You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by is...@apache.org on 2020/04/08 20:36:22 UTC
[airavata-custos] branch develop updated: Add admin user privilage
grant methods
This is an automated email from the ASF dual-hosted git repository.
isjarana pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
The following commit(s) were added to refs/heads/develop by this push:
new a1c4db6 Add admin user privilage grant methods
new cb3cbbc Merge pull request #38 from isururanawaka/microservices_based_impl
a1c4db6 is described below
commit a1c4db6cf88cf247d01c11049e3bc4722939bf12
Author: Isuru Ranawaka <ir...@gmail.com>
AuthorDate: Wed Apr 8 16:35:11 2020 -0400
Add admin user privilage grant methods
---
.../iam/admin/client/IamAdminServiceClient.java | 8 ++
.../apache/custos/iam/service/IamAdminService.java | 88 ++++++++++++++++-
.../org/apache/custos/iam/utils/IAMOperations.java | 2 +
.../custos/iam/validator/InputValidator.java | 5 +-
.../src/main/proto/IamAdminService.proto | 2 +
.../services/clients/keycloak/KeycloakClient.java | 65 ++++++++++++
.../src/main/resources/user-management-service.pb | Bin 115591 -> 117657 bytes
.../interceptors/UserAuthInterceptorImpl.java | 3 +-
.../management/service/UserManagementService.java | 110 ++++++++++++++++++++-
.../src/main/proto/UserManagementService.proto | 13 +++
10 files changed, 287 insertions(+), 9 deletions(-)
diff --git a/custos-core-services-client-stubs/iam-admin-core-service-client-stub/src/main/java/org/apache/custos/iam/admin/client/IamAdminServiceClient.java b/custos-core-services-client-stubs/iam-admin-core-service-client-stub/src/main/java/org/apache/custos/iam/admin/client/IamAdminServiceClient.java
index 3a590bb..bbf37d8 100644
--- a/custos-core-services-client-stubs/iam-admin-core-service-client-stub/src/main/java/org/apache/custos/iam/admin/client/IamAdminServiceClient.java
+++ b/custos-core-services-client-stubs/iam-admin-core-service-client-stub/src/main/java/org/apache/custos/iam/admin/client/IamAdminServiceClient.java
@@ -313,6 +313,14 @@ public class IamAdminServiceClient {
return iamAdminServiceBlockingStub.enableAgent(request);
}
+ public OperationStatus grantAdminPrivilege(UserSearchRequest request) {
+ return iamAdminServiceBlockingStub.grantAdminPrivilege(request);
+ }
+
+ public OperationStatus removeAdminPrivilege(UserSearchRequest request) {
+ return iamAdminServiceBlockingStub.removeAdminPrivilege(request);
+ }
+
public SetUpTenantResponse updateTenant(SetUpTenantRequest request) {
return iamAdminServiceBlockingStub.updateTenant(request);
}
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/service/IamAdminService.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/service/IamAdminService.java
index 06313d9..1eb4275 100644
--- a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/service/IamAdminService.java
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/service/IamAdminService.java
@@ -255,7 +255,7 @@ public class IamAdminService extends IamAdminServiceImplBase {
LOGGER.debug("Request received to enableUser for " + request.getTenantId());
boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
- request.getUser().getId(), request.getAccessToken());
+ request.getUser().getUsername(), request.getAccessToken());
if (!status) {
statusUpdater.updateStatus(IAMOperations.ENABLE_USER.name(),
@@ -317,7 +317,7 @@ public class IamAdminService extends IamAdminServiceImplBase {
LOGGER.debug("Request received to disable for " + request.getTenantId());
boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
- request.getUser().getId(), request.getAccessToken());
+ request.getUser().getUsername(), request.getAccessToken());
if (!status) {
@@ -1957,6 +1957,90 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
}
+
+ @Override
+ public void grantAdminPrivilege(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+ try {
+ LOGGER.debug("Request received to grantAdminPrivilege " + request.getTenantId());
+
+ boolean validationStatus = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+ request.getUser().getUsername(), request.getAccessToken());
+
+ if (validationStatus) {
+
+ boolean status = keycloakClient.grantAdminPrivilege(String.valueOf(request.getTenantId()), request.getUser().getUsername());
+
+ statusUpdater.updateStatus(IAMOperations.GRANT_ADMIN_PRIVILEGE.name(),
+ OperationStatus.FAILED,
+ request.getTenantId(), request.getPerformedBy());
+
+ org.apache.custos.iam.service.OperationStatus operationStatus =
+ org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+
+ responseObserver.onNext(operationStatus);
+ responseObserver.onCompleted();
+ } else {
+ String msg = " Not a valid user";
+ LOGGER.error(msg);
+ responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+ }
+
+ } catch (Exception ex) {
+ String msg = " Grant admin privilege " + request.getTenantId() + " " + ex.getMessage();
+ LOGGER.error(msg, ex);
+ statusUpdater.updateStatus(IAMOperations.GRANT_ADMIN_PRIVILEGE.name(),
+ OperationStatus.SUCCESS,
+ request.getTenantId(), request.getPerformedBy());
+ if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+ }
+
+
+ @Override
+ public void removeAdminPrivilege(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+ try {
+ LOGGER.debug("Request received to removeAdminPrivilege " + request.getTenantId());
+
+ boolean validationStatus = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+ request.getUser().getUsername(), request.getAccessToken());
+
+ if (validationStatus) {
+
+ boolean status = keycloakClient.removeAdminPrivilege(String.valueOf(request.getTenantId()), request.getUser().getUsername());
+
+ statusUpdater.updateStatus(IAMOperations.REMOVE_ADMIN_PRIVILEGE.name(),
+ OperationStatus.FAILED,
+ request.getTenantId(), request.getPerformedBy());
+
+ org.apache.custos.iam.service.OperationStatus operationStatus =
+ org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+
+ responseObserver.onNext(operationStatus);
+ responseObserver.onCompleted();
+ } else {
+ String msg = " Not a valid user";
+ LOGGER.error(msg);
+ responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+ }
+
+ } catch (Exception ex) {
+ String msg = " Remove admin privilege " + request.getTenantId() + " " + ex.getMessage();
+ LOGGER.error(msg, ex);
+ statusUpdater.updateStatus(IAMOperations.REMOVE_ADMIN_PRIVILEGE.name(),
+ OperationStatus.SUCCESS,
+ request.getTenantId(), request.getPerformedBy());
+ if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+ }
+
private OperationMetadata convertFromEntity(StatusEntity entity) {
return OperationMetadata.newBuilder()
.setEvent(entity.getEvent())
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java
index 29903c7..20390d2 100644
--- a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java
@@ -56,5 +56,7 @@ public enum IAMOperations {
DELETE_ROLE_FROM_AGENT,
ADD_AGENT_ATTRIBUTES,
DELETE_AGENT_ATTRIBUTES,
+ GRANT_ADMIN_PRIVILEGE,
+ REMOVE_ADMIN_PRIVILEGE
}
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/validator/InputValidator.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/validator/InputValidator.java
index 707f605..2058673 100644
--- a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/validator/InputValidator.java
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/validator/InputValidator.java
@@ -56,6 +56,7 @@ public class InputValidator implements Validator {
case "getUser":
case "deleteUser":
case "isUsernameAvailable":
+ case "grantAdminPrivilege":
validateUserAccess(obj);
break;
case "resetPassword":
@@ -117,7 +118,7 @@ public class InputValidator implements Validator {
case "deleteAgent":
case "disableAgent":
case "enableAgent":
- validateUserSearchRequest(obj);
+ validateUserSearchRequestForAgent(obj);
break;
case "registerAndEnableAgent":
validateRegisterAndEnableAgent(obj);
@@ -708,7 +709,7 @@ public class InputValidator implements Validator {
}
- private boolean validateUserSearchRequest(Object obj) {
+ private boolean validateUserSearchRequestForAgent(Object obj) {
if (obj instanceof UserSearchRequest) {
UserSearchRequest request = (UserSearchRequest) obj;
if (request.getTenantId() == 0) {
diff --git a/custos-core-services/iam-admin-core-service/src/main/proto/IamAdminService.proto b/custos-core-services/iam-admin-core-service/src/main/proto/IamAdminService.proto
index 4257cf5..d0474f3 100644
--- a/custos-core-services/iam-admin-core-service/src/main/proto/IamAdminService.proto
+++ b/custos-core-services/iam-admin-core-service/src/main/proto/IamAdminService.proto
@@ -394,6 +394,8 @@ service IamAdminService {
rpc getUser (UserSearchRequest) returns (UserRepresentation);
rpc findUsers (FindUsersRequest) returns (FindUsersResponse);
rpc resetPassword (ResetUserPassword) returns (OperationStatus);
+ rpc grantAdminPrivilege (UserSearchRequest) returns (OperationStatus);
+ rpc removeAdminPrivilege (UserSearchRequest) returns (OperationStatus);
rpc registerAndEnableUsers (RegisterUsersRequest) returns (RegisterUsersResponse);
rpc addUserAttributes (AddUserAttributesRequest) returns (OperationStatus);
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClient.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClient.java
index abdb172..8dfb3e0 100644
--- a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClient.java
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClient.java
@@ -246,6 +246,71 @@ public class KeycloakClient {
}
+ public boolean grantAdminPrivilege(String realmId, String username) {
+ Keycloak client = null;
+ try {
+ client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+ UserRepresentation representation = getUserByUsername(client, realmId, username);
+ if (representation != null) {
+
+ UserResource retrievedUser = client.realm(realmId).users().get(representation.getId());
+ RoleResource adminRoleResource = client.realm(realmId).roles().get("admin");
+ retrievedUser.roles().realmLevel().add(Arrays.asList(adminRoleResource.toRepresentation()));
+
+ String realmManagementClientId = getRealmManagementClientId(client, realmId);
+
+ retrievedUser.roles().clientLevel(realmManagementClientId).add(retrievedUser.roles().clientLevel(realmManagementClientId).listAvailable());
+ return true;
+
+ } else {
+ String msg = "Cannot find existing user with username " + username;
+ LOGGER.error(msg);
+ throw new RuntimeException(msg);
+ }
+ } catch (Exception ex) {
+ String msg = "Error granting admin privilege, reason: " + ex.getMessage();
+ LOGGER.error(msg, ex);
+ throw new RuntimeException(msg, ex);
+ } finally {
+ if (client != null) {
+ client.close();
+ }
+ }
+ }
+
+ public boolean removeAdminPrivilege(String realmId, String username) {
+ Keycloak client = null;
+ try {
+ client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+ UserRepresentation representation = getUserByUsername(client, realmId, username);
+ if (representation != null) {
+
+ UserResource retrievedUser = client.realm(realmId).users().get(representation.getId());
+ RoleResource adminRoleResource = client.realm(realmId).roles().get("admin");
+ retrievedUser.roles().realmLevel().remove(Arrays.asList(adminRoleResource.toRepresentation()));
+ String realmManagementClientId = getRealmManagementClientId(client, realmId);
+ List<RoleRepresentation> representations = retrievedUser.roles().clientLevel(realmManagementClientId).listEffective();
+
+ retrievedUser.roles().clientLevel(realmManagementClientId).remove(retrievedUser.roles().clientLevel(realmManagementClientId).listEffective());
+ return true;
+
+ } else {
+ String msg = "Cannot find existing user with username " + username;
+ LOGGER.error(msg);
+ throw new RuntimeException(msg);
+ }
+ } catch (Exception ex) {
+ String msg = "Error removing admin privilege, reason: " + ex.getMessage();
+ LOGGER.error(msg, ex);
+ throw new RuntimeException(msg, ex);
+ } finally {
+ if (client != null) {
+ client.close();
+ }
+ }
+ }
+
+
public KeycloakClientSecret configureClient(String realmId, String clientName, @NotNull String tenantURL, List<String> redirectUris) {
Keycloak client = null;
try {
diff --git a/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/user-management-service.pb b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/user-management-service.pb
index 70db73a..daaa3f1 100644
Binary files a/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/user-management-service.pb and b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/user-management-service.pb differ
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/UserAuthInterceptorImpl.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/UserAuthInterceptorImpl.java
index fb5a573..17d6121 100644
--- a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/UserAuthInterceptorImpl.java
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/UserAuthInterceptorImpl.java
@@ -178,7 +178,8 @@ public class UserAuthInterceptorImpl extends AuthInterceptor {
.setPerformedBy(claim.getPerformedBy())
.build();
- } else if (method.equals("deleteUser")) {
+ } else if (method.equals("deleteUser") || method.equals("grantAdminPrivileges") ||
+ method.equals("removeAdminPrivileges")) {
String token = getToken(headers);
AuthClaim claim = authorizeUsingUserToken(headers);
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/service/UserManagementService.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/service/UserManagementService.java
index c6f86c7..a999607 100644
--- a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/service/UserManagementService.java
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/service/UserManagementService.java
@@ -517,7 +517,7 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
LOGGER.error(msg);
if (ex.getMessage().contains("UNAUTHENTICATED")) {
responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
- } else if (ex.getMessage().contains("NOT_FOUND")) {
+ } else if (ex.getMessage().contains("NOT_FOUND")) {
responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
} else {
responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
@@ -1131,8 +1131,13 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
.setProfile(profile)
.build();
- userProfileClient.updateUserProfile(req);
+ UserProfile exsistingProfile = userProfileClient.getUser(req);
+ if (exsistingProfile == null || exsistingProfile.getUsername().equals("")) {
+ userProfileClient.createUserProfile(req);
+ } else {
+ userProfileClient.updateUserProfile(req);
+ }
}
CheckingResponse response = CheckingResponse.newBuilder().setIsExist(true).build();
@@ -1150,8 +1155,8 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
}
} catch (Exception ex) {
- String msg = "Error occurred while get all user profiles in tenant " + ex.getMessage();
- LOGGER.error(msg);
+ String msg = "Error occurred while linking user profile in tenant " + ex.getMessage();
+ LOGGER.error(msg, ex);
if (ex.getMessage().contains("UNAUTHENTICATED")) {
responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
} else {
@@ -1161,6 +1166,103 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
}
+ @Override
+ public void grantAdminPrivileges(UserSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+ try {
+
+ LOGGER.debug("Request received to grantAdminPrivileges " + request.getUser().getUsername() +
+ " at" + request.getTenantId());
+
+ iamAdminServiceClient.grantAdminPrivilege(request);
+
+ UserRepresentation representation = iamAdminServiceClient.getUser(request);
+
+ if (representation != null) {
+
+ UserProfile profile = convertToProfile(representation);
+
+ org.apache.custos.user.profile.service.UserProfileRequest profileRequest = org.apache.custos.user.profile.service.UserProfileRequest
+ .newBuilder()
+ .setTenantId(request.getTenantId())
+ .setPerformedBy(request.getPerformedBy())
+ .setProfile(profile)
+ .build();
+
+
+ UserProfile exProfile = userProfileClient.getUser(profileRequest);
+
+ if (exProfile == null || exProfile.getUsername().equals("")) {
+
+ userProfileClient.createUserProfile(profileRequest);
+ } else {
+ userProfileClient.updateUserProfile(profileRequest);
+
+ }
+
+ OperationStatus status = OperationStatus.newBuilder().setStatus(true).build();
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+ } else {
+ String msg = "User not found";
+ LOGGER.error(msg);
+ responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+ }
+
+ } catch (Exception ex) {
+ String msg = "Error occurred while get user profile audit trails " + ex.getMessage();
+ LOGGER.error(msg);
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void removeAdminPrivileges(UserSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+
+ try {
+ LOGGER.debug("Request received to removeAdminPrivileges " + request.getUser().getUsername() +
+ " at" + request.getTenantId());
+
+ iamAdminServiceClient.removeAdminPrivilege(request);
+
+ UserRepresentation representation = iamAdminServiceClient.getUser(request);
+
+ if (representation != null) {
+
+ UserProfile profile = convertToProfile(representation);
+
+ org.apache.custos.user.profile.service.UserProfileRequest profileRequest = org.apache.custos.user.profile.service.UserProfileRequest
+ .newBuilder()
+ .setTenantId(request.getTenantId())
+ .setPerformedBy(request.getPerformedBy())
+ .setProfile(profile)
+ .build();
+
+ UserProfile exProfile = userProfileClient.getUser(profileRequest);
+
+ if (exProfile == null || exProfile.getUsername().equals("")) {
+ userProfileClient.createUserProfile(profileRequest);
+ } else {
+ userProfileClient.updateUserProfile(profileRequest);
+ }
+
+ OperationStatus status = OperationStatus.newBuilder().setStatus(true).build();
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+ } else {
+ String msg = "User not found";
+ LOGGER.error(msg);
+ responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+ }
+
+ } catch (Exception ex) {
+ String msg = "Error occurred while get user profile audit trails " + ex.getMessage();
+ LOGGER.error(msg);
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+ }
+ }
+
private UserProfile convertToProfile(UserRepresentation representation) {
UserProfile.Builder profileBuilder = UserProfile.newBuilder();
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService.proto b/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService.proto
index bfa8eea..966c440 100644
--- a/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService.proto
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService.proto
@@ -120,6 +120,19 @@ service UserManagementService {
};
}
+ rpc grantAdminPrivileges (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+ option (google.api.http) = {
+ post: "/user-management/v1.0.0/user/admin"
+ body: "user"
+ };
+ }
+
+ rpc removeAdminPrivileges (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+ option (google.api.http) = {
+ delete: "/user-management/v1.0.0/user/admin"
+ body: "user"
+ };
+ }
rpc addRolesToUsers (org.apache.custos.iam.service.AddUserRolesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
option (google.api.http) = {