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/02/24 22:48:53 UTC
[airavata-custos] branch develop updated: Improve user management
APIs
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 b1bbb6a Improve user management APIs
new 27af9b9 Merge pull request #17 from isururanawaka/microservices_based_impl
b1bbb6a is described below
commit b1bbb6aa62af2be3a81eca4d09740b7d9b62770f
Author: Isuru Ranawaka <ir...@gmail.com>
AuthorDate: Mon Feb 24 17:47:37 2020 -0500
Improve user management APIs
---
.../client/IdentityManagementClient.java | 12 +
.../store/client/CredentialStoreServiceClient.java | 34 +-
.../iam/admin/client/IamAdminServiceClient.java | 64 +--
.../store/credential/CredentialManager.java | 31 ++
.../custos/credential/store/model/Credential.java | 8 +
.../store/service/CredentialStoreService.java | 135 ++++++
.../credential/store/validator/InputValidator.java | 24 +-
.../src/main/proto/CredentialStoreService.proto | 14 +
.../apache/custos/iam/service/IamAdminService.java | 492 ++++++++++++++++-----
.../org/apache/custos/iam/utils/IAMOperations.java | 8 +-
.../custos/iam/validator/InputValidator.java | 227 ++++++----
.../src/main/proto/IamAdminService.proto | 189 ++++++--
.../custos/identity/service/IdentityService.java | 22 +-
.../src/main/proto/IdentityService.proto | 2 +
.../user/profile/mapper/UserProfileMapper.java | 6 +-
.../user/profile/validators/InputValidator.java | 2 +-
.../src/main/proto/UserProfileService.proto | 16 +-
.../services/clients/keycloak/KeycloakClient.java | 265 +++++++----
.../clients/keycloak/UnauthorizedException.java | 21 +-
.../clients/keycloak/auth/KeycloakAuthClient.java | 14 +-
.../commons/interceptors/AuthInterceptor.java | 47 +-
.../services/commons/model/AuthClaim.java | 10 +
.../main/resources/identity-management-service.pb | Bin 85171 -> 93280 bytes
.../identity-management-service.pb | Bin 85171 -> 0 bytes
.../IdentityManagementServiceInitializer.java | 6 +-
.../interceptors/AuthInterceptorImpl.java | 25 +-
.../management/interceptors/InputValidator.java | 15 +
.../service/IdentityManagementService.java | 19 +-
.../src/main/proto/IdentityManagementService.proto | 15 +
.../main/resources/tenant-management-service.pb | Bin 101057 -> 119882 bytes
.../interceptors/AuthInterceptorImpl.java | 24 +
.../management/interceptors/InputValidator.java | 36 +-
.../service/TenantManagementService.java | 39 +-
.../src/main/proto/TenantManagementService.proto | 15 +-
.../src/main/resources/user-management-service.pb | Bin 95322 -> 100895 bytes
.../UserManagementServiceInitializer.java | 8 +-
...torImpl.java => ClientAuthInterceptorImpl.java} | 147 +++---
.../interceptors/UserAuthInterceptorImpl.java | 201 +++++++++
.../management/service/UserManagementService.java | 398 ++++++++---------
.../src/main/proto/UserManagementService.proto | 69 ++-
pom.xml | 5 +
41 files changed, 1878 insertions(+), 787 deletions(-)
diff --git a/custos-clients/identity-management-client/src/main/java/org/apache/custos/identity/management/client/IdentityManagementClient.java b/custos-clients/identity-management-client/src/main/java/org/apache/custos/identity/management/client/IdentityManagementClient.java
index d38a666..6227974 100644
--- a/custos-clients/identity-management-client/src/main/java/org/apache/custos/identity/management/client/IdentityManagementClient.java
+++ b/custos-clients/identity-management-client/src/main/java/org/apache/custos/identity/management/client/IdentityManagementClient.java
@@ -24,8 +24,10 @@ import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyChannelBuilder;
import io.grpc.stub.MetadataUtils;
import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.credential.store.service.Credentials;
import org.apache.custos.identity.management.service.AuthorizationRequest;
import org.apache.custos.identity.management.service.AuthorizationResponse;
+import org.apache.custos.identity.management.service.GetCredentialsRequest;
import org.apache.custos.identity.management.service.IdentityManagementServiceGrpc;
import org.apache.custos.identity.service.GetTokenRequest;
import org.apache.custos.identity.service.TokenResponse;
@@ -107,5 +109,15 @@ public class IdentityManagementClient {
return null;
}
+ /**
+ * Returns Custos Id, Custos client secret, IAM Id, IAM Client Secret, CILogon Id, CILogon Client Secret
+ *
+ * @return
+ */
+ public Credentials getCredentials(String clientId) {
+ GetCredentialsRequest request = GetCredentialsRequest.newBuilder().setClientId(clientId).build();
+ return blockingStub.getCredentials(request);
+ }
+
}
diff --git a/custos-core-services-client-stubs/credential-store-core-service-client-stubs/src/main/java/org/apache/custos/credential/store/client/CredentialStoreServiceClient.java b/custos-core-services-client-stubs/credential-store-core-service-client-stubs/src/main/java/org/apache/custos/credential/store/client/CredentialStoreServiceClient.java
index f47367f..327be9b 100644
--- a/custos-core-services-client-stubs/credential-store-core-service-client-stubs/src/main/java/org/apache/custos/credential/store/client/CredentialStoreServiceClient.java
+++ b/custos-core-services-client-stubs/credential-store-core-service-client-stubs/src/main/java/org/apache/custos/credential/store/client/CredentialStoreServiceClient.java
@@ -80,27 +80,24 @@ public class CredentialStoreServiceClient {
public void getOperationsMetadataAsync(GetOperationsMetadataRequest request, final ServiceCallback callback) {
StreamObserver observer = getObserver(callback, "get operations metadata");
- credentialStoreServiceStub.getOperationMetadata(request,observer);
+ credentialStoreServiceStub.getOperationMetadata(request, observer);
}
- public void getNewCustosCredentialsAsync(GetNewCustosCredentialRequest request, final ServiceCallback callback) {
+ public void getNewCustosCredentialsAsync(GetNewCustosCredentialRequest request, final ServiceCallback callback) {
StreamObserver observer = getObserver(callback, "get new custos credentials metadata");
- credentialStoreServiceStub.getNewCustosCredential(request,observer);
+ credentialStoreServiceStub.getNewCustosCredential(request, observer);
}
- public void getOwnerIdFormToken( TokenRequest request, final ServiceCallback callback) {
+ public void getOwnerIdFormToken(TokenRequest request, final ServiceCallback callback) {
StreamObserver observer = getObserver(callback, "get new custos credentials metadata");
- credentialStoreServiceStub.getOwnerIdFromToken(request,observer);
+ credentialStoreServiceStub.getOwnerIdFromToken(request, observer);
}
-
-
-
public OperationStatus putCredential(CredentialMetadata request) {
return credentialStoreServiceBlockingStub.putCredential(request);
@@ -127,24 +124,33 @@ public class CredentialStoreServiceClient {
}
public CredentialMetadata getNewCustosCredentials(GetNewCustosCredentialRequest request) {
- return credentialStoreServiceBlockingStub.getNewCustosCredential(request);
+ return credentialStoreServiceBlockingStub.getNewCustosCredential(request);
}
- public GetOwnerIdResponse getOwnerIdFormToken( TokenRequest request) {
- return credentialStoreServiceBlockingStub.getOwnerIdFromToken(request);
+ public GetOwnerIdResponse getOwnerIdFormToken(TokenRequest request) {
+ return credentialStoreServiceBlockingStub.getOwnerIdFromToken(request);
}
- public CredentialMetadata getCustosCredentialFromToken( TokenRequest request) {
+ public CredentialMetadata getCustosCredentialFromToken(TokenRequest request) {
return credentialStoreServiceBlockingStub.getCustosCredentialFromToken(request);
}
- public CredentialMetadata getCustosCredentialFromClientId (GetCredentialRequest request) {
+ public CredentialMetadata getCustosCredentialFromClientId(GetCredentialRequest request) {
return credentialStoreServiceBlockingStub.getCustosCredentialFromClientId(request);
}
- public GetAllCredentialsResponse getAllCredentialFromToken (TokenRequest request) {
+
+ public GetAllCredentialsResponse getAllCredentialFromToken(TokenRequest request) {
return credentialStoreServiceBlockingStub.getAllCredentialsFromToken(request);
}
+ public Credentials getBasicCredentials(TokenRequest request) {
+ return credentialStoreServiceBlockingStub.getBasicCredentials(request);
+ }
+
+ public GetAllCredentialsResponse getAllCredentialsFromJWTToken(TokenRequest request) {
+ return credentialStoreServiceBlockingStub.getAllCredentialsFromJWTToken(request);
+ }
+
private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
final Object[] response = new Object[1];
StreamObserver observer = new StreamObserver() {
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 ad2cecb..0383b55 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
@@ -65,22 +65,19 @@ public class IamAdminServiceClient {
}
- public void isUsernameAvailableAsync(IsUsernameAvailableRequest request, final ServiceCallback callback) {
+ public void isUsernameAvailableAsync(UserSearchRequest request, final ServiceCallback callback) {
StreamObserver observer = this.getObserver(callback, "isUsernameAvailable task failed");
iamAdminServiceStub.isUsernameAvailable(request, observer);
}
- public void isUserEnabledAsync(UserAccessInfo request, final ServiceCallback callback) {
+ public void isUserEnabledAsync(UserSearchRequest request, final ServiceCallback callback) {
StreamObserver observer = this.getObserver(callback, "isUserEnabled task failed");
iamAdminServiceStub.isUserEnabled(request, observer);
}
- public void addRoleToUserAsync(RoleOperationsUserRequest request, final ServiceCallback callback) {
- StreamObserver observer = this.getObserver(callback, "addRoleToUser task failed");
- iamAdminServiceStub.addRoleToUser(request, observer);
- }
+
public void registerUserAsync(RegisterUserRequest request, final ServiceCallback callback) {
@@ -89,27 +86,27 @@ public class IamAdminServiceClient {
}
- public void enableUserAsync(UserAccessInfo request, final ServiceCallback callback) {
+ public void enableUserAsync(UserSearchRequest request, final ServiceCallback callback) {
StreamObserver observer = this.getObserver(callback, "enableUser task failed");
iamAdminServiceStub.enableUser(request, observer);
}
- public void isUserExistAsync(UserAccessInfo request, final ServiceCallback callback) {
+ public void isUserExistAsync(UserSearchRequest request, final ServiceCallback callback) {
StreamObserver observer = this.getObserver(callback, "isUserExist task failed");
iamAdminServiceStub.isUserExist(request, observer);
}
- public void getUserAsync(UserAccessInfo request, final ServiceCallback callback) {
+ public void getUserAsync(UserSearchRequest request, final ServiceCallback callback) {
StreamObserver observer = this.getObserver(callback, "getUser task failed");
iamAdminServiceStub.getUser(request, observer);
}
- public void getUsersAsync(GetUsersRequest request, final ServiceCallback callback) {
+ public void getUsersAsync(FindUsersRequest request, final ServiceCallback callback) {
StreamObserver observer = this.getObserver(callback, "getUsers task failed");
- iamAdminServiceStub.getUsers(request, observer);
+ iamAdminServiceStub.findUsers(request, observer);
}
@@ -130,15 +127,15 @@ public class IamAdminServiceClient {
iamAdminServiceStub.updateUserProfile(request, observer);
}
- public void deleteUserAsync(UserAccessInfo request, final ServiceCallback callback) {
+ public void deleteUserAsync(UserSearchRequest request, final ServiceCallback callback) {
StreamObserver observer = this.getObserver(callback, "deleteUser task failed");
iamAdminServiceStub.deleteUser(request, observer);
}
- public void deleteRoleFromUserAsync(RoleOperationsUserRequest request, final ServiceCallback callback) {
+ public void deleteRoleFromUserAsync(DeleteUserRolesRequest request, final ServiceCallback callback) {
StreamObserver observer = this.getObserver(callback, "deleteRoleFromUser task failed");
- iamAdminServiceStub.deleteRoleFromUser(request, observer);
+ iamAdminServiceStub.deleteRolesFromUser(request, observer);
}
public void getOperationsMetadataAsync(GetOperationsMetadataRequest request, final ServiceCallback callback) {
@@ -151,18 +148,18 @@ public class IamAdminServiceClient {
}
- public CheckingResponse isUsernameAvailable(IsUsernameAvailableRequest request) {
+ public CheckingResponse isUsernameAvailable(UserSearchRequest request) {
return iamAdminServiceBlockingStub.isUsernameAvailable(request);
}
- public CheckingResponse isUserEnabled(UserAccessInfo request) {
+ public CheckingResponse isUserEnabled(UserSearchRequest request) {
return iamAdminServiceBlockingStub.isUserEnabled(request);
}
- public CheckingResponse addRoleToUser(RoleOperationsUserRequest request) {
- return iamAdminServiceBlockingStub.addRoleToUser(request);
+ public OperationStatus addRolesToUsers(AddUserRolesRequest request) {
+ return iamAdminServiceBlockingStub.addRolesToUsers(request);
}
@@ -172,26 +169,26 @@ public class IamAdminServiceClient {
}
- public User enableUser(UserAccessInfo request) {
+ public UserRepresentation enableUser(UserSearchRequest request) {
return iamAdminServiceBlockingStub.enableUser(request);
}
- public CheckingResponse isUserExist(UserAccessInfo request) {
+ public CheckingResponse isUserExist(UserSearchRequest request) {
return iamAdminServiceBlockingStub.isUserExist(request);
}
- public User getUser(UserAccessInfo request) {
+ public UserRepresentation getUser(UserSearchRequest request) {
return iamAdminServiceBlockingStub.getUser(request);
}
- public GetUsersResponse getUsers(GetUsersRequest request) {
- return iamAdminServiceBlockingStub.getUsers(request);
+ public FindUsersResponse getUsers(FindUsersRequest request) {
+ return iamAdminServiceBlockingStub.findUsers(request);
}
@@ -202,22 +199,19 @@ public class IamAdminServiceClient {
}
- public GetUsersResponse findUsers(FindUsersRequest request) {
- return iamAdminServiceBlockingStub.findUsers(request);
- }
public CheckingResponse updateUserProfile(UpdateUserProfileRequest request) {
return iamAdminServiceBlockingStub.updateUserProfile(request);
}
- public CheckingResponse deleteUser(UserAccessInfo request) {
+ public CheckingResponse deleteUser(UserSearchRequest request) {
return iamAdminServiceBlockingStub.deleteUser(request);
}
- public CheckingResponse deleteRoleFromUser(RoleOperationsUserRequest request) {
- return iamAdminServiceBlockingStub.deleteRoleFromUser(request);
+ public CheckingResponse deleteUserRoles(DeleteUserRolesRequest request) {
+ return iamAdminServiceBlockingStub.deleteRolesFromUser(request);
}
public GetOperationsMetadataResponse getOperationsMetadata(GetOperationsMetadataRequest request) {
@@ -233,6 +227,18 @@ public class IamAdminServiceClient {
return iamAdminServiceBlockingStub.registerAndEnableUsers(registerUsersRequest);
}
+ public AllRoles addRolesToTenant(AddRolesRequest rolesRequest) {
+ return iamAdminServiceBlockingStub.addRolesToTenant(rolesRequest);
+ }
+
+ public OperationStatus addProtocolMapper (AddProtocolMapperRequest addProtocolMapper) {
+ return iamAdminServiceBlockingStub.addProtocolMapper(addProtocolMapper);
+ }
+
+ public OperationStatus addUserAttributes (AddUserAttributesRequest addUserAttributesRequest) {
+ return iamAdminServiceBlockingStub.addUserAttributes(addUserAttributesRequest);
+ }
+
public String getIamServerURL() {
return iamServerURL;
}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/credential/CredentialManager.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/credential/CredentialManager.java
index d88882e..6e46e9a 100644
--- a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/credential/CredentialManager.java
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/credential/CredentialManager.java
@@ -19,6 +19,8 @@
package org.apache.custos.credential.store.credential;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.custos.credential.store.exceptions.CredentialGenerationException;
import org.apache.custos.credential.store.model.Credential;
import org.apache.custos.credential.store.model.CredentialTypes;
@@ -31,6 +33,7 @@ import org.springframework.stereotype.Component;
import java.security.SecureRandom;
import java.util.Base64;
+import java.util.Map;
import java.util.Random;
/**
@@ -108,6 +111,34 @@ public class CredentialManager {
}
+ public Credential decodeJWTToken(String token) {
+ try {
+ java.util.Base64.Decoder decoder = java.util.Base64.getUrlDecoder();
+ String[] parts = token.split("\\."); // split out the "parts" (header, payload and signature)
+
+ String headerJson = new String(decoder.decode(parts[0]));
+ String payloadJson = new String(decoder.decode(parts[1]));
+ String signatureJson = new String(decoder.decode(parts[2]));
+
+ ObjectMapper mapper = new ObjectMapper();
+ Map<String, Object> jsonMap = mapper.readValue(payloadJson, new TypeReference<Map<String, Object>>() {
+ });
+ LOGGER.info("Decoded clientId" + jsonMap.get("azp").toString());
+
+ Credential credential = new Credential();
+ credential.setId(jsonMap.get("azp").toString());
+ credential.setEmail(jsonMap.get("email").toString());
+
+ return credential;
+ } catch (Exception ex) {
+ throw new CredentialGenerationException
+ ("Error occurred while decoding token ", ex);
+
+ }
+
+ }
+
+
private String generateRandomClientId(int length) {
StringBuilder returnValue = new StringBuilder(length);
for (int i = 0; i < length; i++) {
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/Credential.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/Credential.java
index 1215865..11b5839 100644
--- a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/Credential.java
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/Credential.java
@@ -26,6 +26,7 @@ public class Credential {
private String id;
private String secret;
+ private String email;
public Credential(String id, String secret) {
this.id = id;
@@ -51,4 +52,11 @@ public class Credential {
this.secret = secret;
}
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/service/CredentialStoreService.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/service/CredentialStoreService.java
index b53c61e..dc5c4ac 100644
--- a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/service/CredentialStoreService.java
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/service/CredentialStoreService.java
@@ -504,6 +504,141 @@ public class CredentialStoreService extends CredentialStoreServiceImplBase {
}
}
+
+ @Override
+ public void getBasicCredentials(TokenRequest request, StreamObserver<Credentials> responseObserver) {
+ try {
+
+ String token = request.getToken();
+ Credential credential = credentialManager.decodeToken(token);
+
+ if (credential == null || credential.getId() == null) {
+ LOGGER.error("Invalid access token");
+ responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+ return;
+ }
+
+ CredentialEntity entity = repository.findByClientId(credential.getId());
+
+ if (entity == null) {
+ LOGGER.error("User not found");
+ responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+ return;
+ }
+ String subPath = BASE_PATH + entity.getOwnerId();
+ List<String> paths = vaultTemplate.list(subPath);
+
+
+ Credentials.Builder credentialsBuilder = Credentials.newBuilder();
+
+
+ if (entity == null) {
+ LOGGER.error("User not found");
+ responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+ return;
+ }
+
+
+ if (paths != null && !paths.isEmpty()) {
+ for (String key : paths) {
+ String path = subPath + "/" + key;
+ VaultResponseSupport<Credential> crRe = vaultTemplate.read(path, Credential.class);
+ if (key.equals(Type.CUSTOS)) {
+
+ credentialsBuilder.setCustosClientId(crRe.getData().getId())
+ .setCustosClientSecret(crRe.getData().getSecret())
+ .setCustosClientIdIssuedAt(entity.getIssuedAt().getTime())
+ .setCustosClientSecretExpiredAt(entity.getClientSecretExpiredAt());
+
+ } else if (key.equals(Type.IAM)) {
+ credentialsBuilder.setIamClientId(crRe.getData().getId())
+ .setIamClientSecret(crRe.getData().getSecret());
+
+
+ } else if (key.equals(Type.CILOGON)) {
+
+ credentialsBuilder.setCiLogonClientId(crRe.getData().getId())
+ .setCiLogonClientSecret(crRe.getData().getSecret());
+
+ }
+
+ }
+ }
+
+ Credentials credentials = credentialsBuilder.build();
+
+ responseObserver.onNext(credentials);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = " Operation failed failed " + ex;
+ LOGGER.error(msg);
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+
+ @Override
+ public void getAllCredentialsFromJWTToken(TokenRequest request, StreamObserver<GetAllCredentialsResponse> responseObserver) {
+ try {
+ String token = request.getToken();
+
+ LOGGER.info("TOken "+ token );
+ Credential credential = credentialManager.decodeJWTToken(token);
+
+ if (credential == null || credential.getId() == null) {
+ LOGGER.error("Invalid access token");
+ responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+ return;
+ }
+
+ CredentialEntity entity = repository.findByClientId(credential.getId());
+
+ if (entity == null) {
+ LOGGER.error("User not found");
+ responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+ return;
+ }
+
+ String subPath = BASE_PATH + entity.getOwnerId();
+ List<String> paths = vaultTemplate.list(subPath);
+
+
+ List<CredentialMetadata> credentialMetadata = new ArrayList<>();
+
+ if (paths != null && !paths.isEmpty()) {
+ for (String key : paths) {
+ String path = subPath + "/" + key;
+ VaultResponseSupport<Credential> crRe = vaultTemplate.read(path, Credential.class);
+ CredentialMetadata metadata = convertToCredentialMetadata(crRe.getData(), entity.getOwnerId(), key);
+
+
+ if (key.equals(Type.CUSTOS)) {
+ metadata = metadata.toBuilder()
+ .setClientIdIssuedAt(entity.getIssuedAt().getTime())
+ .setClientSecretExpiredAt(entity.getClientSecretExpiredAt())
+ .build();
+ }
+ credentialMetadata.add(metadata);
+ }
+ }
+ GetAllCredentialsResponse response = GetAllCredentialsResponse.newBuilder()
+ .addAllSecretList(credentialMetadata)
+ .setRequestedUserEmail(credential.getEmail())
+ .build();
+
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = " Operation failed " + ex;
+ LOGGER.error(msg);
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
private OperationMetadata convertFromEntity(StatusEntity entity) {
return OperationMetadata.newBuilder()
.setEvent(entity.getEvent())
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/validator/InputValidator.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/validator/InputValidator.java
index eef1dbc..d26f365 100644
--- a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/validator/InputValidator.java
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/validator/InputValidator.java
@@ -36,7 +36,7 @@ public class InputValidator implements Validator {
* @param obj
* @return
*/
- public void validate(String methodName, Object obj) {
+ public void validate(String methodName, Object obj) {
switch (methodName) {
case "putCredential":
@@ -56,16 +56,18 @@ public class InputValidator implements Validator {
break;
case "getOwnerIdFromToken":
case "getCredentialFromToken":
+ case "getAllCredentialsFromJWTToken":
+ case "getAllCredentialsFromToken":
validateTokenRequest(obj, methodName);
break;
case "getCredentialFromClientId":
- validateGetCredentialFromClientId(obj,methodName);
+ validateGetCredentialFromClientId(obj, methodName);
break;
default:
}
}
- private boolean validatePutCredential(Object obj, String method) {
+ private boolean validatePutCredential(Object obj, String method) {
if (obj instanceof CredentialMetadata) {
CredentialMetadata metadata = (CredentialMetadata) obj;
@@ -91,7 +93,7 @@ public class InputValidator implements Validator {
return true;
}
- private boolean validateDeleteCredential(Object obj, String method) {
+ private boolean validateDeleteCredential(Object obj, String method) {
if (obj instanceof DeleteCredentialRequest) {
DeleteCredentialRequest metadata = (DeleteCredentialRequest) obj;
if (metadata.getOwnerId() == 0) {
@@ -110,7 +112,7 @@ public class InputValidator implements Validator {
return true;
}
- private boolean validateGetCredential(Object obj, String method) {
+ private boolean validateGetCredential(Object obj, String method) {
if (obj instanceof GetCredentialRequest) {
GetCredentialRequest metadata = (GetCredentialRequest) obj;
if (metadata.getOwnerId() == 0) {
@@ -128,7 +130,7 @@ public class InputValidator implements Validator {
}
- private boolean validateGetNewCustosCredential (Object obj, String method) {
+ private boolean validateGetNewCustosCredential(Object obj, String method) {
if (obj instanceof GetNewCustosCredentialRequest) {
GetNewCustosCredentialRequest metadata = (GetNewCustosCredentialRequest) obj;
if (metadata.getOwnerId() == 0) {
@@ -142,11 +144,11 @@ public class InputValidator implements Validator {
}
- private boolean validateTokenRequest(Object obj, String method) {
+ private boolean validateTokenRequest(Object obj, String method) {
if (obj instanceof TokenRequest) {
TokenRequest metadata = (TokenRequest) obj;
- if (metadata.getToken() == null || metadata.getToken().trim().equals("") ){
- throw new MissingParameterException("OwnerId cannot be null at " + method, null);
+ if (metadata.getToken() == null || metadata.getToken().trim().equals("")) {
+ throw new MissingParameterException("Token cannot be null at " + method, null);
}
} else {
@@ -156,7 +158,7 @@ public class InputValidator implements Validator {
}
- private boolean validateGetAllCredentials(Object obj, String method) {
+ private boolean validateGetAllCredentials(Object obj, String method) {
if (obj instanceof GetAllCredentialsRequest) {
GetAllCredentialsRequest request = (GetAllCredentialsRequest) obj;
if (request.getOwnerId() == 0) {
@@ -170,7 +172,7 @@ public class InputValidator implements Validator {
}
- private boolean validateGetCredentialFromClientId (Object obj, String method) {
+ private boolean validateGetCredentialFromClientId(Object obj, String method) {
if (obj instanceof GetCredentialRequest) {
GetCredentialRequest request = (GetCredentialRequest) obj;
if (request.getId() == null || request.getId().equals("")) {
diff --git a/custos-core-services/credential-store-core-service/src/main/proto/CredentialStoreService.proto b/custos-core-services/credential-store-core-service/src/main/proto/CredentialStoreService.proto
index 30c45f6..814a524 100644
--- a/custos-core-services/credential-store-core-service/src/main/proto/CredentialStoreService.proto
+++ b/custos-core-services/credential-store-core-service/src/main/proto/CredentialStoreService.proto
@@ -50,6 +50,7 @@ message GetAllCredentialsRequest {
message GetAllCredentialsResponse {
repeated CredentialMetadata secretList = 1;
+ string requestedUserEmail = 2;
}
message OperationStatus {
@@ -93,6 +94,17 @@ message GetOwnerIdResponse {
int64 ownerId = 2;
}
+message Credentials {
+ string iam_client_id = 1;
+ string iam_client_secret = 2;
+ string ci_logon_client_id = 3;
+ string ci_logon_client_secret = 4;
+ string custos_client_id = 5;
+ string custos_client_secret = 6;
+ double custos_client_id_issued_at = 7;
+ double custos_client_secret_expired_at = 8;
+}
+
service CredentialStoreService {
rpc putCredential (CredentialMetadata) returns (OperationStatus);
rpc deleteCredential (DeleteCredentialRequest) returns (OperationStatus);
@@ -104,4 +116,6 @@ service CredentialStoreService {
rpc getCustosCredentialFromToken (TokenRequest) returns (CredentialMetadata);
rpc getCustosCredentialFromClientId (GetCredentialRequest) returns (CredentialMetadata);
rpc getAllCredentialsFromToken (TokenRequest) returns (GetAllCredentialsResponse);
+ rpc getAllCredentialsFromJWTToken (TokenRequest) returns (GetAllCredentialsResponse);
+ rpc getBasicCredentials(TokenRequest) returns (Credentials);
}
\ No newline at end of file
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 9cb4733..1494dd9 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
@@ -26,9 +26,11 @@ import org.apache.custos.core.services.commons.persistance.model.OperationStatus
import org.apache.custos.core.services.commons.persistance.model.StatusEntity;
import org.apache.custos.federated.services.clients.keycloak.KeycloakClient;
import org.apache.custos.federated.services.clients.keycloak.KeycloakClientSecret;
+import org.apache.custos.federated.services.clients.keycloak.UnauthorizedException;
import org.apache.custos.iam.service.IamAdminServiceGrpc.IamAdminServiceImplBase;
import org.apache.custos.iam.utils.IAMOperations;
import org.apache.custos.iam.utils.Status;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.lognet.springboot.grpc.GRpcService;
import org.slf4j.Logger;
@@ -36,7 +38,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
@GRpcService
public class IamAdminService extends IamAdminServiceImplBase {
@@ -111,12 +115,12 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
@Override
- public void isUsernameAvailable(IsUsernameAvailableRequest request, StreamObserver<CheckingResponse> responseObserver) {
+ public void isUsernameAvailable(UserSearchRequest request, StreamObserver<CheckingResponse> responseObserver) {
try {
LOGGER.debug("Request received to isUsernameAvailable at " + request.getTenantId());
boolean isAvailable = keycloakClient.isUsernameAvailable(String.valueOf(request.getTenantId()),
- request.getUserName(),
+ request.getUser().getUsername(),
request.getAccessToken());
CheckingResponse response = CheckingResponse.newBuilder().setIsExist(isAvailable).build();
@@ -132,13 +136,13 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
@Override
- public void isUserEnabled(UserAccessInfo request, StreamObserver<CheckingResponse> responseObserver) {
+ public void isUserEnabled(UserSearchRequest request, StreamObserver<CheckingResponse> responseObserver) {
try {
LOGGER.debug("Request received to isUserEnabled at " + request.getTenantId());
boolean isAvailable = keycloakClient.isUserAccountEnabled(String.valueOf(request.getTenantId()),
request.getAccessToken(),
- request.getUsername());
+ request.getUser().getUsername());
CheckingResponse response = CheckingResponse.newBuilder().setIsExist(isAvailable).build();
responseObserver.onNext(response);
@@ -151,43 +155,6 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
}
- @Override
- public void addRoleToUser(RoleOperationsUserRequest request, StreamObserver<CheckingResponse> responseObserver) {
-
- String userId = request.getAdminUsername() + "@" + request.getTenantId();
-
- try {
- LOGGER.debug("Request received to addRoleToUser at " + request.getTenantId());
-
- boolean isAdded = keycloakClient.addRoleToUser(request.getAdminUsername(),
- request.getPassword(),
- String.valueOf(request.getTenantId()),
- request.getUsername(),
- request.getRole());
-
- CheckingResponse response = CheckingResponse.newBuilder().setIsExist(isAdded).build();
-
-
- statusUpdater.updateStatus(IAMOperations.ADD_ROLE_TO_USER.name(),
- OperationStatus.SUCCESS,
- request.getTenantId(),
- userId);
-
- responseObserver.onNext(response);
- responseObserver.onCompleted();
-
- } catch (Exception ex) {
- String msg = "Error occurred during addRoleToUser" + ex;
- LOGGER.error(msg, ex);
-
- statusUpdater.updateStatus(IAMOperations.ADD_ROLE_TO_USER.name(),
- OperationStatus.FAILED,
- request.getTenantId(),
- userId);
-
- responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
- }
- }
@Override
public void registerUser(RegisterUserRequest request, StreamObserver<RegisterUserResponse> responseObserver) {
@@ -217,6 +184,13 @@ public class IamAdminService extends IamAdminServiceImplBase {
responseObserver.onNext(registerUserResponse);
responseObserver.onCompleted();
+ } catch (UnauthorizedException ex) {
+ String msg = "Error occurred during registerUser" + ex;
+ statusUpdater.updateStatus(IAMOperations.REGISTER_USER.name(),
+ OperationStatus.FAILED,
+ request.getTenantId(),
+ String.valueOf(request.getTenantId()));
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
} catch (Exception ex) {
String msg = "Error occurred during registerUser" + ex;
LOGGER.error(msg, ex);
@@ -229,19 +203,19 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
@Override
- public void enableUser(UserAccessInfo request, StreamObserver<User> responseObserver) {
+ public void enableUser(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.UserRepresentation> responseObserver) {
try {
LOGGER.debug("Request received to enableUser for " + request.getTenantId());
boolean accountEnabled = keycloakClient.enableUserAccount(String.valueOf(request.getTenantId()),
- request.getAccessToken(), request.getUsername());
+ request.getAccessToken(), request.getUser().getUsername());
if (accountEnabled) {
UserRepresentation representation = keycloakClient.getUser(String.valueOf(request.getTenantId()),
- request.getAccessToken(), request.getUsername());
+ request.getAccessToken(), request.getUser().getUsername());
- User user = getUser(representation, request.getTenantId());
+ org.apache.custos.iam.service.UserRepresentation user = getUser(representation, request.getClientId());
statusUpdater.updateStatus(IAMOperations.ENABLE_USER.name(),
@@ -277,12 +251,12 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
@Override
- public void isUserExist(UserAccessInfo request, StreamObserver<CheckingResponse> responseObserver) {
+ public void isUserExist(UserSearchRequest request, StreamObserver<CheckingResponse> responseObserver) {
try {
LOGGER.debug("Request received to isUserExist for " + request.getTenantId());
boolean isUserExist = keycloakClient.isUserExist(String.valueOf(request.getTenantId()),
- request.getAccessToken(), request.getUsername());
+ request.getAccessToken(), request.getUser().getUsername());
CheckingResponse response = CheckingResponse.newBuilder().setIsExist(isUserExist).build();
responseObserver.onNext(response);
@@ -297,60 +271,71 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
@Override
- public void getUser(UserAccessInfo request, StreamObserver<User> responseObserver) {
+ public void getUser(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.UserRepresentation> responseObserver) {
try {
LOGGER.debug("Request received to getUser for " + request.getTenantId());
UserRepresentation representation = keycloakClient.getUser(String.valueOf(request.getTenantId()),
- request.getAccessToken(), request.getUsername());
+ request.getAccessToken(), request.getUser().getUsername());
if (representation != null) {
- User user = getUser(representation, request.getTenantId());
+ org.apache.custos.iam.service.UserRepresentation user = getUser(representation, request.getClientId());
responseObserver.onNext(user);
responseObserver.onCompleted();
} else {
- String msg = "User " + request.getUsername() + "not found at " + request.getTenantId();
+ String msg = "User " + request.getUser().getUsername() + "not found at " + request.getTenantId();
responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
}
} catch (Exception ex) {
String msg = "Error occurred during getUser" + ex;
LOGGER.error(msg, ex);
- responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ if (ex.getMessage().contains("Unauthorized")) {
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
}
}
@Override
- public void getUsers(GetUsersRequest request, StreamObserver<GetUsersResponse> responseObserver) {
+ public void findUsers(FindUsersRequest request, StreamObserver<FindUsersResponse> responseObserver) {
try {
- LOGGER.debug("Request received to getUsers for " + request.getInfo().getUsername());
+ LOGGER.debug("Request received to getUsers for " + request.getUser().getUsername());
- List<UserRepresentation> representation = keycloakClient.getUsers(request.getInfo().getAccessToken(),
- String.valueOf(request.getInfo().getTenantId()), request.getOffset(), request.getLimit(), request.getSearch());
- List<User> users = new ArrayList<>();
- representation.stream().forEach(r -> users.add(this.getUser(r, request.getInfo().getTenantId())));
+ List<UserRepresentation> representation = keycloakClient.getUsers(request.getAccessToken(),
+ String.valueOf(request.getTenantId()), request.getOffset(), request.getLimit(),
+ request.getUser().getUsername(), request.getUser().getFirstName(),
+ request.getUser().getLastName(),
+ request.getUser().getEmail());
+ List<org.apache.custos.iam.service.UserRepresentation> users = new ArrayList<>();
+ representation.stream().forEach(r -> users.add(this.getUser(r, request.getClientId())));
- GetUsersResponse response = GetUsersResponse.newBuilder().addAllUser(users).build();
+ FindUsersResponse response = FindUsersResponse.newBuilder().addAllUser(users).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (Exception ex) {
String msg = "Error occurred during getUsers" + ex;
LOGGER.error(msg, ex);
- responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ if (ex.getMessage().contains("Unauthorized")) {
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
}
}
@Override
public void resetPassword(ResetUserPassword request, StreamObserver<CheckingResponse> responseObserver) {
- String userId = request.getInfo().getUsername() + "@" + request.getInfo().getTenantId();
+ String userId = request.getUsername() + "@" + request.getTenantId();
try {
- LOGGER.debug("Request received to resetPassword for " + request.getInfo().getUsername());
+ LOGGER.debug("Request received to resetPassword for " + request.getUsername());
- boolean isChanged = keycloakClient.resetUserPassword(request.getInfo().getAccessToken(),
- String.valueOf(request.getInfo().getTenantId()),
- request.getInfo().getUsername(),
+ boolean isChanged = keycloakClient.resetUserPassword(request.getAccessToken(),
+ String.valueOf(request.getTenantId()),
+ request.getUsername(),
request.getPassword());
CheckingResponse response = CheckingResponse.newBuilder().setIsExist(isChanged).build();
@@ -358,7 +343,7 @@ public class IamAdminService extends IamAdminServiceImplBase {
statusUpdater.updateStatus(IAMOperations.RESET_PASSWORD.name(),
OperationStatus.SUCCESS,
- request.getInfo().getTenantId(), userId);
+ request.getTenantId(), userId);
responseObserver.onNext(response);
@@ -371,44 +356,22 @@ public class IamAdminService extends IamAdminServiceImplBase {
statusUpdater.updateStatus(IAMOperations.RESET_PASSWORD.name(),
OperationStatus.FAILED,
- request.getInfo().getTenantId(), userId);
+ request.getTenantId(), userId);
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
}
}
- @Override
- public void findUsers(FindUsersRequest request, StreamObserver<GetUsersResponse> responseObserver) {
- try {
- LOGGER.debug("Request received to findUsers for " + request.getInfo().getTenantId());
-
- List<UserRepresentation> representations = keycloakClient.findUser(request.getInfo().getAccessToken(),
- String.valueOf(request.getInfo().getTenantId()),
- request.getInfo().getUsername(),
- request.getEmail());
- List<User> users = new ArrayList<>();
- representations.stream().forEach(r -> users.add(this.getUser(r, request.getInfo().getTenantId())));
-
- GetUsersResponse response = GetUsersResponse.newBuilder().addAllUser(users).build();
- responseObserver.onNext(response);
- responseObserver.onCompleted();
-
- } catch (Exception ex) {
- String msg = "Error occurred during findUsers" + ex;
- LOGGER.error(msg, ex);
- responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
- }
- }
@Override
public void updateUserProfile(UpdateUserProfileRequest request, StreamObserver<CheckingResponse> responseObserver) {
- String userId = request.getUser().getUsername() + "@" + request.getUser().getTenantId();
+ String userId = request.getUser().getUsername() + "@" + request.getTenantId();
try {
LOGGER.debug("Request received to updateUserProfile for " + request.getUser().getUsername());
keycloakClient.updateUserRepresentation(request.getAccessToken(),
- String.valueOf(request.getUser().getTenantId()),
+ String.valueOf(request.getTenantId()),
request.getUser().getUsername(),
request.getUser().getFirstName(),
request.getUser().getLastName(),
@@ -419,7 +382,7 @@ public class IamAdminService extends IamAdminServiceImplBase {
statusUpdater.updateStatus(IAMOperations.UPDATE_USER_PROFILE.name(),
OperationStatus.SUCCESS,
- request.getUser().getTenantId(), userId);
+ request.getTenantId(), userId);
responseObserver.onNext(response);
@@ -432,22 +395,22 @@ public class IamAdminService extends IamAdminServiceImplBase {
statusUpdater.updateStatus(IAMOperations.UPDATE_USER_PROFILE.name(),
OperationStatus.FAILED,
- request.getUser().getTenantId(), userId);
+ request.getTenantId(), userId);
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
}
}
@Override
- public void deleteUser(UserAccessInfo request, StreamObserver<CheckingResponse> responseObserver) {
+ public void deleteUser(UserSearchRequest request, StreamObserver<CheckingResponse> responseObserver) {
- String userId = request.getUsername() + "@" + request.getTenantId();
+ String userId = request.getUser().getUsername() + "@" + request.getTenantId();
try {
LOGGER.debug("Request received to deleteUser for " + request.getTenantId());
boolean isUpdated = keycloakClient.deleteUser(request.getAccessToken(),
- String.valueOf(request.getTenantId()), request.getUsername());
+ String.valueOf(request.getTenantId()), request.getUser().getUsername());
CheckingResponse response = CheckingResponse.newBuilder().setIsExist(isUpdated).build();
@@ -470,24 +433,31 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
@Override
- public void deleteRoleFromUser(RoleOperationsUserRequest request, StreamObserver<CheckingResponse> responseObserver) {
-
- String userId = request.getAdminUsername() + "@" + request.getTenantId();
+ public void deleteRolesFromUser(DeleteUserRolesRequest request, StreamObserver<CheckingResponse> responseObserver) {
try {
LOGGER.debug("Request received to deleteRoleFromUser for " + request.getTenantId());
- boolean isRemoved = keycloakClient.removeRoleFromUser(request.getAdminUsername(), request.getPassword(),
- String.valueOf(request.getTenantId()), request.getUsername(), request.getRole());
+ if (!request.getRealmRolesList().isEmpty()) {
- CheckingResponse response = CheckingResponse.newBuilder().setIsExist(isRemoved).build();
+ keycloakClient.removeRoleFromUser(request.getAccessToken(),
+ String.valueOf(request.getTenantId()), request.getUsername(),
+ request.getRealmRolesList(), request.getClientId(), false);
+ }
+
+ if (!request.getClientRolesList().isEmpty()) {
+ keycloakClient.removeRoleFromUser(request.getAccessToken(),
+ String.valueOf(request.getTenantId()), request.getUsername(),
+ request.getClientRolesList(), request.getClientId(), true);
+
+ }
+ CheckingResponse response = CheckingResponse.newBuilder().setIsExist(true).build();
statusUpdater.updateStatus(IAMOperations.DELETE_ROLE_FROM_USER.name(),
OperationStatus.SUCCESS,
- request.getTenantId(), userId);
-
+ request.getTenantId(), request.getPerformedBy());
responseObserver.onNext(response);
responseObserver.onCompleted();
@@ -498,9 +468,13 @@ public class IamAdminService extends IamAdminServiceImplBase {
statusUpdater.updateStatus(IAMOperations.DELETE_ROLE_FROM_USER.name(),
OperationStatus.FAILED,
- request.getTenantId(), userId);
+ request.getTenantId(), request.getPerformedBy());
- responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ if (ex.getMessage().contains("Unauthorized")) {
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
}
}
@@ -570,6 +544,7 @@ public class IamAdminService extends IamAdminServiceImplBase {
List<org.apache.custos.iam.service.UserRepresentation> failedList = new ArrayList<>();
+
for (org.apache.custos.iam.service.UserRepresentation userRepresentation : userRepresentations) {
try {
@@ -584,16 +559,47 @@ public class IamAdminService extends IamAdminServiceImplBase {
keycloakClient.enableUserAccount
(String.valueOf(request.getTenantId()),
- request.getAccessToken(), userRepresentation.getUsername());
+ request.getAccessToken(), userRepresentation.getUsername().toLowerCase());
+ List<String> userList = new ArrayList<>();
+ userList.add(userRepresentation.getUsername());
+ if (!userRepresentation.getRealmRolesList().isEmpty()) {
+ keycloakClient.addRolesToUsers(request.getAccessToken(),
+ String.valueOf(request.getTenantId()), userList, userRepresentation.getRealmRolesList(),
+ request.getClientId(), false);
+ }
+ if (!userRepresentation.getClientRolesList().isEmpty()) {
+ keycloakClient.addRolesToUsers(request.getAccessToken(),
+ String.valueOf(request.getTenantId()), userList, userRepresentation.getClientRolesList(),
+ request.getClientId(), true);
+ }
+
+ if (!userRepresentation.getAttributesList().isEmpty()) {
+
+ Map<String, List<String>> map = new HashMap<>();
+ for (UserAttribute attribute : userRepresentation.getAttributesList()) {
+ map.put(attribute.getKey(), attribute.getValuesList());
+ }
+
+ keycloakClient.addUserAttributes(String.valueOf(request.getTenantId()),
+ request.getAccessToken(), map, userList);
+
+ }
+
+ } catch (UnauthorizedException ex) {
+ LOGGER.error(" Error occurred while adding user " + userRepresentation.getUsername() +
+ " to realm" + request.getTenantId());
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(ex.getMessage())
+ .asRuntimeException());
+ return;
} catch (Exception ex) {
-
+ if (ex.getMessage().contains("Unauthorized")) {
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(ex.getMessage())
+ .asRuntimeException());
+ return;
+ }
LOGGER.error(" Error occurred while adding user " + userRepresentation.getUsername() +
" to realm" + request.getTenantId());
failedList.add(userRepresentation);
- statusUpdater.updateStatus(IAMOperations.REGISTER_ENABLE_USERS.name(),
- OperationStatus.FAILED,
- request.getTenantId(),
- userRepresentation.getUsername());
}
}
@@ -601,7 +607,7 @@ public class IamAdminService extends IamAdminServiceImplBase {
statusUpdater.updateStatus(IAMOperations.REGISTER_ENABLE_USERS.name(),
OperationStatus.FAILED,
request.getTenantId(),
- String.valueOf(request.getTenantId()));
+ request.getPerformedBy());
}
@@ -618,11 +624,231 @@ public class IamAdminService extends IamAdminServiceImplBase {
request.getTenantId(),
String.valueOf(request.getTenantId()));
String msg = " Register multiple users failed for " + request.getTenantId();
+ responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+ }
+ }
+
+
+ @Override
+ public void addRolesToUsers(AddUserRolesRequest request,
+ StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+ try {
+ LOGGER.debug("Request received to addRolesToUsers for " + request.getTenantId());
+
+ keycloakClient.addRolesToUsers(request.getAccessToken(), String.valueOf(request.getTenantId()),
+ request.getUsernamesList(), request.getRolesList(), request.getClientId(), request.getClientLevel());
+
+ statusUpdater.updateStatus(IAMOperations.ADD_ROLES_TO_USERS.name(),
+ OperationStatus.SUCCESS,
+ request.getTenantId(),
+ request.getPerformedBy());
+
+ org.apache.custos.iam.service.OperationStatus status = org.apache.custos.iam.service.OperationStatus.
+ newBuilder().setStatus(true).build();
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+ } catch (Exception ex) {
+ statusUpdater.updateStatus(IAMOperations.ADD_ROLES_TO_USERS.name(),
+ OperationStatus.FAILED,
+ request.getTenantId(),
+ request.getPerformedBy());
+ String msg = " Add multiple users failed for " + request.getTenantId() + " " + ex.getMessage();
LOGGER.error(msg);
+ 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 addRolesToTenant(AddRolesRequest request, StreamObserver<AllRoles> responseObserver) {
+ try {
+ LOGGER.debug("Request received to add roles to tenant for " + request.getTenantId());
+
+ List<RoleRepresentation> rolesRepresentations = request.getRolesList();
+
+ List<org.keycloak.representations.idm.RoleRepresentation> keycloakRolesList = new ArrayList<>();
+
+ for (RoleRepresentation roleRepresentation : rolesRepresentations) {
+ org.keycloak.representations.idm.RoleRepresentation role = new org.keycloak.representations.idm.RoleRepresentation();
+ role.setName(roleRepresentation.getName());
+ role.setDescription(roleRepresentation.getDescription());
+ role.setComposite(roleRepresentation.getComposite());
+ keycloakRolesList.add(role);
+ }
+
+ keycloakClient.addRoles(keycloakRolesList, String.valueOf(request.getTenantId()),
+ request.getClientId(), request.getClientLevel());
+
+ statusUpdater.updateStatus(IAMOperations.ADD_ROLES_TO_TENANT.name(),
+ OperationStatus.SUCCESS,
+ request.getTenantId(),
+ String.valueOf(request.getTenantId()));
+
+ List<org.keycloak.representations.idm.RoleRepresentation> allKeycloakRoles = keycloakClient.
+ getAllRoles(String.valueOf(request.getTenantId()), (request.getClientLevel()) ? request.getClientId() : null);
+ AllRoles.Builder builder = AllRoles.newBuilder();
+ if (allKeycloakRoles != null && !allKeycloakRoles.isEmpty()) {
+
+ List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+ for (org.keycloak.representations.idm.RoleRepresentation role : allKeycloakRoles) {
+ RoleRepresentation roleRepresentation = RoleRepresentation.
+ newBuilder().setName(role.getName())
+ .setComposite(role.isComposite())
+ .build();
+ if (role.getDescription() != null) {
+ roleRepresentation = roleRepresentation.toBuilder().setDescription(role.getDescription()).build();
+ }
+ roleRepresentations.add(roleRepresentation);
+
+
+ }
+
+ builder.addAllRoles(roleRepresentations);
+ if (request.getClientLevel()) {
+ builder.setScope("client_level");
+ } else {
+ builder.setScope("realm_level");
+ }
+
+ }
+
+ responseObserver.onNext(builder.build());
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ statusUpdater.updateStatus(IAMOperations.ADD_ROLES_TO_TENANT.name(),
+ OperationStatus.FAILED,
+ request.getTenantId(),
+ String.valueOf(request.getTenantId()));
+ String msg = " Add roles failed for " + request.getTenantId() + " " + ex.getMessage();
+ LOGGER.error(msg, ex);
+ responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+
+ @Override
+ public void addProtocolMapper(AddProtocolMapperRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+ try {
+ LOGGER.debug("Request received to add protocol mapper " + request.getTenantId());
+
+
+ if (!request.getMapperType().equals(MapperTypes.USER_ATTRIBUTE)) {
+ responseObserver.onError(io.grpc.Status.UNIMPLEMENTED.
+ withDescription("Mapping type not supported").asRuntimeException());
+ return;
+ }
+
+ ProtocolMapperRepresentation protocolMapperRepresentation = new ProtocolMapperRepresentation();
+ protocolMapperRepresentation.setName(request.getName());
+ protocolMapperRepresentation.setProtocol("openid-connect");
+ protocolMapperRepresentation.setProtocolMapper("oidc-usermodel-attribute-mapper");
+
+ Map<String, String> configMap = new HashMap<>();
+
+ configMap.put("user.session.note", request.getClaimName());
+ configMap.put("id.token.claim", String.valueOf(request.getAddToIdToken()));
+ configMap.put("access.token.claim", String.valueOf(request.getAddToAccessToken()));
+ configMap.put("claim.name", request.getClaimName());
+ switch (request.getClaimType()) {
+ case JSON:
+ configMap.put("jsonType.label", "JSON");
+ break;
+ case LONG:
+ configMap.put("jsonType.label", "long");
+ break;
+ case STRING:
+ configMap.put("jsonType.label", "String");
+ break;
+ case BOOLEAN:
+ configMap.put("jsonType.label", "boolean");
+ break;
+ case INTEGER:
+ configMap.put("jsonType.label", "int");
+ break;
+ default: {
+ responseObserver.onError(io.grpc.Status.INVALID_ARGUMENT.
+ withDescription("Unknown claim type").asRuntimeException());
+ return;
+ }
+ }
+
+ configMap.put("aggregate.attrs", String.valueOf(request.getAggregateAttributeValues()));
+ configMap.put("userinfo.token.claim", String.valueOf(request.getAddToUserInfo()));
+ configMap.put("multivalued", String.valueOf(request.getMultiValued()));
+ configMap.put("user.attribute", request.getAttributeName());
+
+
+ protocolMapperRepresentation.setConfig(configMap);
+
+ keycloakClient.addProtocolMapper(protocolMapperRepresentation, String.valueOf(request.getTenantId()),
+ request.getClientId());
+
+ statusUpdater.updateStatus(IAMOperations.ADD_PROTOCOL_MAPPER.name(),
+ OperationStatus.SUCCESS,
+ request.getTenantId(),
+ String.valueOf(request.getTenantId()));
+
+ org.apache.custos.iam.service.OperationStatus status =
+ org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(true).build();
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ statusUpdater.updateStatus(IAMOperations.ADD_PROTOCOL_MAPPER.name(),
+ OperationStatus.FAILED,
+ request.getTenantId(),
+ String.valueOf(request.getTenantId()));
+ String msg = " Add roles failed for " + request.getTenantId() + " " + ex.getMessage();
+ LOGGER.error(msg, ex);
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
}
}
+ @Override
+ public void addUserAttributes(AddUserAttributesRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+ try {
+ LOGGER.debug("Request received to add protocol mapper " + request.getTenantId());
+
+ List<UserAttribute> attributes = request.getAttributesList();
+
+ Map<String, List<String>> attributeMap = new HashMap<>();
+ for (UserAttribute attribute : attributes) {
+ attributeMap.put(attribute.getKey(), attribute.getValuesList());
+ }
+
+ keycloakClient.addUserAttributes(String.valueOf(request.getTenantId()), request.getAccessToken(), attributeMap, request.getUsersList());
+
+ statusUpdater.updateStatus(IAMOperations.ADD_USER_ATTRIBUTE.name(),
+ OperationStatus.SUCCESS,
+ request.getTenantId(),
+ request.getPerformedBy());
+
+ org.apache.custos.iam.service.OperationStatus status =
+ org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(true).build();
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ statusUpdater.updateStatus(IAMOperations.ADD_USER_ATTRIBUTE.name(),
+ OperationStatus.FAILED,
+ request.getTenantId(),
+ request.getPerformedBy());
+ String msg = " Add attributes failed for " + request.getTenantId() + " " + ex.getMessage();
+ LOGGER.error(msg, ex);
+ 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())
@@ -632,7 +858,7 @@ public class IamAdminService extends IamAdminServiceImplBase {
}
- private User getUser(UserRepresentation representation, long teantId) {
+ private org.apache.custos.iam.service.UserRepresentation getUser(UserRepresentation representation, String clientId) {
String state = Status.PENDING_CONFIRMATION;
if (representation.isEnabled()) {
state = Status.ACTIVE;
@@ -640,16 +866,44 @@ public class IamAdminService extends IamAdminServiceImplBase {
state = Status.CONFIRMED;
}
- return User.newBuilder()
- .setInternalUserId(representation.getUsername() + "@" + teantId)
+ Map<String, List<String>> attributes = representation.getAttributes();
+
+ List<UserAttribute> attributeList = new ArrayList<>();
+
+ if (attributes != null && !attributes.isEmpty()) {
+ for (String key : attributes.keySet()) {
+ UserAttribute attribute = UserAttribute.
+ newBuilder()
+ .setKey(key)
+ .addAllValues(attributes.get(key)).build();
+ attributeList.add(attribute);
+ }
+ }
+
+ org.apache.custos.iam.service.UserRepresentation.Builder builder = org.apache.custos.iam.service.UserRepresentation.newBuilder()
.setUsername(representation.getUsername())
.setFirstName(representation.getFirstName())
.setLastName(representation.getLastName())
.setState(state)
.setCreationTime(representation.getCreatedTimestamp())
- .setEmail(representation.getEmail())
- .setTenantId(teantId)
- .build();
+ .setEmail(representation.getEmail());
+
+
+ if (representation.getAttributes() != null && !representation.getAttributes().isEmpty()) {
+ builder.addAllAttributes(attributeList);
+ }
+
+
+ if (representation.getRealmRoles() != null && !representation.getRealmRoles().isEmpty()) {
+ builder.addAllRealmRoles(representation.getRealmRoles());
+ }
+
+ if (representation.getClientRoles() != null && representation.getClientRoles().get(clientId) != null &&
+ !representation.getClientRoles().get(clientId).isEmpty()) {
+ builder.addAllClientRoles(representation.getClientRoles().get(clientId));
+ }
+
+ return builder.build();
}
}
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 505b113..bafb0c1 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
@@ -33,7 +33,9 @@ public enum IAMOperations {
ADD_ROLE_TO_USER,
DELETE_ROLE_FROM_USER,
CONFIGURE_IDP,
- REGISTER_ENABLE_USERS
-
-
+ REGISTER_ENABLE_USERS,
+ ADD_ROLES_TO_TENANT,
+ ADD_PROTOCOL_MAPPER,
+ ADD_USER_ATTRIBUTE,
+ ADD_ROLES_TO_USERS
}
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 2a4b3f6..41bc473 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
@@ -24,7 +24,6 @@ import org.apache.custos.core.services.commons.Validator;
import org.apache.custos.iam.exceptions.MissingParameterException;
import org.apache.custos.iam.service.*;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -45,9 +44,6 @@ public class InputValidator implements Validator {
case "setUPTenant":
validateSetUPTenant(obj);
break;
- case "isUsernameAvailable":
- validateIsUsernameAvailable(obj);
- break;
case "registerUser":
validateRegisterUser(obj);
break;
@@ -59,23 +55,34 @@ public class InputValidator implements Validator {
case "isUserExist":
case "getUser":
case "deleteUser":
+ case "isUsernameAvailable":
validateUserAccess(obj);
break;
- case "getUsers":
- validateGetUsers(obj);
- break;
case "resetPassword":
validateResetPassword(obj);
break;
case "findUsers":
validateFindUsers(obj);
+ break;
case "updateUserProfile":
validateUpdateUserProfile(obj);
+ break;
case "addRoleToUser":
- case "deleteRoleFromUser":
- validateRoleOperationsRequest(obj);
+ case "deleteRolesFromUser":
+ validateDeleteRolesFromUser(obj);
+ break;
case "configureFederatedIDP":
validateConfigureFederatedIDP(obj);
+ break;
+ case "addRolesToTenant":
+ validateAddRoleToTenant(obj);
+ break;
+ case "addProtocolMapper":
+ validateAddProtocolMapper(obj);
+ break;
+ case "addUserAttributes":
+ validateAddUserAttributes(obj);
+ break;
default:
}
@@ -121,26 +128,6 @@ public class InputValidator implements Validator {
return true;
}
- private boolean validateIsUsernameAvailable(Object obj) {
- if (obj instanceof IsUsernameAvailableRequest) {
- IsUsernameAvailableRequest request = (IsUsernameAvailableRequest) obj;
- if (request.getTenantId() == 0) {
- throw new MissingParameterException("Tenant Id should not be null", null);
- }
-
- if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
- throw new MissingParameterException("Access token should not be null", null);
- }
-
- if (request.getUserName() == null || request.getUserName().trim().equals("")) {
- throw new MissingParameterException("Username should not be null", null);
- }
-
- } else {
- throw new RuntimeException("Unexpected input type for method isUsernameAvailable");
- }
- return true;
- }
private boolean validateRegisterUser(Object obj) {
if (obj instanceof RegisterUserRequest) {
@@ -193,6 +180,10 @@ public class InputValidator implements Validator {
throw new MissingParameterException("Access Token should not be null", null);
}
+ if (usersRequest.getClientId() == null) {
+ throw new MissingParameterException("Client Id should not be null", null);
+ }
+
List<UserRepresentation> userRepresentationList = usersRequest.getUsersList();
for (UserRepresentation user : userRepresentationList) {
@@ -217,14 +208,14 @@ public class InputValidator implements Validator {
}
} else {
- throw new RuntimeException("Unexpected input type for method registerUser");
+ throw new RuntimeException("Unexpected input type for method registerUsers");
}
return true;
}
private boolean validateUserAccess(Object obj) {
- if (obj instanceof UserAccessInfo) {
- UserAccessInfo request = (UserAccessInfo) obj;
+ if (obj instanceof UserSearchRequest) {
+ UserSearchRequest request = (UserSearchRequest) obj;
if (request.getTenantId() == 0) {
throw new MissingParameterException("Tenant Id should not be null", null);
}
@@ -233,7 +224,7 @@ public class InputValidator implements Validator {
throw new MissingParameterException("Access token should not be null", null);
}
- if (request.getUsername() == null || request.getUsername().trim().equals("")) {
+ if (request.getUser().getUsername() == null || request.getUser().getUsername().trim().equals("")) {
throw new MissingParameterException("Username should not be null", null);
}
@@ -244,40 +235,19 @@ public class InputValidator implements Validator {
}
- private boolean validateGetUsers(Object obj) {
- if (obj instanceof GetUsersRequest) {
- GetUsersRequest request = (GetUsersRequest) obj;
- UserAccessInfo info = request.getInfo();
- if (info.getTenantId() == 0) {
- throw new MissingParameterException("Tenant Id should not be null", null);
- }
-
- if (info.getAccessToken() == null || info.getAccessToken().trim().equals("")) {
- throw new MissingParameterException("Access token should not be null", null);
- }
-
- if (request.getSearch() == null || request.getSearch().trim().equals("")) {
- throw new MissingParameterException("Search parameter should not be null", null);
- }
- } else {
- throw new RuntimeException("Unexpected input type for method getUsers");
- }
- return true;
- }
-
private boolean validateResetPassword(Object obj) {
if (obj instanceof ResetUserPassword) {
ResetUserPassword request = (ResetUserPassword) obj;
- UserAccessInfo info = request.getInfo();
- if (info.getTenantId() == 0) {
+
+ if (request.getTenantId() == 0) {
throw new MissingParameterException("Tenant Id should not be null", null);
}
- if (info.getAccessToken() == null || info.getAccessToken().trim().equals("")) {
+ if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
throw new MissingParameterException("Access token should not be null", null);
}
- if (info.getUsername() == null || info.getUsername().trim().equals("")) {
+ if (request.getUsername() == null || request.getUsername().trim().equals("")) {
throw new MissingParameterException("Username should not be null", null);
}
@@ -294,21 +264,16 @@ public class InputValidator implements Validator {
private boolean validateFindUsers(Object obj) {
if (obj instanceof FindUsersRequest) {
FindUsersRequest request = (FindUsersRequest) obj;
- UserAccessInfo info = request.getInfo();
- if (info.getTenantId() == 0) {
+ if (request.getTenantId() == 0) {
throw new MissingParameterException("Tenant Id should not be null", null);
}
- if (info.getAccessToken() == null || info.getAccessToken().trim().equals("")) {
+ if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
throw new MissingParameterException("Access token should not be null", null);
}
- if (info.getUsername() == null || info.getUsername().trim().equals("")) {
- throw new MissingParameterException("Username should not be null", null);
- }
-
- if (request.getEmail() == null || request.getEmail().trim().equals("")) {
- throw new MissingParameterException("Email should not be null", null);
+ if (request.getUser() == null) {
+ throw new MissingParameterException("Atleast one user search string is required", null);
}
} else {
@@ -320,8 +285,8 @@ public class InputValidator implements Validator {
private boolean validateUpdateUserProfile(Object obj) {
if (obj instanceof UpdateUserProfileRequest) {
UpdateUserProfileRequest re = (UpdateUserProfileRequest) obj;
- User request = re.getUser();
- if (request.getTenantId() == 0) {
+ UserRepresentation request = re.getUser();
+ if (re.getTenantId() == 0) {
throw new MissingParameterException("Tenant Id should not be null", null);
}
@@ -351,28 +316,33 @@ public class InputValidator implements Validator {
}
- private boolean validateRoleOperationsRequest(Object obj) {
- if (obj instanceof RoleOperationsUserRequest) {
- RoleOperationsUserRequest request = (RoleOperationsUserRequest) obj;
+ private boolean validateDeleteRolesFromUser(Object obj) {
+ if (obj instanceof DeleteUserRolesRequest) {
+ DeleteUserRolesRequest request = (DeleteUserRolesRequest) obj;
+
if (request.getTenantId() == 0) {
throw new MissingParameterException("Tenant Id should not be null", null);
}
- if (request.getAdminUsername() == null || request.getAdminUsername().trim().equals("")) {
- throw new MissingParameterException("Admin username should not be null", null);
- }
-
if (request.getUsername() == null || request.getUsername().trim().equals("")) {
throw new MissingParameterException("Username should not be null", null);
}
- if (request.getPassword() == null || request.getPassword().trim().equals("")) {
- throw new MissingParameterException("Password should not be null", null);
+ if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+ throw new MissingParameterException("Client Id should not be null", null);
}
- if (request.getRole() == null || request.getRole().trim().equals("")) {
- throw new MissingParameterException("Role should not be null", null);
+
+ if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+ throw new MissingParameterException("Access token should not be null", null);
}
+ if (request.getClientRolesList().isEmpty() && request.getRealmRolesList().isEmpty()) {
+ throw new MissingParameterException("At least client roles or realm roles should not be null", null);
+ }
+
+ if (request.getPerformedBy() == null || request.getPerformedBy().equals("")) {
+ throw new MissingParameterException("Performed By should not be null", null);
+ }
} else {
throw new RuntimeException("Unexpected input type for method roleOperationsRequest");
@@ -409,4 +379,101 @@ public class InputValidator implements Validator {
return true;
}
+ private boolean validateAddRoleToTenant(Object obj) {
+ if (obj instanceof AddRolesRequest) {
+ AddRolesRequest request = (AddRolesRequest) obj;
+ if (request.getTenantId() == 0) {
+ throw new MissingParameterException("Tenant Id should not be null", null);
+ }
+
+ if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+ throw new MissingParameterException("Client Id should not be null", null);
+ }
+
+ if (request.getRolesCount() == 0) {
+ throw new MissingParameterException("There should be at least one role", null);
+ }
+
+ } else {
+ throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+ }
+ return true;
+ }
+
+
+ private boolean validateAddProtocolMapper(Object obj) {
+ if (obj instanceof AddProtocolMapperRequest) {
+ AddProtocolMapperRequest request = (AddProtocolMapperRequest) obj;
+ if (request.getTenantId() == 0) {
+ throw new MissingParameterException("Tenant Id should not be null", null);
+ }
+
+ if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+ throw new MissingParameterException("Client Id should not be null", null);
+ }
+
+ if (request.getClaimName() == null || request.getClaimName().trim().equals("")) {
+ throw new MissingParameterException("Claim name should not be null", null);
+ }
+
+ if (request.getAttributeName() == null || request.getAttributeName().trim().equals("")) {
+ throw new MissingParameterException("Attribute name should not be null", null);
+ }
+
+
+ if (request.getName() == null || request.getName().trim().equals("")) {
+ throw new MissingParameterException("Name should not be null", null);
+ }
+
+
+ if (request.getClaimType() == null) {
+ throw new MissingParameterException("Claim Type should not be null", null);
+ }
+
+ if (request.getMapperType() == null) {
+ throw new MissingParameterException("Mapper Type should not be null", null);
+ }
+
+ } else {
+ throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+ }
+ return true;
+ }
+
+ private boolean validateAddUserAttributes(Object obj) {
+ if (obj instanceof AddUserAttributesRequest) {
+ AddUserAttributesRequest request = (AddUserAttributesRequest) obj;
+ if (request.getTenantId() == 0) {
+ throw new MissingParameterException("Tenant Id should not be null", null);
+ }
+
+ if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+ throw new MissingParameterException("Client Id should not be null", null);
+ }
+
+ if (request.getAttributesList().isEmpty()) {
+ throw new MissingParameterException("Attributes should not be null", null);
+ }
+
+ if (request.getUsersList().isEmpty()) {
+ throw new MissingParameterException("Users should not be null", null);
+ }
+
+
+ for (UserAttribute attribute : request.getAttributesList()) {
+ if (attribute.getKey() == null || attribute.getKey().equals("")) {
+ throw new MissingParameterException("Attribute Key should not be null", null);
+ }
+
+ if (attribute.getValuesList().isEmpty()) {
+ throw new MissingParameterException("Attribute value should not be null", null);
+ }
+ }
+
+ } else {
+ throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+ }
+ return true;
+ }
+
}
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 932bcf2..fc0bebc 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
@@ -35,16 +35,6 @@ enum FederatedIDPs {
CUSTOM_OIDC = 5;
}
-message User {
- string internalUserId = 1;
- string username = 2;
- int64 tenantId = 3;
- string firstName = 4;
- string lastName = 5;
- string email = 6;
- float creationTime = 7;
- string state = 8;
-}
message SetUpTenantRequest {
int64 tenantId = 1;
@@ -90,7 +80,7 @@ message IsUsernameAvailableRequest {
}
message CheckingResponse {
- bool isExist = 1;
+ bool is_exist = 1;
}
@@ -101,6 +91,11 @@ message UserRepresentation {
string password = 6;
string email = 7;
bool temporary_password = 8;
+ repeated string realm_roles = 9;
+ repeated string client_roles = 10;
+ repeated UserAttribute attributes = 11;
+ string state = 12;
+ double creation_time = 13;
}
@@ -118,11 +113,11 @@ message RegisterUsersRequest {
int64 tenantId = 2;
string accessToken = 3;
string clientId = 4;
- string clientSecret = 5;
+ string performedBy = 5;
}
message RegisterUserResponse {
- bool isRegistered = 1;
+ bool is_registered = 1;
}
message RegisterUsersResponse {
@@ -131,47 +126,70 @@ message RegisterUsersResponse {
}
-message UserAccessInfo {
+message UserSearchMetadata {
+ string username = 1;
+ string first_name = 2;
+ string last_name = 3;
+ string email = 4;
+}
+
+message FindUsersRequest {
+ UserSearchMetadata user = 3;
+ int32 offset = 4;
+ int32 limit = 5;
int64 tenantId = 1;
string accessToken = 2;
- string username = 3;
+ string client_id = 6;
}
-message GetUsersRequest {
- UserAccessInfo info = 1;
- int32 offset = 3;
- int32 limit = 4;
- string search = 5;
-
+message UserSearchRequest {
+ UserSearchMetadata user = 1;
+ int64 tenantId = 2;
+ string accessToken = 3;
+ string client_id = 4;
+ string client_sec = 5;
}
-message GetUsersResponse {
- repeated User user = 1;
+message FindUsersResponse {
+ repeated UserRepresentation user = 1;
}
message ResetUserPassword {
- UserAccessInfo info = 1;
+ string username = 1;
string password = 2;
+ int64 tenantId = 3;
+ string accessToken = 4;
+ string clientId = 5;
+ string clientSec = 6;
}
-message FindUsersRequest {
- UserAccessInfo info = 1;
- string email = 2;
-}
-message RoleOperationsUserRequest {
- int64 tenantId = 1;
+message DeleteUserRolesRequest {
+ int64 tenant_id= 1;
string username = 2;
- string role = 3;
- string adminUsername = 4;
- string password = 5;
+ repeated string client_roles = 3;
+ repeated string realm_roles = 4;
+ string access_token = 5;
+ string client_id = 6;
+ string performed_by = 7;
+}
+message AddUserRolesRequest {
+ int64 tenant_id= 1;
+ repeated string usernames = 2;
+ repeated string roles = 3;
+ string access_token = 4;
+ string client_id = 5;
+ bool client_level = 6;
+ string performed_by = 7;
}
message UpdateUserProfileRequest {
string accessToken = 1;
- User user = 2;
+ int64 tenantId = 2;
+ UserRepresentation user = 3;
+
}
message AddUserResponse {
@@ -196,25 +214,102 @@ message DeleteTenantRequest {
int64 tenantId = 1;
}
+message AddRolesRequest {
+ repeated RoleRepresentation roles = 1;
+ bool client_level = 2;
+ int64 tenant_id = 3;
+ string client_id = 4;
+}
+
+message RoleRepresentation {
+ string name = 1;
+ string description = 2;
+ bool composite = 3;
+
+
+}
+
+message AllRoles {
+ repeated RoleRepresentation roles = 1;
+ string scope = 2;
+}
+
+message AddProtocolMapperRequest {
+ string name = 1;
+ string attribute_name = 2;
+ string claim_name = 3;
+ ClaimJSONTypes claim_type = 4;
+ int64 tenant_id = 6;
+ string client_id = 7;
+ MapperTypes mapper_type = 8;
+ bool add_to_id_token = 9;
+ bool add_to_access_token = 10;
+ bool add_to_user_info = 11;
+ bool multi_valued = 12;
+ bool aggregate_attribute_values = 13;
+}
+
+enum MapperTypes {
+ USER_ATTRIBUTE = 0;
+}
+
+enum ClaimJSONTypes {
+ STRING = 0;
+ LONG = 1;
+ INTEGER = 2;
+ BOOLEAN = 3;
+ JSON = 4;
+}
+
+
+message OperationStatus {
+ bool status = 1;
+}
+
+message AddUserAttributesRequest {
+ repeated UserAttribute attributes = 1;
+ repeated string users = 2;
+ int64 tenant_id = 3;
+ string client_id = 4;
+ string access_token = 5;
+ string performedBy = 6;
+
+}
+
+message UserAttribute {
+ string key = 1;
+ repeated string values = 2;
+}
service IamAdminService {
+
rpc setUPTenant (SetUpTenantRequest) returns (SetUpTenantResponse);
rpc deleteTenant (DeleteTenantRequest) returns (google.protobuf.Empty);
- rpc isUsernameAvailable (IsUsernameAvailableRequest) returns (CheckingResponse);
+ rpc configureFederatedIDP (ConfigureFederateIDPRequest) returns (FederateIDPResponse);
+ rpc addRolesToTenant (AddRolesRequest) returns (AllRoles);
+ rpc addProtocolMapper (AddProtocolMapperRequest) returns (OperationStatus);
+
+
+ rpc isUsernameAvailable (UserSearchRequest) returns (CheckingResponse);
rpc registerUser (RegisterUserRequest) returns (RegisterUserResponse);
- rpc enableUser (UserAccessInfo) returns (User);
- rpc isUserEnabled (UserAccessInfo) returns (CheckingResponse);
- rpc isUserExist (UserAccessInfo) returns (CheckingResponse);
- rpc getUser (UserAccessInfo) returns (User);
- rpc getUsers (GetUsersRequest) returns (GetUsersResponse);
+ rpc enableUser (UserSearchRequest) returns (UserRepresentation);
+ rpc isUserEnabled (UserSearchRequest) returns (CheckingResponse);
+ rpc isUserExist (UserSearchRequest) returns (CheckingResponse);
+
+ rpc getUser (UserSearchRequest) returns (UserRepresentation);
+ rpc findUsers (FindUsersRequest) returns (FindUsersResponse);
rpc resetPassword (ResetUserPassword) returns (CheckingResponse);
- rpc findUsers (FindUsersRequest) returns (GetUsersResponse);
- rpc updateUserProfile (UpdateUserProfileRequest) returns (CheckingResponse);
- rpc deleteUser (UserAccessInfo) returns (CheckingResponse);
- rpc addRoleToUser (RoleOperationsUserRequest) returns (CheckingResponse);
- rpc deleteRoleFromUser (RoleOperationsUserRequest) returns (CheckingResponse);
- rpc getOperationMetadata (GetOperationsMetadataRequest) returns (GetOperationsMetadataResponse);
- rpc configureFederatedIDP (ConfigureFederateIDPRequest) returns (FederateIDPResponse);
rpc registerAndEnableUsers (RegisterUsersRequest) returns (RegisterUsersResponse);
+ rpc addUserAttributes (AddUserAttributesRequest) returns (OperationStatus);
+ rpc addRolesToUsers (AddUserRolesRequest) returns (OperationStatus);
+
+ rpc deleteUser (UserSearchRequest) returns (CheckingResponse);
+ rpc deleteRolesFromUser (DeleteUserRolesRequest) returns (CheckingResponse);
+
+
+
+ rpc updateUserProfile (UpdateUserProfileRequest) returns (CheckingResponse);
+
+ rpc getOperationMetadata (GetOperationsMetadataRequest) returns (GetOperationsMetadataResponse);
}
\ No newline at end of file
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/service/IdentityService.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/service/IdentityService.java
index 8c00f96..2848d38 100644
--- a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/service/IdentityService.java
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/service/IdentityService.java
@@ -254,14 +254,24 @@ public class IdentityService extends IdentityServiceImplBase {
getAccessToken(request.getClientId(), request.getClientSecret(), String.valueOf(request.getTenantId()),
request.getCode(), request.getRedirectUri());
- Struct.Builder structBuilder = Struct.newBuilder();
- LOGGER.info(object.toString());
+ LOGGER.info(object.toString());
- Struct struct = structBuilder.build();
+ try {
+ if (object != null && object.getString("access_token") != null) {
+ Struct.Builder structBuilder = Struct.newBuilder();
+
+ JsonFormat.parser().merge(object.toString(), structBuilder);
+ responseObserver.onNext(structBuilder.build());
+ responseObserver.onCompleted();
+ }
+ } catch (Exception ex) {
+
+ String error = object.getString("error") + " " + object.getString("error_description");
+ responseObserver.onError(Status.INTERNAL.withDescription(error).asRuntimeException());
+ return;
+
+ }
- JsonFormat.parser().merge(object.toString(), structBuilder);
- responseObserver.onNext(struct);
- responseObserver.onCompleted();
} catch (Exception ex) {
String msg = "Error occurred while fetching access token for user " + request.getTenantId() + " " + ex.getMessage();
diff --git a/custos-core-services/identity-core-service/src/main/proto/IdentityService.proto b/custos-core-services/identity-core-service/src/main/proto/IdentityService.proto
index 4adb643..28b12a5 100644
--- a/custos-core-services/identity-core-service/src/main/proto/IdentityService.proto
+++ b/custos-core-services/identity-core-service/src/main/proto/IdentityService.proto
@@ -99,6 +99,8 @@ message GetOIDCConfiguration {
int64 tenant_id = 3;
}
+
+
service IdentityService {
rpc authenticate (AuthenticationRequest) returns (AuthToken);
rpc isAuthenticate (AuthToken) returns (IsAuthenticateResponse);
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/UserProfileMapper.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/UserProfileMapper.java
index e0ea18b..d04954a 100644
--- a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/UserProfileMapper.java
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/UserProfileMapper.java
@@ -41,7 +41,7 @@ public class UserProfileMapper {
entity.setId(userProfile.getUserId());
entity.setUsername(userProfile.getUsername());
- entity.setEmailAddress(userProfile.getEmailAddress());
+ entity.setEmailAddress(userProfile.getEmail());
entity.setFirstName(userProfile.getFirstName());
entity.setLastName(userProfile.getLastName());
entity.setTenantId(userProfile.getTenantId());
@@ -62,7 +62,7 @@ public class UserProfileMapper {
return org.apache.custos.user.profile.service.UserProfile.newBuilder()
.setUsername(profileEntity.getUsername())
- .setEmailAddress(profileEntity.getEmailAddress())
+ .setEmail(profileEntity.getEmailAddress())
.setFirstName(profileEntity.getFirstName())
.setLastName(profileEntity.getLastName())
.setTenantId(profileEntity.getTenantId())
@@ -79,7 +79,7 @@ public class UserProfileMapper {
buffer.append("\n");
buffer.append("tenantId : " + userProfile.getTenantId());
buffer.append("\n");
- buffer.append("emailAddress : " + userProfile.getEmailAddress());
+ buffer.append("emailAddress : " + userProfile.getEmail());
buffer.append("\n");
buffer.append("firstName : " + userProfile.getFirstName());
buffer.append("\n");
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/validators/InputValidator.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/validators/InputValidator.java
index 2aa591d..d13ea59 100644
--- a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/validators/InputValidator.java
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/validators/InputValidator.java
@@ -69,7 +69,7 @@ public class InputValidator implements Validator {
if (profile.getLastName() == null || profile.getLastName().equals("")) {
throw new MissingParameterException("lastName should not be null", null);
}
- if (profile.getEmailAddress() == null || profile.getEmailAddress().equals("")) {
+ if (profile.getEmail() == null || profile.getEmail().equals("")) {
throw new MissingParameterException("emailAddress should not be null", null);
}
} else {
diff --git a/custos-core-services/user-profile-core-service/src/main/proto/UserProfileService.proto b/custos-core-services/user-profile-core-service/src/main/proto/UserProfileService.proto
index 434a697..c626cbf 100644
--- a/custos-core-services/user-profile-core-service/src/main/proto/UserProfileService.proto
+++ b/custos-core-services/user-profile-core-service/src/main/proto/UserProfileService.proto
@@ -45,15 +45,15 @@ enum UserStatus {
message UserProfile {
int64 tenantId = 1;
string username = 2;
- string emailAddress = 3;
- string firstName = 4;
- string lastName = 5;
- string createAt = 6;
- string lastAccessAt = 7;
- int32 validTill = 8;
+ string email = 3;
+ string first_name = 4;
+ string last_name = 5;
+ string created_at = 6;
+ string last_access_at = 7;
+ int32 valid_till = 8;
UserStatus status = 9;
- string userId = 10;
- string updatedBy = 11;
+ string user_id = 10;
+ string updated_by = 11;
}
message GetUserProfileRequest {
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 0dac6fc..f07c088 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
@@ -39,10 +39,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.stream.Collectors;
/**
@@ -274,7 +271,7 @@ public class KeycloakClient {
public boolean createUser(String realmId, String username, String newPassword, String firstName,
- String lastName, String emailAddress, boolean tempPassowrd, String accessToken) {
+ String lastName, String emailAddress, boolean tempPassowrd, String accessToken) throws UnauthorizedException {
Keycloak client = null;
try {
client = getClient(iamServerURL, realmId, accessToken);
@@ -285,6 +282,7 @@ public class KeycloakClient {
user.setEmail(emailAddress);
user.setEnabled(false);
Response httpResponse = client.realm(realmId).users().create(user);
+
if (httpResponse.getStatus() == HttpStatus.SC_CREATED) { //HTTP code for record creation: HTTP 201
List<UserRepresentation> retrieveCreatedUserList = client.realm(realmId).users().search(user.getUsername(),
user.getFirstName(),
@@ -302,12 +300,8 @@ public class KeycloakClient {
String msg = "Reason for user account creation failure : " + httpResponse.getStatusInfo();
LOGGER.error("Request for user Account Creation failed with HTTP code : " + httpResponse.getStatus());
LOGGER.error(msg);
- throw new RuntimeException(msg, null);
+ throw new UnauthorizedException(msg, null);
}
- } catch (Exception ex) {
- String msg = "Error getting values from property file, reason: " + ex.getMessage();
- LOGGER.error(msg, ex);
- throw new RuntimeException(msg, null);
} finally {
if (client != null) {
client.close();
@@ -320,7 +314,9 @@ public class KeycloakClient {
Keycloak client = null;
try {
client = getClient(iamServerURL, realmId, accessToken);
+
UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+
UserResource userResource = client.realm(realmId).users().get(userRepresentation.getId());
UserRepresentation profile = userResource.toRepresentation();
profile.setEnabled(true);
@@ -379,7 +375,7 @@ public class KeycloakClient {
client = getClient(iamServerURL, realmId, accessToken);
return getUserByUsername(client, realmId, username);
} catch (Exception ex) {
- String msg = "Error getting values from property file, reason: " + ex.getMessage();
+ String msg = "Error retrieving user, reason: " + ex.getMessage();
LOGGER.error(msg, ex);
throw new RuntimeException(msg, ex);
} finally {
@@ -390,15 +386,16 @@ public class KeycloakClient {
}
- public List<UserRepresentation> getUsers(String accessToken, String realmId, int offset, int limit, String search) {
+ public List<UserRepresentation> getUsers(String accessToken, String realmId, int offset, int limit,
+ String username, String firstName, String lastName, String email) {
Keycloak client = null;
try {
client = getClient(iamServerURL, realmId, accessToken);
- return client.realm(realmId).users().search(search, offset, limit);
+ return searchUsers(client, realmId, username, firstName, lastName, email, offset, limit);
} catch (Exception ex) {
- String msg = "Error getting values from property file, reason: " + ex.getMessage();
- LOGGER.error("Error getting values from property file, reason: " + ex.getMessage(), ex);
+ String msg = "Error occurred while searching for user, reason: " + ex.getMessage();
+ LOGGER.error(msg, ex);
throw new RuntimeException(msg, ex);
} finally {
if (client != null) {
@@ -474,6 +471,7 @@ public class KeycloakClient {
userRepresentation.setLastName(lastName);
userRepresentation.setEmail(email);
UserResource userResource = client.realm(realmId).users().get(userRepresentation.getId());
+
userResource.update(userRepresentation);
} else {
throw new RuntimeException("User [" + username + "] wasn't found in Keycloak!");
@@ -513,24 +511,41 @@ public class KeycloakClient {
}
- public boolean addRoleToUser(String adminUsername, String adminPassword, String realmId, String username, String roleName) {
+ public boolean addRolesToUsers(String accessToken, String realmId, List<String> users, List<String> roles, String clientId, boolean clientLevel) {
Keycloak client = null;
try {
- client = getClient(iamServerURL, realmId, adminUsername, adminPassword);
- List<UserRepresentation> retrieveCreatedUserList = client.realm(realmId).users().search(username,
- null,
- null,
- null,
- 0, 1);
- UserResource retrievedUser = client.realm(realmId).users().get(retrieveCreatedUserList.get(0).getId());
+ client = getClient(iamServerURL, realmId, accessToken);
+
+ for (String username : users) {
+
+ UserRepresentation representation = getUserByUsername(client, realmId, username.toLowerCase());
+ ClientRepresentation clientRepresentation = client.realm(realmId).clients().findByClientId(clientId).get(0);
+ if (representation != null) {
+ RealmResource realmResource = client.realm(realmId);
+ UserResource resource = client.realm(realmId).users().get(representation.getId());
+ List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+ if (clientLevel) {
+ for (String role : roles) {
+ RoleResource roleResource = realmResource.clients().get(clientRepresentation.getId()).roles().get(role);
+ roleRepresentations.add(roleResource.toRepresentation());
+ }
+ resource.roles().clientLevel(clientRepresentation.getId()).add(roleRepresentations);
+
+ } else {
+
+ for (String role : roles) {
+ RoleResource roleResource = client.realm(realmId).roles().get(role);
+ roleRepresentations.add(roleResource.toRepresentation());
+ }
+ resource.roles().realmLevel().add(roleRepresentations);
+ }
- // Add user to the role
- RoleResource roleResource = client.realm(realmId).roles().get(roleName);
- retrievedUser.roles().realmLevel().add(Arrays.asList(roleResource.toRepresentation()));
+ }
+ }
return true;
} catch (Exception ex) {
- String msg = "Error getting values from property file, reason: " + ex.getMessage();
+ String msg = "Error while adding roles to user " + ex.getMessage();
LOGGER.error(msg, ex);
throw new RuntimeException(msg, ex);
} finally {
@@ -541,24 +556,53 @@ public class KeycloakClient {
}
- public boolean removeRoleFromUser(String adminUsername, String password, String realmId, String username, String roleName) {
+ public boolean removeRoleFromUser(String accessToken, String realmId, String username, List<String> roles, String clientId, boolean clientLevel) {
Keycloak client = null;
try {
- client = getClient(iamServerURL, realmId, adminUsername, password);
- List<UserRepresentation> retrieveCreatedUserList = client.realm(realmId).users().search(username,
- null,
- null,
- null,
- 0, 1);
- UserResource retrievedUser = client.realm(realmId).users().get(retrieveCreatedUserList.get(0).getId());
+ client = getClient(iamServerURL, realmId, accessToken);
+ UserRepresentation representation = getUserByUsername(client, realmId, username.toLowerCase());
+
+ if (representation != null) {
+ UserResource retrievedUser = client.realm(realmId).users().get(representation.getId());
+
+ if (clientLevel) {
+ List<ClientRepresentation> clientRepresentationList =
+ client.realm(realmId).clients().findByClientId(clientId);
+
+ if (clientRepresentationList != null && !clientRepresentationList.isEmpty()) {
+ ClientRepresentation clientRep = clientRepresentationList.get(0);
+ List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+ for (String roleName : roles) {
+ RoleResource roleResource = client.realm(realmId).
+ clients().get(clientRep.getId()).roles().get(roleName);
+ LOGGER.info("Roles Representatioin "+ roleName+ " roles resource " + roleResource);
+ if (roleResource != null) {
+ roleRepresentations.add(roleResource.toRepresentation());
+ }
+ }
+ if (!roleRepresentations.isEmpty()) {
+ retrievedUser.roles().clientLevel(clientRep.getId()).remove(roleRepresentations);
+ }
+
- // Remove role from user
- RoleResource roleResource = client.realm(realmId).roles().get(roleName);
- retrievedUser.roles().realmLevel().remove(Arrays.asList(roleResource.toRepresentation()));
+ }
+ } else {
+ List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+ for (String roleName : roles) {
+ RoleResource roleResource = client.realm(realmId).roles().get(roleName);
+ if (roleResource != null) {
+ roleRepresentations.add(roleResource.toRepresentation());
+ }
+ }
+ if (!roleRepresentations.isEmpty()) {
+ retrievedUser.roles().realmLevel().remove(roleRepresentations);
+ }
+ }
+ }
return true;
} catch (Exception ex) {
- String msg = "Error getting values from property file, reason " + ex.getMessage();
+ String msg = "Error removing roles from user , reason " + ex.getMessage();
LOGGER.error(msg, ex);
throw new RuntimeException(msg, ex);
} finally {
@@ -640,33 +684,30 @@ public class KeycloakClient {
/**
- * Add user level roles
+ * This adds user attributes to users
*
* @param realmId
- * @param roles
+ * @param attributeMap
* @param users
* @return
*/
- public boolean addUserRoles(String realmId, String clientId, List<RoleRepresentation> roles, List<String> users, boolean isClientLevel) {
+ public boolean addUserAttributes(String realmId, String accessToken, Map<String, List<String>> attributeMap, List<String> users) {
Keycloak client = null;
try {
- client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+ client = getClient(iamServerURL, realmId, accessToken);
RealmResource realmResource = client.realm(realmId);
+ for (String user : users) {
- users.forEach(user -> {
- UserResource resource = realmResource.users().get(user);
+ UserRepresentation userRepresentation = getUserByUsername(client, realmId, user.toLowerCase());
+ UserResource resource = realmResource.users().get(userRepresentation.getId());
- UserRepresentation representation = resource.toRepresentation();
+ userRepresentation.setAttributes(attributeMap);
+ resource.update(userRepresentation);
+ }
- if (isClientLevel) {
- resource.roles().clientLevel(clientId).add(roles);
- } else {
- resource.roles().realmLevel().add(roles);
- }
- });
} catch (Exception ex) {
String msg = "Error occurred while adding user attributes in Keycloak Server, reason: " + ex.getMessage();
LOGGER.error(msg, ex);
@@ -683,33 +724,49 @@ public class KeycloakClient {
/**
- * This adds user attributes to users
+ * Create protocol mapper representation in given client
*
+ * @param protocolMapperRepresentations
* @param realmId
- * @param attributeMap
- * @param users
+ * @param clientId
* @return
*/
- public boolean addUserAttributes(String realmId, Map<String, List<String>> attributeMap, List<String> users) {
+ public boolean addProtocolMapper(ProtocolMapperRepresentation protocolMapperRepresentations,
+ String realmId, String clientId) {
Keycloak client = null;
try {
client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
RealmResource realmResource = client.realm(realmId);
- for (String user : users) {
- UserResource resource = realmResource.users().get(user);
+ ClientRepresentation representation = realmResource.clients().findByClientId(clientId).get(0);
+
+
+ ProtocolMappersResource resource = realmResource.clients().get(representation.getId()).getProtocolMappers();
+ resource.createMapper(protocolMapperRepresentations);
+
+ ProtocolMappersResource resource2 = realmResource.clients().get(representation.getId()).getProtocolMappers();
- UserRepresentation representation = resource.toRepresentation();
+ List<ProtocolMapperRepresentation> mapperRepresentations = resource2.getMappers();
- representation.setAttributes(attributeMap);
+ for (ProtocolMapperRepresentation protocolMapperRepresentation : mapperRepresentations) {
+
+ LOGGER.info("Id " + protocolMapperRepresentation.getId());
+ LOGGER.info("Name " + protocolMapperRepresentation.getName());
+ LOGGER.info("Protocol " + protocolMapperRepresentation.getProtocol());
+ LOGGER.info("Protocol Mapper " + protocolMapperRepresentation.getProtocolMapper());
+ Map<String, String> config = protocolMapperRepresentation.getConfig();
+
+ for (String key : config.keySet()) {
+ LOGGER.info("Key " + key + " value" + config.get(key));
+
+ }
- resource.update(representation);
}
} catch (Exception ex) {
- String msg = "Error occurred while adding user attributes in Keycloak Server, reason: " + ex.getMessage();
+ String msg = "Error occurred while adding protocol mappers in Keycloak Server, reason: " + ex.getMessage();
LOGGER.error(msg, ex);
throw new RuntimeException(msg, ex);
@@ -719,33 +776,41 @@ public class KeycloakClient {
}
}
return true;
-
}
/**
- * Create protocol mapper representation in given client
+ * Configure Roles in keycloak Realm or Client
*
- * @param protocolMapperRepresentations
+ * @param roleRepresentations
* @param realmId
- * @param clientId
+ * @param clientScope if true add roles to client else to realm
* @return
*/
- public boolean addProtocolMapper(List<ProtocolMapperRepresentation> protocolMapperRepresentations,
- String realmId, String clientId) {
+ public boolean addRoles(List<RoleRepresentation> roleRepresentations, String realmId, String clientId, boolean clientScope) {
Keycloak client = null;
try {
client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
RealmResource realmResource = client.realm(realmId);
- ProtocolMappersResource resource = realmResource.clients().get(clientId).getProtocolMappers();
+ if (clientScope) {
+ ClientRepresentation representation = realmResource.clients().findByClientId(clientId).get(0);
- resource.createMapper(protocolMapperRepresentations);
+ for (RoleRepresentation roleRepresentation : roleRepresentations) {
+ realmResource.clients().get(representation.getId()).roles().create(roleRepresentation);
+ }
+
+ } else {
+ for (RoleRepresentation representation : roleRepresentations) {
+ realmResource.roles().create(representation);
+ }
+
+ }
} catch (Exception ex) {
- String msg = "Error occurred while adding protocol mappers in Keycloak Server, reason: " + ex.getMessage();
+ String msg = "Error occurred while adding roles in Keycloak Server, reason: " + ex.getMessage();
LOGGER.error(msg, ex);
throw new RuntimeException(msg, ex);
@@ -759,32 +824,27 @@ public class KeycloakClient {
/**
- * Configure Roles in keycloak Realm or Client
- * @param roleRepresentations
+ * Provides all Roles belongs to client, if clientId not present, provides all
+ * Roles related to Realm
+ *
* @param realmId
- * @param clientScope if true add roles to client else to realm
- * @return
+ * @param clientId
*/
- public boolean addRoles(List<RoleRepresentation> roleRepresentations, String realmId, String clientId, boolean clientScope) {
+ public List<RoleRepresentation> getAllRoles(String realmId, String clientId) {
Keycloak client = null;
try {
client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
RealmResource realmResource = client.realm(realmId);
- if (clientScope) {
+ if (clientId != null) {
- ClientResource resource = realmResource.clients().get(clientId);
+ ClientRepresentation representation = realmResource.clients().findByClientId(clientId).get(0);
- for (RoleRepresentation representation : roleRepresentations) {
- resource.roles().create(representation);
- }
+ return realmResource.clients().get(representation.getId()).roles().list();
} else {
-
- for (RoleRepresentation representation : roleRepresentations) {
- realmResource.roles().create(representation);
- }
+ return realmResource.roles().list();
}
@@ -798,9 +858,8 @@ public class KeycloakClient {
client.close();
}
}
- return true;
- }
+ }
private ResteasyClient getRestClient() {
return new ResteasyClientBuilder()
@@ -905,14 +964,42 @@ public class KeycloakClient {
// Searching for users by username returns also partial matches, so need to filter down to an exact match if it exists
List<UserRepresentation> userResourceList = client.realm(tenantId).users().search(
- username, null, null, null, null, null);
+ username.toLowerCase(), null, null, null, null, null);
for (UserRepresentation userRepresentation : userResourceList) {
- if (userRepresentation.getUsername().equals(username)) {
+ if (userRepresentation.getUsername().equals(username.toLowerCase())) {
+ RoleMappingResource resource = client.realm(tenantId).users().get(userRepresentation.getId()).roles();
+ MappingsRepresentation representation = resource.getAll();
+ if (representation != null && representation.getRealmMappings() != null) {
+ List<String> roleRepresentations = new ArrayList<>();
+ representation.getRealmMappings().forEach(t -> roleRepresentations.add(t.getName()));
+ userRepresentation.setRealmRoles(roleRepresentations);
+ }
+ if (representation != null && representation.getClientMappings() != null) {
+ Map<String, List<String>> roleRepresentations = new HashMap<>();
+ representation.getClientMappings().keySet().forEach(key -> {
+ if (representation.getClientMappings().get(key).getMappings() != null) {
+ List<String> roleList = new ArrayList<>();
+ representation.getClientMappings().get(key).getMappings().forEach(t -> roleList.add(t.getName()));
+ roleRepresentations.put(key, roleList);
+ }
+ });
+ userRepresentation.setClientRoles(roleRepresentations);
+ }
+
return userRepresentation;
}
}
return null;
}
+ private List<UserRepresentation> searchUsers(Keycloak client, String tenantId, String username,
+ String firstName, String lastName, String email, int offset, int limit) {
+
+ // Searching for users by username returns also partial matches, so need to filter down to an exact match if it exists
+ return client.realm(tenantId).users().search(
+ username.toLowerCase(), firstName, lastName, email, offset, limit);
+
+ }
+
}
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/UnauthorizedException.java
similarity index 71%
copy from custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java
copy to custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/UnauthorizedException.java
index 505b113..2a818f4 100644
--- a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/UnauthorizedException.java
@@ -17,23 +17,14 @@
* under the License.
*/
-package org.apache.custos.iam.utils;
+package org.apache.custos.federated.services.clients.keycloak;
/**
- * Includes operations associated with keycloak
+ * UnAuthorized Exception
*/
-public enum IAMOperations {
-
- SET_UP_TENANT,
- REGISTER_USER,
- ENABLE_USER,
- DELETE_USER,
- RESET_PASSWORD,
- UPDATE_USER_PROFILE,
- ADD_ROLE_TO_USER,
- DELETE_ROLE_FROM_USER,
- CONFIGURE_IDP,
- REGISTER_ENABLE_USERS
-
+public class UnauthorizedException extends Exception {
+ public UnauthorizedException(String msg, Throwable throwable) {
+ super(msg, throwable);
+ }
}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/KeycloakAuthClient.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/KeycloakAuthClient.java
index 93e8c45..821acff 100644
--- a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/KeycloakAuthClient.java
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/KeycloakAuthClient.java
@@ -222,15 +222,15 @@ public class KeycloakAuthClient {
String openIdConnectUrl = getOpenIDConfigurationUrl(tenantId);
JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, null));
- openIdConnectConfig.put("introspection_endpoint", introEndpoint);
- openIdConnectConfig.put("issuer", issuer);
- openIdConnectConfig.put("token_endpoint", tokenEndpoint);
- openIdConnectConfig.put("end_session_endpoint", sessionEndpoint);
- openIdConnectConfig.put("token_introspection_endpoint", introEndpoint);
+ // openIdConnectConfig.put("introspection_endpoint", introEndpoint);
+ // openIdConnectConfig.put("issuer", issuer);
+ openIdConnectConfig.put("custos_token_endpoint", tokenEndpoint);
+ // openIdConnectConfig.put("end_session_endpoint", sessionEndpoint);
+ // openIdConnectConfig.put("token_introspection_endpoint", introEndpoint);
openIdConnectConfig.put("userinfo_endpoint", userInfoEndpoint);
- openIdConnectConfig.put("jwks_uri", jwksUri);
+ // openIdConnectConfig.put("jwks_uri", jwksUri);
openIdConnectConfig.put("registration_endpoint", registrationEndpoint);
- openIdConnectConfig.remove("check_session_iframe");
+ // openIdConnectConfig.remove("check_session_iframe");
return openIdConnectConfig;
diff --git a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
index 6dedd58..14a487c 100644
--- a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
+++ b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
@@ -65,14 +65,50 @@ public abstract class AuthInterceptor implements IntegrationServiceInterceptor {
GetAllCredentialsResponse response = credentialStoreServiceClient.getAllCredentialFromToken(request);
+ return getAuthClaim(response);
+ }
+
+ public AuthClaim authorizeUsingUserToken(Metadata headers) {
+ String formattedToken = getToken(headers);
+
+ if (formattedToken == null) {
+ return null;
+ }
+
+ TokenRequest request = TokenRequest
+ .newBuilder()
+ .setToken(formattedToken)
+ .build();
+
+
+ GetAllCredentialsResponse response = credentialStoreServiceClient.getAllCredentialsFromJWTToken(request);
+
+ return getAuthClaim(response);
+ }
+
+
+ public String getToken(Metadata headers) {
+ String tokenWithBearer = headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER));
+ if (tokenWithBearer == null) {
+ tokenWithBearer = headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER));
+ }
+ if (tokenWithBearer == null) {
+ return null;
+ }
+ String prefix = "Bearer";
+ String token = tokenWithBearer.substring(prefix.length());
+ return token.trim();
+ }
+ private AuthClaim getAuthClaim(GetAllCredentialsResponse response) {
if (response == null || response.getSecretListCount() == 0) {
return null;
}
AuthClaim authClaim = new AuthClaim();
+ authClaim.setPerformedBy(response.getRequestedUserEmail());
response.getSecretListList().forEach(metadata -> {
if (metadata.getType() == Type.CUSTOS) {
@@ -109,15 +145,4 @@ public abstract class AuthInterceptor implements IntegrationServiceInterceptor {
}
- private String getToken(Metadata headers) {
- String tokenWithBearer = headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER));
- if (tokenWithBearer == null) {
- return null;
- }
- String prefix = "Bearer";
- String token = tokenWithBearer.substring(prefix.length());
- return token.trim();
- }
-
-
}
diff --git a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/model/AuthClaim.java b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/model/AuthClaim.java
index 9a6cba3..69753ff 100644
--- a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/model/AuthClaim.java
+++ b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/model/AuthClaim.java
@@ -40,6 +40,8 @@ public class AuthClaim {
private long custosSecretExpiredAt;
+ private String performedBy;
+
public AuthClaim() {
}
@@ -121,4 +123,12 @@ public class AuthClaim {
public void setCustosSecretExpiredAt(long custosSecretExpiredAt) {
this.custosSecretExpiredAt = custosSecretExpiredAt;
}
+
+ public String getPerformedBy() {
+ return performedBy;
+ }
+
+ public void setPerformedBy(String performedBy) {
+ this.performedBy = performedBy;
+ }
}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/identity-management-service.pb b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/identity-management-service.pb
index c0b7256..fef9ec8 100644
Binary files a/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/identity-management-service.pb and b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/identity-management-service.pb differ
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/identity-management-service.pb b/custos-integration-services/identity-management-service-parent/identity-management-service/identity-management-service.pb
deleted file mode 100644
index c0b7256..0000000
Binary files a/custos-integration-services/identity-management-service-parent/identity-management-service/identity-management-service.pb and /dev/null differ
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/IdentityManagementServiceInitializer.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/IdentityManagementServiceInitializer.java
index b3191cb..03ded39 100644
--- a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/IdentityManagementServiceInitializer.java
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/IdentityManagementServiceInitializer.java
@@ -78,10 +78,6 @@ public class IdentityManagementServiceInitializer {
return new ServiceInterceptor(integrationServiceInterceptors);
}
- @Bean
- @GRpcGlobalInterceptor
- ResponseInterceptor responseInterceptor() {
- return new ResponseInterceptor();
- }
+
}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AuthInterceptorImpl.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AuthInterceptorImpl.java
index bbae32e..3ede220 100644
--- a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AuthInterceptorImpl.java
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AuthInterceptorImpl.java
@@ -21,8 +21,9 @@ package org.apache.custos.identity.management.interceptors;
import io.grpc.Metadata;
import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.Credentials;
import org.apache.custos.identity.management.service.AuthenticationRequest;
-import org.apache.custos.identity.management.service.AuthorizationRequest;
+import org.apache.custos.identity.management.service.GetCredentialsRequest;
import org.apache.custos.identity.service.AuthToken;
import org.apache.custos.identity.service.Claim;
import org.apache.custos.identity.service.GetTokenRequest;
@@ -51,7 +52,7 @@ public class AuthInterceptorImpl extends AuthInterceptor {
@Override
public <ReqT> ReqT intercept(String method, Metadata headers, ReqT reqT) {
- if (method.equals("getOIDCConfiguration") || method.equals("authorize") || method.equals("authorizetest")) {
+ if (method.equals("getOIDCConfiguration") || method.equals("authorize")) {
return reqT;
}
@@ -110,7 +111,7 @@ public class AuthInterceptorImpl extends AuthInterceptor {
.build();
return (ReqT) request;
- } else if (method.equals("token")) {
+ } else if (method.equals("token")) {
GetTokenRequest request = ((GetTokenRequest) reqT).toBuilder()
.setTenantId(claim.getTenantId())
@@ -119,9 +120,23 @@ public class AuthInterceptorImpl extends AuthInterceptor {
.build();
return (ReqT) request;
+ } else if (method.equals("getCredentials")) {
+
+ Credentials credentials = Credentials.newBuilder()
+ .setCustosClientId(claim.getCustosId())
+ .setCustosClientSecret(claim.getCustosSecret())
+ .setCustosClientIdIssuedAt(claim.getCustosIdIssuedAt())
+ .setCustosClientSecretExpiredAt(claim.getCustosSecretExpiredAt())
+ .setCiLogonClientId(claim.getCiLogonId())
+ .setCiLogonClientSecret(claim.getCiLogonSecret())
+ .setIamClientId(claim.getIamAuthId())
+ .setIamClientSecret(claim.getIamAuthSecret())
+ .build();
+
+ return (ReqT) ((GetCredentialsRequest) reqT).toBuilder().setCredentials(credentials).build();
+
}
+
return reqT;
}
-
-
}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/InputValidator.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/InputValidator.java
index 1bdd41b..a811ecf 100644
--- a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/InputValidator.java
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/InputValidator.java
@@ -21,6 +21,7 @@ package org.apache.custos.identity.management.interceptors;
import io.grpc.Metadata;
import org.apache.custos.identity.management.service.AuthorizationRequest;
+import org.apache.custos.identity.management.service.GetCredentialsRequest;
import org.apache.custos.identity.management.utils.Constants;
import org.apache.custos.identity.service.GetOIDCConfiguration;
import org.apache.custos.integration.core.exceptions.MissingParameterException;
@@ -42,6 +43,9 @@ public class InputValidator implements IntegrationServiceInterceptor {
break;
case "getOIDCConfiguration":
validationGetOIDCConfiguration(headers, msg, method);
+
+ case "getCredentials":
+ validationGetCredentials(headers, msg, method);
default:
}
return msg;
@@ -93,4 +97,15 @@ public class InputValidator implements IntegrationServiceInterceptor {
return true;
}
+ private boolean validationGetCredentials(Metadata headers, Object body, String method) {
+ if (body instanceof GetCredentialsRequest) {
+ GetCredentialsRequest configuration = (GetCredentialsRequest) body;
+ if (configuration.getClientId() == null || configuration.getClientId().equals("")) {
+ throw new MissingParameterException("Client Id is not available", null);
+ }
+ }
+
+ return true;
+ }
+
}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/service/IdentityManagementService.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/service/IdentityManagementService.java
index 78b4402..075ede0 100644
--- a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/service/IdentityManagementService.java
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/service/IdentityManagementService.java
@@ -19,12 +19,12 @@
package org.apache.custos.identity.management.service;
-import com.google.protobuf.ByteString;
import com.google.protobuf.Struct;
import io.grpc.Status;
import io.grpc.stub.StreamObserver;
import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
import org.apache.custos.credential.store.service.CredentialMetadata;
+import org.apache.custos.credential.store.service.Credentials;
import org.apache.custos.credential.store.service.GetCredentialRequest;
import org.apache.custos.credential.store.service.Type;
import org.apache.custos.identity.client.IdentityClient;
@@ -236,6 +236,23 @@ public class IdentityManagementService extends IdentityManagementServiceGrpc.Ide
}
}
+ @Override
+ public void getCredentials(GetCredentialsRequest request, StreamObserver<Credentials> responseObserver) {
+ try {
+ LOGGER.debug("Request received to get Credentials for token " + request.getCredentials().getCustosClientId());
+
+ if (request.getClientId().equals(request.getCredentials().getCustosClientId())) {
+ responseObserver.onNext(request.getCredentials());
+ responseObserver.onCompleted();
+ } else {
+ //TODO : check for child tenant under super tenant
+ }
+ } catch (Exception ex) {
+ String msg = "Exception occurred while retrieving Credentials " + ex.getMessage();
+ LOGGER.error(msg);
+ responseObserver.onError(ex);
+ }
+ }
}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/proto/IdentityManagementService.proto b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/proto/IdentityManagementService.proto
index eda4639..b6e146c 100644
--- a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/proto/IdentityManagementService.proto
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/proto/IdentityManagementService.proto
@@ -27,6 +27,8 @@ import "google/api/annotations.proto";
import "IdentityService.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/any.proto";
+import "CredentialStoreService.proto";
+
@@ -48,6 +50,11 @@ message AuthorizationResponse {
string loginURI = 1;
}
+message GetCredentialsRequest {
+ string client_id = 1;
+ org.apache.custos.credential.store.service.Credentials credentials = 2;
+}
+
service IdentityManagementService {
@@ -97,6 +104,14 @@ service IdentityManagementService {
};
}
+ rpc getCredentials (GetCredentialsRequest) returns (org.apache.custos.credential.store.service.Credentials) {
+ option (google.api.http) = {
+ get: "/identity-management/v1.0.0/credentials"
+ };
+ }
+
+
+
rpc getOIDCConfiguration(org.apache.custos.identity.service.GetOIDCConfiguration) returns (google.protobuf.Struct) {
option (google.api.http) = {
get: "/identity-management/v1.0.0/.well-known/openid-configuration"
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/tenant-management-service.pb b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/tenant-management-service.pb
index b17bd61..2e8ea1c 100644
Binary files a/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/tenant-management-service.pb and b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/tenant-management-service.pb differ
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/AuthInterceptorImpl.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/AuthInterceptorImpl.java
index c877692..c0e7ecd 100644
--- a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/AuthInterceptorImpl.java
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/AuthInterceptorImpl.java
@@ -21,6 +21,8 @@ package org.apache.custos.tenant.management.interceptors;
import io.grpc.Metadata;
import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.iam.service.AddProtocolMapperRequest;
+import org.apache.custos.iam.service.AddRolesRequest;
import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
import org.apache.custos.integration.services.commons.model.AuthClaim;
@@ -108,6 +110,28 @@ public class AuthInterceptorImpl extends AuthInterceptor {
return (ReqT) tenantRequest.toBuilder()
.setTenantId(claim.getTenantId()).setCredentials(credentials).build();
+ } else if (method.equals("addTenantRoles")) {
+
+ AuthClaim claim = authorize(headers);
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ AddRolesRequest rolesRequest = ((AddRolesRequest) msg);
+
+ return (ReqT) rolesRequest.toBuilder()
+ .setTenantId(claim.getTenantId()).setClientId(claim.getCustosId()).build();
+ } else if (method.equals("addProtocolMapper")) {
+
+ AuthClaim claim = authorize(headers);
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ AddProtocolMapperRequest rolesRequest = ((AddProtocolMapperRequest) msg);
+
+ return (ReqT) rolesRequest.toBuilder()
+ .setTenantId(claim.getTenantId()).setClientId(claim.getCustosId()).build();
}
return msg;
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/InputValidator.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/InputValidator.java
index 7fef7e4..ccf4018 100644
--- a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/InputValidator.java
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/InputValidator.java
@@ -21,6 +21,8 @@ package org.apache.custos.tenant.management.interceptors;
import io.grpc.Metadata;
+import org.apache.custos.iam.service.AddRolesRequest;
+import org.apache.custos.iam.service.RoleRepresentation;
import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
import org.apache.custos.tenant.management.exceptions.MissingParameterException;
import org.apache.custos.tenant.management.service.DeleteTenantRequest;
@@ -31,6 +33,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
+import java.util.List;
+
/**
* This class validates the request input parameters
*/
@@ -61,6 +65,10 @@ public class InputValidator implements IntegrationServiceInterceptor {
case "deleteTenant":
validateDeleteTenant(headers, body, methodName);
break;
+ case "addTenantRoles":
+ validateAddRoleToTenant(headers, body, methodName);
+
+
default:
}
}
@@ -113,8 +121,34 @@ public class InputValidator implements IntegrationServiceInterceptor {
return true;
}
+ private boolean validateAddRoleToTenant(Metadata headers, Object body, String method) {
+ validationAuthorizationHeader(headers);
+
+
+ AddRolesRequest addRolesRequest = ((AddRolesRequest) body);
+
+ List<RoleRepresentation> rolesList = addRolesRequest.getRolesList();
+
+ if (rolesList == null || rolesList.isEmpty()) {
+ throw new MissingParameterException("Roles should not be null", null);
+ }
+
+ for (RoleRepresentation roleRepresentation : rolesList) {
+ if (roleRepresentation.getName() == null || roleRepresentation.getName().trim().equals("")) {
+ throw new MissingParameterException("Roles name should not be null", null);
+ }
+ if (roleRepresentation.getDescription() == null || roleRepresentation.getDescription().trim().equals("")) {
+ throw new MissingParameterException("Description should not be null", null);
+ }
+ }
+
+
+ return true;
+ }
+
private boolean validationAuthorizationHeader(Metadata headers) {
- if (headers.get(Metadata.Key.of(Constants.AUTHORIZATION_HEADER, Metadata.ASCII_STRING_MARSHALLER)) == null) {
+ if (headers.get(Metadata.Key.of(Constants.AUTHORIZATION_HEADER, Metadata.ASCII_STRING_MARSHALLER)) == null
+ || headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)) == null) {
throw new MissingParameterException("authorization header not available", null);
}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/service/TenantManagementService.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/service/TenantManagementService.java
index 16e2e49..a0e9962 100644
--- a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/service/TenantManagementService.java
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/service/TenantManagementService.java
@@ -27,6 +27,10 @@ import org.apache.custos.credential.store.service.*;
import org.apache.custos.federated.authentication.client.FederatedAuthenticationClient;
import org.apache.custos.federated.authentication.service.DeleteClientRequest;
import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.AddProtocolMapperRequest;
+import org.apache.custos.iam.service.AddRolesRequest;
+import org.apache.custos.iam.service.AllRoles;
+import org.apache.custos.iam.service.OperationStatus;
import org.apache.custos.integration.core.ServiceCallback;
import org.apache.custos.integration.core.ServiceChain;
import org.apache.custos.integration.core.ServiceException;
@@ -123,7 +127,7 @@ public class TenantManagementService extends TenantManagementServiceImplBase {
} catch (Exception ex) {
String msg = "Error occurred at createTenant " + ex.getMessage();
- LOGGER.error(msg,ex);
+ LOGGER.error(msg, ex);
responseObserver.onError(Status.INVALID_ARGUMENT.withDescription(msg).asRuntimeException());
}
}
@@ -342,6 +346,38 @@ public class TenantManagementService extends TenantManagementServiceImplBase {
}
}
+
+ @Override
+ public void addTenantRoles(AddRolesRequest request, StreamObserver<AllRoles> responseObserver) {
+ try {
+ AllRoles allRoles = iamAdminServiceClient.addRolesToTenant(request);
+
+ responseObserver.onNext(allRoles);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at addTenantRoles " + ex.getMessage();
+ LOGGER.error(msg);
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+
+ @Override
+ public void addProtocolMapper(AddProtocolMapperRequest request, StreamObserver<OperationStatus> responseObserver) {
+ try {
+ OperationStatus allRoles = iamAdminServiceClient.addProtocolMapper(request);
+
+ responseObserver.onNext(allRoles);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at addProtocolMapper " + ex.getMessage();
+ LOGGER.error(msg);
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
@Override
public void getAllTenants(Empty request, StreamObserver<GetAllTenantsResponse> responseObserver) {
GetAllTenantsResponse response = profileClient.getAllTenants();
@@ -453,6 +489,7 @@ public class TenantManagementService extends TenantManagementServiceImplBase {
}
}
+
@Override
public void getTenantStatusUpdateAuditTrail(GetAuditTrailRequest request, StreamObserver<GetStatusUpdateAuditTrailResponse> responseObserver) {
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/proto/TenantManagementService.proto b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/proto/TenantManagementService.proto
index b2baa29..870f757 100644
--- a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/proto/TenantManagementService.proto
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/proto/TenantManagementService.proto
@@ -27,6 +27,7 @@ import "google/api/annotations.proto";
import "TenantProfileService.proto";
import "google/rpc/error_details.proto";
import "google/protobuf/empty.proto";
+import "IamAdminService.proto";
message CreateTenantResponse {
@@ -108,8 +109,6 @@ message DeleteTenantRequest {
}
-
-
message GetCredentialsRequest {
int64 tenantId = 1;
}
@@ -149,6 +148,18 @@ service TenantManagementService {
};
}
+ rpc addTenantRoles (org.apache.custos.iam.service.AddRolesRequest) returns (org.apache.custos.iam.service.AllRoles) {
+ option (google.api.http) = {
+ post: "/tenant-management/v1.0.0/roles"
+ };
+ }
+
+ rpc addProtocolMapper (org.apache.custos.iam.service.AddProtocolMapperRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+ option (google.api.http) = {
+ post: "/tenant-management/v1.0.0/protocol/mapper"
+ };
+ }
+
rpc getCredentials (GetCredentialsRequest) returns (GetCredentialsResponse) {
option (google.api.http) = {
get: "/tenant-management/v1.0.0/credentials"
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 f37b21d..946e614 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/UserManagementServiceInitializer.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/UserManagementServiceInitializer.java
index 19d497d..d5871de 100644
--- a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/UserManagementServiceInitializer.java
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/UserManagementServiceInitializer.java
@@ -25,15 +25,14 @@ import io.grpc.ClientInterceptor;
import io.grpc.ServerInterceptor;
import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
-import org.apache.custos.user.management.interceptors.AuthInterceptorImpl;
+import org.apache.custos.user.management.interceptors.ClientAuthInterceptorImpl;
+import org.apache.custos.user.management.interceptors.UserAuthInterceptorImpl;
import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
-import java.util.HashSet;
-import java.util.Set;
import java.util.Stack;
@SpringBootApplication
@@ -63,9 +62,10 @@ public class UserManagementServiceInitializer {
}
@Bean
- public Stack<IntegrationServiceInterceptor> getInterceptorSet(AuthInterceptorImpl authInterceptor) {
+ public Stack<IntegrationServiceInterceptor> getInterceptorSet(ClientAuthInterceptorImpl authInterceptor, UserAuthInterceptorImpl userAuthInterceptor) {
Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
interceptors.add(authInterceptor);
+ interceptors.add(userAuthInterceptor);
return interceptors;
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/AuthInterceptorImpl.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/ClientAuthInterceptorImpl.java
similarity index 50%
rename from custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/AuthInterceptorImpl.java
rename to custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/ClientAuthInterceptorImpl.java
index e982c23..5e347d0 100644
--- a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/AuthInterceptorImpl.java
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/ClientAuthInterceptorImpl.java
@@ -22,12 +22,14 @@ package org.apache.custos.user.management.interceptors;
import io.grpc.Metadata;
import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
import org.apache.custos.iam.service.RegisterUserRequest;
-import org.apache.custos.iam.service.RegisterUsersRequest;
+import org.apache.custos.iam.service.ResetUserPassword;
+import org.apache.custos.iam.service.UserSearchRequest;
import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
import org.apache.custos.integration.services.commons.model.AuthClaim;
import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
-import org.apache.custos.user.management.service.*;
+import org.apache.custos.user.management.service.DeleteProfileRequest;
+import org.apache.custos.user.management.service.UserProfileRequest;
import org.apache.custos.user.profile.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,44 +37,48 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
- * Responsible for managing auth flow
+ * Responsible for validate confidential client specific authorization.
+ * Methods which authenticates based only on client are implemented here.
*/
@Component
-public class AuthInterceptorImpl extends AuthInterceptor {
- private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptorImpl.class);
+public class ClientAuthInterceptorImpl extends AuthInterceptor {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
@Autowired
- public AuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient) {
+ public ClientAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient) {
super(credentialStoreServiceClient, tenantProfileClient);
}
@Override
public <ReqT> ReqT intercept(String method, Metadata headers, ReqT reqT) {
- LOGGER.info("In authinterceptorImpl");
- AuthClaim claim = authorize(headers);
- if (claim == null) {
- throw new NotAuthorizedException("Request is not authorized", null);
- }
-
- String oauthId = claim.getIamAuthId();
- String oauthSec = claim.getIamAuthSecret();
-
- long tenantId = claim.getTenantId();
+ if (method.equals("deleteUserProfile")) {
+ AuthClaim claim = authorize(headers);
- if (method.equals("updateUserProfile")) {
- UserProfile pr = ((UserProfileRequest) reqT).getUserProfile().toBuilder().setTenantId(tenantId).build();
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
- return (ReqT) ((UserProfileRequest) reqT).toBuilder()
- .setIamClientId(oauthId).setUserProfile(pr).setIamClientSecret(oauthSec).build();
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
- } else if (method.equals("deleteUserProfile")) {
+ long tenantId = claim.getTenantId();
DeleteUserProfileRequest pr = ((DeleteProfileRequest) reqT).getDeleteRequest().toBuilder().setTenantId(tenantId).build();
return (ReqT) ((DeleteProfileRequest) reqT).toBuilder()
.setIamClientId(oauthId).setDeleteRequest(pr).setIamClientSecret(oauthSec).build();
} else if (method.equals("registerUser")) {
+ AuthClaim claim = authorize(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
+
+ long tenantId = claim.getTenantId();
org.apache.custos.iam.service.RegisterUserRequest registerUserRequest =
((RegisterUserRequest) reqT).toBuilder()
.setTenantId(tenantId)
@@ -81,80 +87,95 @@ public class AuthInterceptorImpl extends AuthInterceptor {
.build();
return (ReqT) registerUserRequest;
- } else if (method.equals("registerAndEnableUsers")) {
- org.apache.custos.iam.service.RegisterUsersRequest registerUserRequest =
- ((RegisterUsersRequest) reqT).toBuilder()
- .setTenantId(tenantId)
- .setClientId(oauthId)
- .setClientSecret(oauthSec)
- .build();
- return (ReqT) registerUserRequest;
+ } else if (method.equals("enableUser") || method.equals("isUserEnabled") || method.equals("isUsernameAvailable")) {
+ AuthClaim claim = authorize(headers);
- } else if (method.equals("enableUser") || method.equals("deleteUser")) {
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
- UserIdentificationRequest info = ((UserIdentificationRequest) reqT)
- .toBuilder()
- .setInfo(((UserIdentificationRequest) reqT).getInfo().toBuilder().setTenantId(tenantId).build())
- .setIamClientId(oauthId)
- .setIamClientSecret(oauthSec)
- .build();
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
- return (ReqT) info;
- } else if (method.equals("getUser") || method.equals("isUserEnabled")) {
-
- GetUserRequest info = ((GetUserRequest) reqT)
+ long tenantId = claim.getTenantId();
+ UserSearchRequest info = ((UserSearchRequest) reqT)
.toBuilder()
- .setIamClientId(oauthId)
- .setIamClientSecret(oauthSec)
+ .setClientId(oauthId)
+ .setClientSec(oauthSec)
.setTenantId(tenantId)
.build();
return (ReqT) info;
+ } else if (method.equals("getUserProfile")) {
+ AuthClaim claim = authorize(headers);
- } else if (method.equals("getUsers")) {
-
- GetUsersRequest request = ((GetUsersRequest) reqT)
- .toBuilder()
- .setIamClientId(oauthId)
- .setIamClientSecret(oauthSec)
- .setTenantId(tenantId).build();
-
-
- return (ReqT) request;
- } else if (method.equals("addRoleToUser") || method.equals("deleteRoleFromUser")) {
-
- RoleOperationRequest operationRequest = ((RoleOperationRequest) reqT)
- .toBuilder()
- .setRole(((RoleOperationRequest) reqT)
- .getRole().toBuilder().setTenantId(tenantId).build())
- .build();
-
- return (ReqT) operationRequest;
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
- } else if (method.equals("getUserProfile")) {
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
+ long tenantId = claim.getTenantId();
GetUserProfileRequest request = ((GetUserProfileRequest) reqT)
.toBuilder()
.setTenantId(tenantId).build();
return (ReqT) request;
} else if (method.equals("getAllUserProfilesInTenant")) {
+ AuthClaim claim = authorize(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
+ long tenantId = claim.getTenantId();
GetAllUserProfilesRequest request = ((GetAllUserProfilesRequest) reqT)
.toBuilder().setTenantId(tenantId).build();
return (ReqT) request;
} else if (method.equals("getUserProfileAuditTrails")) {
+ AuthClaim claim = authorize(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
+ long tenantId = claim.getTenantId();
GetUpdateAuditTrailRequest request = ((GetUpdateAuditTrailRequest) reqT)
.toBuilder()
.setTenantId(tenantId)
.build();
return (ReqT) request;
- }
+ } else if (method.equals("resetPassword")) {
+ AuthClaim claim = authorize(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
+
+ long tenantId = claim.getTenantId();
+
+ ResetUserPassword request = ((ResetUserPassword) reqT)
+ .toBuilder()
+ .setClientId(oauthId)
+ .setClientSec(oauthSec)
+ .setTenantId(tenantId)
+ .build();
+ return (ReqT) request;
+ }
return reqT;
}
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
new file mode 100644
index 0000000..3bdb87e
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/UserAuthInterceptorImpl.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.custos.user.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.user.management.service.UserProfileRequest;
+import org.apache.custos.user.profile.service.UserProfile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate user specific authorization
+ * Methods authenticates users access tokens are implemented here
+ */
+@Component
+public class UserAuthInterceptorImpl extends AuthInterceptor {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+ @Autowired
+ public UserAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient) {
+ super(credentialStoreServiceClient, tenantProfileClient);
+ }
+
+ @Override
+ public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+
+ if (method.equals("addUserAttributes")) {
+ String token = getToken(headers);
+ AuthClaim claim = authorizeUsingUserToken(headers);
+
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+
+ long tenantId = claim.getTenantId();
+
+
+ return (ReqT) ((AddUserAttributesRequest) msg).toBuilder()
+ .setClientId(oauthId)
+ .setTenantId(tenantId)
+ .setAccessToken(token)
+ .setPerformedBy(claim.getPerformedBy())
+ .build();
+
+ } else if (method.equals("addRolesToUsers")) {
+ String token = getToken(headers);
+ AuthClaim claim = authorizeUsingUserToken(headers);
+
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+
+ long tenantId = claim.getTenantId();
+
+
+ return (ReqT) ((AddUserRolesRequest) msg).toBuilder()
+ .setClientId(oauthId)
+ .setTenantId(tenantId)
+ .setAccessToken(token)
+ .setPerformedBy(claim.getPerformedBy())
+ .build();
+
+ } else if (method.equals("registerAndEnableUsers")) {
+ String token = getToken(headers);
+ AuthClaim claim = authorizeUsingUserToken(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
+
+ long tenantId = claim.getTenantId();
+ org.apache.custos.iam.service.RegisterUsersRequest registerUserRequest =
+ ((RegisterUsersRequest) msg).toBuilder()
+ .setTenantId(tenantId)
+ .setClientId(oauthId)
+ .setAccessToken(token)
+ .setPerformedBy(claim.getPerformedBy())
+ .build();
+ return (ReqT) registerUserRequest;
+ } else if (method.equals("getUser")) {
+ String token = getToken(headers);
+ AuthClaim claim = authorizeUsingUserToken(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+ long tenantId = claim.getTenantId();
+ UserSearchRequest request = ((UserSearchRequest) msg)
+ .toBuilder()
+ .setAccessToken(token)
+ .setClientId(oauthId)
+ .setTenantId(tenantId)
+ .build();
+ return (ReqT) request;
+
+ } else if (method.equals("findUsers")) {
+ String token = getToken(headers);
+ AuthClaim claim = authorizeUsingUserToken(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+ String oauthId = claim.getIamAuthId();
+ long tenantId = claim.getTenantId();
+
+ FindUsersRequest request = ((FindUsersRequest) msg)
+ .toBuilder()
+ .setClientId(oauthId)
+ .setAccessToken(token)
+ .setTenantId(tenantId).build();
+
+
+ return (ReqT) request;
+ } else if (method.equals("deleteUserRoles")) {
+ String token = getToken(headers);
+ AuthClaim claim = authorizeUsingUserToken(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
+
+ long tenantId = claim.getTenantId();
+ DeleteUserRolesRequest operationRequest = ((DeleteUserRolesRequest) msg)
+ .toBuilder()
+ .setClientId(oauthId)
+ .setAccessToken(token)
+ .setTenantId(tenantId)
+ .setPerformedBy(claim.getPerformedBy())
+ .build();
+
+ return (ReqT) operationRequest;
+
+ }
+ if (method.equals("updateUserProfile")) {
+ String token = getToken(headers);
+ AuthClaim claim = authorizeUsingUserToken(headers);
+
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized", null);
+ }
+
+ String oauthId = claim.getIamAuthId();
+ String oauthSec = claim.getIamAuthSecret();
+
+ long tenantId = claim.getTenantId();
+ UserProfile profile = ((UserProfileRequest) msg).getUserProfile().toBuilder().setUpdatedBy(claim.getPerformedBy()).build();
+
+ return (ReqT) ((UserProfileRequest) msg).toBuilder()
+ .setAccessToken(token)
+ .setTenantId(tenantId)
+ .setClientId(oauthId)
+ .setUserProfile(profile)
+ .build();
+
+ } else
+
+ return msg;
+ }
+
+
+}
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 2980cbd..fb20eab 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
@@ -95,64 +95,76 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
@Override
public void registerAndEnableUsers(RegisterUsersRequest request, StreamObserver<RegisterUsersResponse> responseObserver) {
try {
- GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
- .newBuilder()
- .setClientId(request.getClientId())
- .setClientSecret(request.getClientSecret())
- .setTenantId(request.getTenantId())
- .build();
- AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
- if (token != null && token.getAccessToken() != null) {
+ RegisterUsersResponse registerUsersResponse = iamAdminServiceClient.
+ registerAndEnableUsers(request);
- RegisterUsersResponse registerUsersResponse = iamAdminServiceClient.registerAndEnableUsers(request.toBuilder().setAccessToken(token.getAccessToken()).build());
- responseObserver.onNext(registerUsersResponse);
- responseObserver.onCompleted();
+ responseObserver.onNext(registerUsersResponse);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at registerAndEnableUsers " + ex.getMessage();
+ LOGGER.error(msg);
+ if (ex.getMessage().contains("UNAUTHENTICATED")) {
+ responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
} else {
- LOGGER.error("Cannot find service token");
- responseObserver.onError(Status.CANCELLED.
- withDescription("Cannot find service token").asRuntimeException());
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
}
+ }
+
+ }
+
+
+ @Override
+ public void addUserAttributes(AddUserAttributesRequest request, StreamObserver<OperationStatus> responseObserver) {
+ try {
+
+
+ OperationStatus status = iamAdminServiceClient.addUserAttributes(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
} catch (Exception ex) {
- String msg = "Error occurred at registerUser " + ex.getMessage();
+ String msg = "Error occurred at addUserAttributes " + ex.getMessage();
LOGGER.error(msg);
- responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ if (ex.getMessage().contains("UNAUTHENTICATED")) {
+ responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
}
-
}
@Override
- public void enableUser(UserIdentificationRequest request, StreamObserver<User> responseObserver) {
+ public void enableUser(UserSearchRequest request, StreamObserver<UserRepresentation> responseObserver) {
try {
+
GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
.newBuilder()
- .setClientId(request.getIamClientId())
- .setClientSecret(request.getIamClientSecret())
- .setTenantId(request.getInfo().getTenantId())
+ .setClientId(request.getClientId())
+ .setClientSecret(request.getClientSec())
+ .setTenantId(request.getTenantId())
.build();
AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
if (token != null && token.getAccessToken() != null) {
- UserAccessInfo info = request.getInfo()
- .toBuilder()
- .setAccessToken(token.getAccessToken())
- .build();
+ request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
- User user = iamAdminServiceClient.enableUser(info);
+ UserRepresentation user = iamAdminServiceClient.enableUser(request);
if (user != null) {
UserProfile profile = UserProfile.newBuilder()
.setFirstName(user.getFirstName())
.setLastName(user.getLastName())
- .setEmailAddress(user.getEmail())
+ .setEmail(user.getEmail())
.setStatus(UserStatus.valueOf(user.getState()))
- .setTenantId(request.getInfo().getTenantId())
+ .setTenantId(request.getTenantId())
.setUsername(user.getUsername())
.build();
@@ -175,15 +187,13 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
}
-
} else {
-
- String msg = "Cannot find service account";
- LOGGER.error(msg);
- responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
-
+ LOGGER.error("Cannot find service token");
+ responseObserver.onError(Status.CANCELLED.
+ withDescription("Cannot find service token").asRuntimeException());
}
+
} catch (Exception ex) {
String msg = "Error occurred at enableUser " + ex.getMessage();
LOGGER.error(msg);
@@ -192,68 +202,46 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
}
@Override
- public void deleteUser(UserIdentificationRequest request, StreamObserver<CheckingResponse> responseObserver) {
+ public void deleteUser(UserSearchRequest request, StreamObserver<CheckingResponse> responseObserver) {
try {
- GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+ GetUserProfileRequest req = GetUserProfileRequest
.newBuilder()
- .setClientId(request.getIamClientId())
- .setClientSecret(request.getIamClientSecret())
- .setTenantId(request.getInfo().getTenantId())
+ .setTenantId(request.getTenantId())
+ .setUsername(request.getUser().getUsername())
.build();
- AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
- if (token != null && token.getAccessToken() != null) {
+ UserProfile profile = userProfileClient.getUser(req);
- UserAccessInfo info = request.getInfo()
- .toBuilder()
- .setAccessToken(token.getAccessToken())
- .build();
+ if (profile != null) {
- GetUserProfileRequest req = GetUserProfileRequest
+ DeleteUserProfileRequest deleteUserProfileRequest = DeleteUserProfileRequest
.newBuilder()
- .setTenantId(request.getInfo().getTenantId())
- .setUsername(request.getInfo().getUsername())
+ .setTenantId(request.getTenantId())
+ .setUsername(request.getUser().getUsername())
.build();
+ UserProfile deletedProfile = userProfileClient.deleteUser(deleteUserProfileRequest);
- UserProfile profile = userProfileClient.getUser(req);
-
- if (profile != null) {
-
- DeleteUserProfileRequest deleteUserProfileRequest = DeleteUserProfileRequest
- .newBuilder()
- .setTenantId(request.getInfo().getTenantId())
- .setUsername(request.getInfo().getUsername())
- .build();
- UserProfile deletedProfile = userProfileClient.deleteUser(deleteUserProfileRequest);
+ if (deletedProfile != null) {
- if (deletedProfile != null) {
-
- CheckingResponse response = iamAdminServiceClient.deleteUser(info);
-
- responseObserver.onNext(response);
- responseObserver.onCompleted();
+ CheckingResponse response = iamAdminServiceClient.deleteUser(request);
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
- } else {
- String msg = "User profile deletion failed for " + request.getInfo().getUsername();
- LOGGER.error(msg);
- responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
- }
} else {
- CheckingResponse response = iamAdminServiceClient.deleteUser(info);
-
- responseObserver.onNext(response);
- responseObserver.onCompleted();
+ String msg = "User profile deletion failed for " + request.getUser().getUsername();
+ LOGGER.error(msg);
+ responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
}
-
} else {
- String msg = "Cannot find service account";
- LOGGER.error(msg);
- responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
+ CheckingResponse response = iamAdminServiceClient.deleteUser(request);
+
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
}
} catch (Exception ex) {
@@ -264,132 +252,70 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
}
@Override
- public void getUser(GetUserRequest request, StreamObserver<User> responseObserver) {
+ public void getUser(UserSearchRequest request, StreamObserver<UserRepresentation> responseObserver) {
try {
- GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
- .newBuilder()
- .setClientId(request.getIamClientId())
- .setClientSecret(request.getIamClientSecret())
- .setTenantId(request.getTenantId())
- .build();
- AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
-
- if (token != null && token.getAccessToken() != null) {
-
- UserAccessInfo info = UserAccessInfo.newBuilder()
- .setAccessToken(token.getAccessToken())
- .setUsername(request.getUsername())
- .setTenantId(request.getTenantId())
- .build();
-
- User user = iamAdminServiceClient.getUser(info);
-
- responseObserver.onNext(user);
- responseObserver.onCompleted();
-
-
- } else {
-
- String msg = "Cannot find service account";
- LOGGER.error(msg);
- responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
- }
+ UserRepresentation user = iamAdminServiceClient.getUser(request);
+ responseObserver.onNext(user);
+ responseObserver.onCompleted();
} catch (Exception ex) {
String msg = "Error occurred at getUser " + ex.getMessage();
LOGGER.error(msg);
- responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ if (ex.getMessage().contains("UNAUTHENTICATED")) {
+ responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
}
}
@Override
- public void getUsers(GetUsersRequest request, StreamObserver<GetUsersResponse> responseObserver) {
+ public void findUsers(FindUsersRequest request, StreamObserver<FindUsersResponse> responseObserver) {
try {
- GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
- .newBuilder()
- .setClientId(request.getIamClientId())
- .setClientSecret(request.getIamClientSecret())
- .setTenantId(request.getTenantId())
- .build();
- AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
-
- if (token != null && token.getAccessToken() != null) {
-
-
- UserAccessInfo info = UserAccessInfo.newBuilder()
- .setUsername(request.getUsername())
- .setTenantId(request.getTenantId())
- .setAccessToken(token.getAccessToken())
- .build();
-
- org.apache.custos.iam.service.GetUsersRequest getUsersRequest =
-
- org.apache.custos.iam.service.GetUsersRequest
- .newBuilder()
- .setLimit(request.getLimit())
- .setOffset(request.getOffset())
- .setSearch(request.getSearch())
- .setInfo(info)
- .build();
-
- GetUsersResponse user = iamAdminServiceClient.getUsers(getUsersRequest);
- responseObserver.onNext(user);
- responseObserver.onCompleted();
- } else {
-
- String msg = "Cannot find service account";
- LOGGER.error(msg);
- responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
- }
+ FindUsersResponse user = iamAdminServiceClient.getUsers(request);
+ responseObserver.onNext(user);
+ responseObserver.onCompleted();
} catch (Exception ex) {
String msg = "Error occurred at getUsers " + ex.getMessage();
LOGGER.error(msg);
- responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ if (ex.getMessage().contains("UNAUTHENTICATED")) {
+ responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
}
}
@Override
- public void resetPassword(ResetPasswordRequest request, StreamObserver<CheckingResponse> responseObserver) {
+ public void resetPassword(ResetUserPassword request, StreamObserver<CheckingResponse> responseObserver) {
try {
GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
.newBuilder()
- .setClientId(request.getPasswordMetadata().getIamClientId())
- .setClientSecret(request.getPasswordMetadata().getIamClientSecret())
- .setTenantId(request.getPasswordMetadata().getTenantId())
+ .setClientId(request.getClientId())
+ .setClientSecret(request.getClientSec())
+ .setTenantId(request.getTenantId())
.build();
AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
if (token != null && token.getAccessToken() != null) {
- UserAccessInfo info = UserAccessInfo.newBuilder()
- .setUsername(request.getPasswordMetadata().getUsername())
- .setTenantId(request.getPasswordMetadata().getTenantId())
- .setAccessToken(token.getAccessToken())
- .build();
+ request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
- ResetUserPassword resetUserPassword = ResetUserPassword
- .newBuilder()
- .setPassword(request.getPasswordMetadata().getPassword())
- .setInfo(info)
- .build();
-
- CheckingResponse response = iamAdminServiceClient.resetPassword(resetUserPassword);
+ CheckingResponse response = iamAdminServiceClient.resetPassword(request);
responseObserver.onNext(response);
responseObserver.onCompleted();
-
} else {
- String msg = "Cannot find service account";
- LOGGER.error(msg);
- responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
+ LOGGER.error("Cannot find service token");
+ responseObserver.onError(Status.CANCELLED.
+ withDescription("Cannot find service token").asRuntimeException());
}
-
} catch (Exception ex) {
String msg = "Error occurred at resetPassword " + ex.getMessage();
LOGGER.error(msg);
@@ -398,120 +324,143 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
}
@Override
- public void addRoleToUser(RoleOperationRequest request, StreamObserver<CheckingResponse> responseObserver) {
+ public void addRolesToUsers(AddUserRolesRequest request, StreamObserver<OperationStatus> responseObserver) {
try {
- CheckingResponse response = iamAdminServiceClient.addRoleToUser(request.getRole());
+
+ OperationStatus response = iamAdminServiceClient.addRolesToUsers(request);
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (Exception ex) {
- String msg = "Error occurred at addRoleToUser " + ex.getMessage();
+ String msg = "Error occurred at addRolesToUsers " + ex.getMessage();
LOGGER.error(msg);
- responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ if (ex.getMessage().contains("UNAUTHENTICATED")) {
+ responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
}
}
@Override
- public void deleteRoleFromUser(RoleOperationRequest request, StreamObserver<CheckingResponse> responseObserver) {
+ public void deleteUserRoles(DeleteUserRolesRequest
+ request, StreamObserver<CheckingResponse> responseObserver) {
try {
- CheckingResponse response = iamAdminServiceClient.deleteRoleFromUser(request.getRole());
+ CheckingResponse response = iamAdminServiceClient.deleteUserRoles(request);
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (Exception ex) {
String msg = "Error occurred at deleteRoleFromUser " + ex.getMessage();
LOGGER.error(msg);
- responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ if (ex.getMessage().contains("UNAUTHENTICATED")) {
+ responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+ } else {
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
}
}
@Override
- public void isUserEnabled(GetUserRequest request, StreamObserver<CheckingResponse> responseObserver) {
+ public void isUserEnabled(UserSearchRequest request, StreamObserver<CheckingResponse> responseObserver) {
try {
-
-
GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
.newBuilder()
- .setClientId(request.getIamClientId())
- .setClientSecret(request.getIamClientSecret())
+ .setClientId(request.getClientId())
+ .setClientSecret(request.getClientSec())
.setTenantId(request.getTenantId())
.build();
AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
if (token != null && token.getAccessToken() != null) {
+ request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+ CheckingResponse response = iamAdminServiceClient.isUserEnabled(request);
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
+ } else {
- UserAccessInfo info = UserAccessInfo.newBuilder()
- .setAccessToken(token.getAccessToken())
- .setUsername(request.getUsername())
- .setTenantId(request.getTenantId())
- .build();
+ LOGGER.error("Cannot find service token");
+ responseObserver.onError(Status.CANCELLED.
+ withDescription("Cannot find service token").asRuntimeException());
+ }
- CheckingResponse response = iamAdminServiceClient.isUserEnabled(info);
+ } catch (Exception ex) {
+ String msg = "Error occurred at isUserEnabled " + ex.getMessage();
+ LOGGER.error(msg);
+ responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
- responseObserver.onNext(response);
- responseObserver.onCompleted();
+ @Override
+ public void isUsernameAvailable(UserSearchRequest request, StreamObserver<CheckingResponse> responseObserver) {
+ try {
+ GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+ .newBuilder()
+ .setClientId(request.getClientId())
+ .setClientSecret(request.getClientSec())
+ .setTenantId(request.getTenantId())
+ .build();
+ AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+ if (token != null && token.getAccessToken() != null) {
+ request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+ CheckingResponse response = iamAdminServiceClient.isUsernameAvailable(request);
+
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
} else {
- String msg = "Cannot find service account";
- LOGGER.error(msg);
- responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
+ LOGGER.error("Cannot find service token");
+ responseObserver.onError(Status.CANCELLED.
+ withDescription("Cannot find service token").asRuntimeException());
}
+
} catch (Exception ex) {
- String msg = "Error occurred at isUserEnabled " + ex.getMessage();
+ String msg = "Error occurred at isUsernameAvailable " + ex.getMessage();
LOGGER.error(msg);
responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
}
}
+ //TODO: this is not updated
@Override
public void updateUserProfile(UserProfileRequest request, StreamObserver<UserProfile> responseObserver) {
try {
LOGGER.debug("Request received to updateUserProfile " + request.getUserProfile().getUsername() +
" at" + request.getUserProfile().getTenantId());
- GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
- .newBuilder()
- .setClientId(request.getIamClientId())
- .setClientSecret(request.getIamClientSecret())
- .setTenantId(request.getUserProfile().getTenantId())
- .build();
- AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
-
- if (token != null && token.getAccessToken() != null) {
-
- User user = User.newBuilder()
+ UserRepresentation.Builder builder = UserRepresentation.newBuilder()
.setFirstName(request.getUserProfile().getFirstName())
.setLastName(request.getUserProfile().getLastName())
- .setEmail(request.getUserProfile().getEmailAddress())
- .setUsername(request.getUserProfile().getUsername())
- .setTenantId(request.getUserProfile().getTenantId())
- .setInternalUserId(request.getUserProfile().getUserId())
- .setCreationTime(System.currentTimeMillis())
- .setState(request.getUserProfile().getStatus().name())
- .build();
+ .setEmail(request.getUserProfile().getEmail())
+ .setUsername(request.getUserProfile().getUsername());
+
+ if (request.getUserProfile().getStatus() != null) {
+ builder.setState(request.getUserProfile().getStatus().name());
+ }
+
UpdateUserProfileRequest updateUserProfileRequest = UpdateUserProfileRequest
.newBuilder()
- .setUser(user)
- .setAccessToken(token.getAccessToken())
+ .setUser(builder.build())
+ .setAccessToken(request.getAccessToken())
+ .setTenantId(request.getTenantId())
.build();
- UserAccessInfo info = UserAccessInfo
+ UserSearchRequest info = UserSearchRequest
.newBuilder()
- .setAccessToken(token.getAccessToken())
- .setTenantId(request.getUserProfile().getTenantId())
- .setUsername(request.getUserProfile().getUsername())
+ .setAccessToken(request.getAccessToken())
+ .setTenantId(request.getTenantId())
.build();
- User exUser = iamAdminServiceClient.getUser(info);
+ UserRepresentation exUser = iamAdminServiceClient.getUser(info);
CheckingResponse response = iamAdminServiceClient.updateUserProfile(updateUserProfileRequest);
@@ -525,7 +474,7 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
UpdateUserProfileRequest rollingRequest = UpdateUserProfileRequest
.newBuilder()
.setUser(exUser)
- .setAccessToken(token.getAccessToken())
+ .setAccessToken(request.getAccessToken())
.build();
iamAdminServiceClient.updateUserProfile(rollingRequest);
}
@@ -534,11 +483,6 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
responseObserver.onError(Status.CANCELLED.
withDescription("IAM server failed to update user profile").asRuntimeException());
}
- } else {
- LOGGER.error("Error occurred retreving service account");
- responseObserver.onError(Status.CANCELLED.
- withDescription("Service account not found").asRuntimeException());
- }
} catch (Exception ex) {
String msg = "Error occurred while updating user profile " + ex.getMessage();
@@ -548,6 +492,8 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
}
+ //TODO: this is not updated
+
@Override
public void deleteUserProfile(DeleteProfileRequest request, StreamObserver<UserProfile> responseObserver) {
try {
@@ -567,11 +513,11 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
if (token != null && token.getAccessToken() != null) {
- UserAccessInfo info = UserAccessInfo
+ UserSearchRequest info = UserSearchRequest
.newBuilder()
.setAccessToken(token.getAccessToken())
.setTenantId(request.getDeleteRequest().getTenantId())
- .setUsername(request.getDeleteRequest().getUsername())
+ // .setUsername(request.getDeleteRequest().getUsername())
.build();
@@ -629,7 +575,8 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
@Override
- public void getAllUserProfilesInTenant(GetAllUserProfilesRequest request, StreamObserver<GetAllUserProfilesResponse> responseObserver) {
+ public void getAllUserProfilesInTenant(GetAllUserProfilesRequest
+ request, StreamObserver<GetAllUserProfilesResponse> responseObserver) {
try {
LOGGER.debug("Request received to getAllUserProfilesInTenant " + request.getTenantId() +
" at" + request.getTenantId());
@@ -647,7 +594,8 @@ public class UserManagementService extends UserManagementServiceGrpc.UserManagem
}
@Override
- public void getUserProfileAuditTrails(GetUpdateAuditTrailRequest request, StreamObserver<GetUpdateAuditTrailResponse> responseObserver) {
+ public void getUserProfileAuditTrails(GetUpdateAuditTrailRequest
+ request, StreamObserver<GetUpdateAuditTrailResponse> responseObserver) {
try {
LOGGER.debug("Request received to getUserProfileAuditTrails " + request.getUsername() +
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 2254e77..77077a9 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
@@ -30,8 +30,9 @@ import "IamAdminService.proto";
message UserProfileRequest {
org.apache.custos.user.profile.service.UserProfile userProfile = 1;
- string iamClientId = 2;
- string iamClientSecret = 3;
+ string clientId = 2;
+ int64 tenantId = 3;
+ string accessToken = 4;
}
message DeleteProfileRequest {
@@ -40,18 +41,9 @@ message DeleteProfileRequest {
string iamClientSecret = 3;
}
-
-message UserIdentificationRequest {
- org.apache.custos.iam.service.UserAccessInfo info = 1;
- string iamClientId = 2;
- string iamClientSecret = 3;
-}
-
message GetUserRequest {
string username = 1;
- string iamClientId = 2;
- string iamClientSecret = 3;
- int64 tenantId = 4;
+ org.apache.custos.iam.service.UserSearchRequest userSearchRequest = 2;
}
message GetUsersRequest {
@@ -80,13 +72,6 @@ message ResetPasswordRequest {
-message RoleOperationRequest {
- org.apache.custos.iam.service.RoleOperationsUserRequest role = 1;
- string iamClientId = 2;
- string iamClientSecret = 3;
-}
-
-
service UserManagementService {
@@ -104,45 +89,63 @@ service UserManagementService {
};
}
+ rpc addUserAttributes (org.apache.custos.iam.service.AddUserAttributesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+ option (google.api.http) = {
+ post: "/user-management/v1.0.0/attributes"
+ };
+ }
- rpc enableUser (UserIdentificationRequest) returns (org.apache.custos.iam.service.User) {
+ rpc enableUser (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.UserRepresentation) {
option (google.api.http) = {
post: "/user-management/v1.0.0/user/activation"
- body: "info"
+ body: "user"
+ };
+ }
+
+ rpc addRolesToUsers ( org.apache.custos.iam.service.AddUserRolesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+ option (google.api.http) = {
+ post: "/user-management/v1.0.0/users/roles"
};
}
- rpc isUserEnabled (GetUserRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
+ rpc isUserEnabled (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
option (google.api.http) = {
get: "/user-management/v1.0.0/user/activation/status"
};
}
- rpc getUser (GetUserRequest) returns (org.apache.custos.iam.service.User) {
+ rpc isUsernameAvailable(org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
+ option (google.api.http) = {
+ get: "/user-management/v1.0.0/user/availability"
+ };
+ }
+
+
+
+ rpc getUser (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.UserRepresentation) {
option (google.api.http) = {
get: "/user-management/v1.0.0/user"
};
}
- rpc getUsers (GetUsersRequest) returns (org.apache.custos.iam.service.GetUsersResponse) {
+ rpc findUsers (org.apache.custos.iam.service.FindUsersRequest) returns (org.apache.custos.iam.service.FindUsersResponse) {
option (google.api.http) = {
get: "/user-management/v1.0.0/users"
};
}
- rpc resetPassword (ResetPasswordRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
+ rpc resetPassword (org.apache.custos.iam.service.ResetUserPassword) returns (org.apache.custos.iam.service.CheckingResponse) {
option (google.api.http) = {
put: "/user-management/v1.0.0/user/password"
- body: "passwordMetadata"
};
}
- rpc deleteUser (UserIdentificationRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
+ rpc deleteUser (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
option (google.api.http) = {
delete: "/user-management/v1.0.0/user"
body: "info"
@@ -150,18 +153,10 @@ service UserManagementService {
}
- rpc addRoleToUser (RoleOperationRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
- option (google.api.http) = {
- post: "/user-management/v1.0.0/user/role"
- body: "role"
- };
- }
-
- rpc deleteRoleFromUser (RoleOperationRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
+ rpc deleteUserRoles (org.apache.custos.iam.service.DeleteUserRolesRequest) returns (org.apache.custos.iam.service.CheckingResponse) {
option (google.api.http) = {
- delete: "/user-management/v1.0.0/user/role"
- body: "role"
+ delete: "/user-management/v1.0.0/user/roles"
};
}
diff --git a/pom.xml b/pom.xml
index 6ecdaac..04a3cb3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -157,6 +157,11 @@
<version>${keycloak.admin.version}</version>
</dependency>
<dependency>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-authz-client</artifactId>
+ <version>${keycloak.admin.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${reasteasy.client.version}</version>