This is an automated email from the ASF dual-hosted git repository. dominikriemer pushed a commit to branch migrate-configuration-storage in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 449ad75d2290aaaf72caa7a8c17b6fe1bd92089f Author: Dominik Riemer <[email protected]> AuthorDate: Wed Jun 24 09:31:56 2026 +0200 Migrate user group storage --- .../loadbalance/ResourceUnitMigration.java | 2 +- .../loadbalance/unit/InvokeHttpRequest.java | 29 ++++++++----- .../api/extensions/ExtensionServiceRequests.java | 18 ++++----- .../execution/http/InvokeExtensionRequest.java | 4 +- .../remote/ContainerProvidedOptionsHandler.java | 4 +- .../tasks/ApplyDefaultRolesAndPrivilegesTask.java | 6 +-- ...{AuthTokenUtils.java => AuthTokenProvider.java} | 47 +++++++++++++--------- .../resource/management/SpResourceManager.java | 18 ++++++++- .../streampipes/rest/impl/Authentication.java | 12 +++++- .../streampipes/rest/impl/ResetResource.java | 6 ++- .../streampipes/rest/impl/admin/RoleResource.java | 6 +-- .../rest/impl/admin/UserGroupResource.java | 20 ++++----- .../service/core/StreamPipesCoreApplication.java | 6 ++- .../service/core/WebSecurityConfig.java | 18 +++++---- .../ExtensionServiceRequestConfiguration.java | 10 ++++- .../core/filter/TokenAuthenticationFilter.java | 30 +++++++++----- .../core/migrations/AvailableMigrations.java | 8 +++- .../v099/RemoveAssetUserRoleMigration.java | 7 ++-- .../oauth2/OAuth2AuthenticationSuccessHandler.java | 8 +++- .../core/oauth2/OidcUserAccountDetails.java | 16 ++++++-- .../service/core/oauth2/UserService.java | 24 +++++------ .../core/storage/StorageApiConfiguration.java | 14 +++++++ .../storage/api/core/INoSqlStorage.java | 6 --- .../storage/couchdb/CouchDbStorageManager.java | 14 ------- .../user/management/authorization/RoleManager.java | 5 +-- .../user/management/jwt/JwtTokenProvider.java | 12 +++++- .../management/model/PrincipalUserDetails.java | 8 +++- .../management/model/ServiceAccountDetails.java | 8 +++- .../user/management/model/UserAccountDetails.java | 8 +++- .../management/service/SpUserDetailsService.java | 19 +++++++-- .../management/util/GrantedAuthoritiesBuilder.java | 16 +++++--- 31 files changed, 265 insertions(+), 144 deletions(-) diff --git a/streampipes-load-balancer/src/main/java/org/apache/streampipes/loadbalance/ResourceUnitMigration.java b/streampipes-load-balancer/src/main/java/org/apache/streampipes/loadbalance/ResourceUnitMigration.java index 2d3d064f54..ba0834c8ea 100644 --- a/streampipes-load-balancer/src/main/java/org/apache/streampipes/loadbalance/ResourceUnitMigration.java +++ b/streampipes-load-balancer/src/main/java/org/apache/streampipes/loadbalance/ResourceUnitMigration.java @@ -69,7 +69,7 @@ public class ResourceUnitMigration { newEndpointUrl); new InvokeHttpRequest().execute( - element, newEndpointUrl, resourceUnit.getPipelineId(), resourceManager.getCoreConfigurationStorage()); + element, newEndpointUrl, resourceUnit.getPipelineId(), resourceManager); } // Update pipeline in storage with new endpoints diff --git a/streampipes-load-balancer/src/main/java/org/apache/streampipes/loadbalance/unit/InvokeHttpRequest.java b/streampipes-load-balancer/src/main/java/org/apache/streampipes/loadbalance/unit/InvokeHttpRequest.java index 468ee2f783..8ad59402d9 100644 --- a/streampipes-load-balancer/src/main/java/org/apache/streampipes/loadbalance/unit/InvokeHttpRequest.java +++ b/streampipes-load-balancer/src/main/java/org/apache/streampipes/loadbalance/unit/InvokeHttpRequest.java @@ -22,8 +22,8 @@ import org.apache.streampipes.model.api.EndpointSelectable; import org.apache.streampipes.model.client.user.Permission; import org.apache.streampipes.model.client.user.Principal; import org.apache.streampipes.model.pipeline.PipelineElementStatus; +import org.apache.streampipes.resource.management.SpResourceManager; import org.apache.streampipes.serializers.json.JacksonSerializer; -import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; import org.apache.streampipes.storage.couchdb.impl.user.PermissionStorageImpl; import org.apache.streampipes.storage.management.StorageDispatcher; import org.apache.streampipes.user.management.jwt.JwtTokenProvider; @@ -66,10 +66,10 @@ public class InvokeHttpRequest{ public PipelineElementStatus execute(EndpointSelectable pipelineElement, String endpointUrl, String pipelineId, - ISpCoreConfigurationStorage configurationStorage) { + SpResourceManager resourceManager) { try { Response httpResp = initRequest(pipelineElement, endpointUrl) - .addHeader("Authorization", getAuthToken(pipelineId, configurationStorage)) + .addHeader("Authorization", getAuthToken(pipelineId, resourceManager)) .connectTimeout(10000) .execute(); return handleResponse(httpResp, pipelineElement, endpointUrl); @@ -97,14 +97,19 @@ public class InvokeHttpRequest{ } public static String getAuthToken(String resourceId, - ISpCoreConfigurationStorage configurationStorage) { + SpResourceManager resourceManager) { + var configurationStorage = resourceManager.getCoreConfigurationStorage(); if (SecurityContextHolder.getContext().getAuthentication() != null) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - return makeBearerToken(new JwtTokenProvider(configurationStorage).createToken(auth)); + return makeBearerToken(new JwtTokenProvider( + configurationStorage, + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ).createToken(auth)); } else { if (resourceId != null) { String ownerSid = getOwnerSid(resourceId); - return getAuthTokenForUser(ownerSid, configurationStorage); + return getAuthTokenForUser(ownerSid, resourceManager); } else { throw new IllegalArgumentException("No authenticated user found to associate with request"); } @@ -112,14 +117,18 @@ public class InvokeHttpRequest{ } public static String getAuthTokenForUser(String ownerSid, - ISpCoreConfigurationStorage configurationStorage) { + SpResourceManager resourceManager) { Principal correspondingUser = StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI().getUserById(ownerSid); - return getAuthTokenForUser(correspondingUser, configurationStorage); + return getAuthTokenForUser(correspondingUser, resourceManager); } public static String getAuthTokenForUser(Principal principal, - ISpCoreConfigurationStorage configurationStorage) { - return makeBearerToken(new JwtTokenProvider(configurationStorage).createToken(principal)); + SpResourceManager resourceManager) { + return makeBearerToken(new JwtTokenProvider( + resourceManager.getCoreConfigurationStorage(), + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ).createToken(principal)); } private static String makeBearerToken(String token) { diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/api/extensions/ExtensionServiceRequests.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/api/extensions/ExtensionServiceRequests.java index 5acb784ecc..20d4111e75 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/api/extensions/ExtensionServiceRequests.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/api/extensions/ExtensionServiceRequests.java @@ -18,7 +18,7 @@ package org.apache.streampipes.manager.api.extensions; -import org.apache.streampipes.manager.util.AuthTokenUtils; +import org.apache.streampipes.manager.util.AuthTokenProvider; import org.apache.streampipes.resource.management.SpResourceManager; public final class ExtensionServiceRequests { @@ -58,7 +58,7 @@ public final class ExtensionServiceRequests { return post( target, payload, - AuthTokenUtils.getAuthTokenForCurrentUser(resourceManager.getCoreConfigurationStorage()) + new AuthTokenProvider(resourceManager).getAuthTokenForCurrentUser() ); } @@ -81,7 +81,7 @@ public final class ExtensionServiceRequests { String elementId, String payload, SpResourceManager resourceManager) { - return post(target, payload, AuthTokenUtils.getAuthToken(elementId, resourceManager)); + return post(target, payload, new AuthTokenProvider(resourceManager).getAuthToken(elementId)); } public static ExtensionServiceRequest runtimeOptions(ExtensionServiceRequestTarget target, @@ -90,7 +90,7 @@ public final class ExtensionServiceRequests { return post( target, payload, - AuthTokenUtils.getAuthTokenForCurrentUser(resourceManager.getCoreConfigurationStorage()) + new AuthTokenProvider(resourceManager).getAuthTokenForCurrentUser() ); } @@ -100,7 +100,7 @@ public final class ExtensionServiceRequests { return post( target, payload, - AuthTokenUtils.getAuthTokenForCurrentUser(resourceManager.getCoreConfigurationStorage()) + new AuthTokenProvider(resourceManager).getAuthTokenForCurrentUser() ); } @@ -128,7 +128,7 @@ public final class ExtensionServiceRequests { public static ExtensionServiceRequest pipelineElementDetach(ExtensionServiceRequestTarget target, String pipelineId, SpResourceManager resourceManager) { - return delete(target, AuthTokenUtils.getAuthToken(pipelineId, resourceManager)); + return delete(target, new AuthTokenProvider(resourceManager).getAuthToken(pipelineId)); } public static ExtensionServiceRequest pipelineElementAssets(ExtensionServiceRequestTarget target) { @@ -156,8 +156,8 @@ public final class ExtensionServiceRequests { } private static String serviceAdminToken(SpResourceManager resourceManager) { - return AuthTokenUtils.getAuthTokenForUser( - resourceManager.manageUsers().getServiceAdmin().getPrincipalId(), - resourceManager); + return new AuthTokenProvider(resourceManager).getAuthTokenForUser( + resourceManager.manageUsers().getServiceAdmin().getPrincipalId() + ); } } diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/execution/http/InvokeExtensionRequest.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/execution/http/InvokeExtensionRequest.java index 96a7023683..d77a44326c 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/execution/http/InvokeExtensionRequest.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/execution/http/InvokeExtensionRequest.java @@ -23,7 +23,7 @@ import org.apache.streampipes.manager.api.extensions.ExtensionServiceRequestMana import org.apache.streampipes.manager.api.extensions.ExtensionServiceRequestTargets; import org.apache.streampipes.manager.api.extensions.ExtensionServiceRequests; import org.apache.streampipes.manager.execution.endpoint.ExtensionsServiceEndpointUtils; -import org.apache.streampipes.manager.util.AuthTokenUtils; +import org.apache.streampipes.manager.util.AuthTokenProvider; import org.apache.streampipes.model.api.EndpointSelectable; import org.apache.streampipes.model.base.InvocableStreamPipesEntity; import org.apache.streampipes.resource.management.SpResourceManager; @@ -55,7 +55,7 @@ public class InvokeExtensionRequest extends PipelineElementExtensionRequest { provider, pipelineElement.getAppId() ); - var authToken = AuthTokenUtils.getAuthToken(pipelineId, resourceManager); + var authToken = new AuthTokenProvider(resourceManager).getAuthToken(pipelineId); return requestManager().request( ExtensionServiceRequests .pipelineElementInvocation(requestTarget, toJson(pipelineElement), authToken) diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java index 312d08957c..32badb4040 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java @@ -24,7 +24,7 @@ import org.apache.streampipes.manager.api.extensions.ExtensionServiceRequestTarg import org.apache.streampipes.manager.api.extensions.ExtensionServiceRequests; import org.apache.streampipes.manager.execution.endpoint.ExtensionsServiceEndpointGenerator; import org.apache.streampipes.manager.execution.endpoint.ExtensionsServiceEndpointUtils; -import org.apache.streampipes.manager.util.AuthTokenUtils; +import org.apache.streampipes.manager.util.AuthTokenProvider; import org.apache.streampipes.model.runtime.RuntimeOptionsRequest; import org.apache.streampipes.model.runtime.RuntimeOptionsResponse; import org.apache.streampipes.resource.management.SpResourceManager; @@ -52,7 +52,7 @@ public class ContainerProvidedOptionsHandler { try { var payload = JacksonSerializer.getObjectMapper().writeValueAsString(request); var requestTarget = getEndpointRequestTarget(request.getAppId()); - var authToken = AuthTokenUtils.getAuthTokenForCurrentUser(resourceManager.getCoreConfigurationStorage()); + var authToken = new AuthTokenProvider(resourceManager).getAuthTokenForCurrentUser(); var response = extensionRequestManager.request( ExtensionServiceRequests.containerProvidedOptions(requestTarget, payload, authToken) ); diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/ApplyDefaultRolesAndPrivilegesTask.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/ApplyDefaultRolesAndPrivilegesTask.java index 59b5a65004..8fcafefc19 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/ApplyDefaultRolesAndPrivilegesTask.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/ApplyDefaultRolesAndPrivilegesTask.java @@ -39,15 +39,15 @@ public class ApplyDefaultRolesAndPrivilegesTask implements InstallationTask { private final IRoleStorage roleStorage; private final IPrivilegeStorage privilegeStorage; - public ApplyDefaultRolesAndPrivilegesTask() { - this.roleStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getRoleStorage(); + public ApplyDefaultRolesAndPrivilegesTask(IRoleStorage roleStorage) { + this.roleStorage = roleStorage; this.privilegeStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getPrivilegeStorage(); } @Override public void execute() { LOG.info("Creating or updating default roles and privileges"); - var defaultRoles = new RoleManager().makeDefaultRoles(); + var defaultRoles = new RoleManager(roleStorage).makeDefaultRoles(); var defaultPrivileges = new PrivilegeManager().makeDefaultPrivileges(); updateDocs(roleStorage, defaultRoles); updateDocs(privilegeStorage, defaultPrivileges); diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/util/AuthTokenUtils.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/util/AuthTokenProvider.java similarity index 56% rename from streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/util/AuthTokenUtils.java rename to streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/util/AuthTokenProvider.java index b296d5f07a..d87ea1c032 100644 --- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/util/AuthTokenUtils.java +++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/util/AuthTokenProvider.java @@ -20,52 +20,61 @@ package org.apache.streampipes.manager.util; import org.apache.streampipes.model.client.user.Permission; import org.apache.streampipes.model.client.user.Principal; -import org.apache.streampipes.resource.management.PermissionResourceManager; import org.apache.streampipes.resource.management.SpResourceManager; -import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; import org.apache.streampipes.user.management.jwt.JwtTokenProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -public class AuthTokenUtils { +public class AuthTokenProvider { - public static String getAuthTokenForCurrentUser(ISpCoreConfigurationStorage coreConfigurationStorage) { + private final SpResourceManager resourceManager; + + public AuthTokenProvider(SpResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + public String getAuthTokenForCurrentUser() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - return makeBearerToken(new JwtTokenProvider(coreConfigurationStorage).createToken(auth)); + return makeBearerToken(new JwtTokenProvider( + resourceManager.getCoreConfigurationStorage(), + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ).createToken(auth)); } - public static String getAuthToken(String resourceId, - SpResourceManager resourceManager) { + public String getAuthToken(String resourceId) { if (SecurityContextHolder.getContext().getAuthentication() != null) { - return getAuthTokenForCurrentUser(resourceManager.getCoreConfigurationStorage()); + return getAuthTokenForCurrentUser(); } else { if (resourceId != null) { - String ownerSid = getOwnerSid(resourceId, resourceManager.managePermissions()); - return getAuthTokenForUser(ownerSid, resourceManager); + String ownerSid = getOwnerSid(resourceId); + return getAuthTokenForUser(ownerSid); } else { throw new IllegalArgumentException("No authenticated user found to associate with request"); } } } - public static String getAuthTokenForUser(String ownerSid, - SpResourceManager resourceManager) { + public String getAuthTokenForUser(String ownerSid) { Principal correspondingUser = resourceManager.manageUsers().getPrincipalById(ownerSid); - return getAuthTokenForUser(correspondingUser, resourceManager.getCoreConfigurationStorage()); + return getAuthTokenForUser(correspondingUser); } - public static String getAuthTokenForUser(Principal principal, - ISpCoreConfigurationStorage configurationStorage) { - return makeBearerToken(new JwtTokenProvider(configurationStorage).createToken(principal)); + public String getAuthTokenForUser(Principal principal) { + return makeBearerToken(new JwtTokenProvider( + resourceManager.getCoreConfigurationStorage(), + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ).createToken(principal)); } - private static String makeBearerToken(String token) { + private String makeBearerToken(String token) { return "Bearer " + token; } - private static String getOwnerSid(String resourceId, PermissionResourceManager permissionResourceManager) { - return permissionResourceManager.findForObjectId(resourceId) + private String getOwnerSid(String resourceId) { + return resourceManager.managePermissions().findForObjectId(resourceId) .stream() .findFirst() .map(Permission::getOwnerSid) diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/SpResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/SpResourceManager.java index 45742f3a2b..2feb6fa72e 100644 --- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/SpResourceManager.java +++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/SpResourceManager.java @@ -26,6 +26,8 @@ import org.apache.streampipes.storage.api.system.IAssetStorage; import org.apache.streampipes.storage.api.system.IFileMetadataStorage; import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.storage.management.StorageDispatcher; public class SpResourceManager { @@ -39,6 +41,8 @@ public class SpResourceManager { private final IDataLakeMeasureStorage datasetStorage; private final ISpCoreConfigurationStorage coreConfigurationStorage; private final IFileMetadataStorage fileMetadataStorage; + private final IRoleStorage roleStorage; + private final IUserGroupStorage userGroupStorage; public SpResourceManager(IPermissionStorage permissionStorage, IChartStorage chartStorage, @@ -48,7 +52,9 @@ public class SpResourceManager { IPipelineStorage pipelineStorage, IDataLakeMeasureStorage datasetStorage, ISpCoreConfigurationStorage coreConfigurationStorage, - IFileMetadataStorage fileMetadataStorage) { + IFileMetadataStorage fileMetadataStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { this.permissionStorage = permissionStorage; this.chartStorage = chartStorage; this.adapterStorage = adapterStorage; @@ -58,6 +64,8 @@ public class SpResourceManager { this.datasetStorage = datasetStorage; this.coreConfigurationStorage = coreConfigurationStorage; this.fileMetadataStorage = fileMetadataStorage; + this.roleStorage = roleStorage; + this.userGroupStorage = userGroupStorage; } public AdapterDescriptionResourceManager manageAdapterDescriptions() { @@ -114,6 +122,14 @@ public class SpResourceManager { return fileMetadataStorage; } + public IRoleStorage getRoleStorage() { + return roleStorage; + } + + public IUserGroupStorage getUserGroupStorage() { + return userGroupStorage; + } + public UserResourceManager manageUsers() { return new UserResourceManager(coreConfigurationStorage); } diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/Authentication.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/Authentication.java index 0ff0792fda..a30484c283 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/Authentication.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/Authentication.java @@ -132,7 +132,11 @@ public class Authentication extends AbstractRestResource { setRefreshCookie(request, response, issuedRefreshToken); - String jwt = new JwtTokenProvider(coreConfigurationStorage).createToken(userAccount); + String jwt = new JwtTokenProvider( + coreConfigurationStorage, + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ).createToken(userAccount); return ok(new JwtAuthenticationResponse(jwt)); } @@ -244,7 +248,11 @@ public class Authentication extends AbstractRestResource { } private JwtAuthenticationResponse makeJwtResponse(org.springframework.security.core.Authentication auth) { - String jwt = new JwtTokenProvider(coreConfigurationStorage).createToken(auth); + String jwt = new JwtTokenProvider( + coreConfigurationStorage, + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ).createToken(auth); return new JwtAuthenticationResponse(jwt); } diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/ResetResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/ResetResource.java index 700a942ea0..00e1c2d4cd 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/ResetResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/ResetResource.java @@ -50,11 +50,13 @@ import java.util.ArrayList; public class ResetResource extends AbstractAuthGuardedRestResource { private final ResetManagement resetManagement; + private final SpResourceManager resourceManager; public ResetResource(WorkerRestClient workerRestClient, ExtensionServiceRequestManager requestManager, SpResourceManager resourceManager) { IExtensionsServiceStorage extensionsServiceStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getExtensionsServiceStorage(); + this.resourceManager = resourceManager; var pipelineManager = new PipelineManager( resourceManager ); @@ -86,9 +88,9 @@ public class ResetResource extends AbstractAuthGuardedRestResource { } // Delete all user Groups - var allUserGroups = getNoSqlStorage().getUserGroupStorage().findAll(); + var allUserGroups = resourceManager.getUserGroupStorage().findAll(); for (var group : allUserGroups) { - getNoSqlStorage().getUserGroupStorage().deleteElementById(group.getElementId()); + resourceManager.getUserGroupStorage().deleteElementById(group.getElementId()); } // Delete all connect script templates diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/RoleResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/RoleResource.java index 5fd0bd0d2e..09d8af4ef5 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/RoleResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/RoleResource.java @@ -21,7 +21,7 @@ package org.apache.streampipes.rest.impl.admin; import org.apache.streampipes.model.client.user.Role; import org.apache.streampipes.rest.core.base.impl.DefaultCRUDRestResource; import org.apache.streampipes.rest.security.AuthConstants; -import org.apache.streampipes.storage.management.StorageDispatcher; +import org.apache.streampipes.storage.api.user.IRoleStorage; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; @@ -32,7 +32,7 @@ import org.springframework.web.bind.annotation.RestController; @PreAuthorize(AuthConstants.IS_ADMIN_ROLE) public class RoleResource extends DefaultCRUDRestResource<Role> { - public RoleResource() { - super(StorageDispatcher.INSTANCE.getNoSqlStore().getRoleStorage()); + public RoleResource(IRoleStorage roleStorage) { + super(roleStorage); } } diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/UserGroupResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/UserGroupResource.java index 043cd28f81..885e4e6c3d 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/UserGroupResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/UserGroupResource.java @@ -43,15 +43,21 @@ import java.util.List; @RequestMapping("/api/v2/usergroups") public class UserGroupResource extends AbstractAuthGuardedRestResource { + private final IUserGroupStorage userGroupStorage; + + public UserGroupResource(IUserGroupStorage userGroupStorage) { + this.userGroupStorage = userGroupStorage; + } + @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<List<Group>> getAllUserGroups() { - return ok(getUserGroupStorage().findAll()); + return ok(userGroupStorage.findAll()); } @PostMapping @PreAuthorize(AuthConstants.IS_ADMIN_ROLE) public ResponseEntity<Void> addUserGroup(@RequestBody Group group) { - getUserGroupStorage().persist(group); + userGroupStorage.persist(group); return ok(); } @@ -64,16 +70,16 @@ public class UserGroupResource extends AbstractAuthGuardedRestResource { HttpStatus.BAD_REQUEST, Notifications.error("Wrong group id provided")); } else { - return ok(getUserGroupStorage().updateElement(group)); + return ok(userGroupStorage.updateElement(group)); } } @DeleteMapping(path = "{groupId}", produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize(AuthConstants.IS_ADMIN_ROLE) public ResponseEntity<Void> deleteUserGroup(@PathVariable("groupId") String groupId) { - Group group = getUserGroupStorage().getElementById(groupId); + Group group = userGroupStorage.getElementById(groupId); if (group != null) { - getUserGroupStorage().deleteElement(group); + userGroupStorage.deleteElement(group); // TODO remove group from all users getUserStorage().getAllUsers().forEach(user -> { @@ -87,8 +93,4 @@ public class UserGroupResource extends AbstractAuthGuardedRestResource { return badRequest(); } } - - private IUserGroupStorage getUserGroupStorage() { - return getNoSqlStorage().getUserGroupStorage(); - } } diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/StreamPipesCoreApplication.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/StreamPipesCoreApplication.java index 09d2109ecb..ec6f80672e 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/StreamPipesCoreApplication.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/StreamPipesCoreApplication.java @@ -62,6 +62,7 @@ import org.apache.streampipes.service.core.storage.StorageApiConfiguration; import org.apache.streampipes.storage.api.function.IFunctionStateStorage; import org.apache.streampipes.storage.api.pipeline.IPipelineStorage; import org.apache.streampipes.storage.api.system.IExtensionsServiceStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; import org.apache.streampipes.storage.couchdb.impl.user.UserStorage; import org.apache.streampipes.storage.couchdb.utils.CouchDbViewGenerator; import org.apache.streampipes.storage.management.StorageDispatcher; @@ -110,6 +111,9 @@ public class StreamPipesCoreApplication extends StreamPipesServiceBase { @Autowired protected SpResourceManager resourceManager; + @Autowired + protected IRoleStorage roleStorage; + private final IExtensionsServiceStorage extensionsServiceStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getExtensionsServiceStorage(); @@ -186,7 +190,7 @@ public class StreamPipesCoreApplication extends StreamPipesServiceBase { new MigrationsHandler().performMigrations(getMigrations()); } - new ApplyDefaultRolesAndPrivilegesTask().execute(); + new ApplyDefaultRolesAndPrivilegesTask(roleStorage).execute(); coreStatusManager.updateCoreStatus(SpCoreConfigurationStatus.READY); executorService.schedule(new PostStartupTask( diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/WebSecurityConfig.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/WebSecurityConfig.java index 288cea95e5..44e717e4c7 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/WebSecurityConfig.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/WebSecurityConfig.java @@ -21,6 +21,7 @@ package org.apache.streampipes.service.core; import org.apache.streampipes.commons.environment.Environment; import org.apache.streampipes.commons.environment.Environments; import org.apache.streampipes.commons.environment.model.OAuthConfiguration; +import org.apache.streampipes.resource.management.SpResourceManager; import org.apache.streampipes.service.base.security.UnauthorizedRequestEntryPoint; import org.apache.streampipes.service.core.filter.TokenAuthenticationFilter; import org.apache.streampipes.service.core.oauth2.CustomOAuth2UserService; @@ -97,14 +98,17 @@ public class WebSecurityConfig { @Autowired private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler; - private final IPermissionStorage permissionStorage; + private final SpResourceManager resourceManager; public WebSecurityConfig(StreamPipesPasswordEncoder passwordEncoder, - IPermissionStorage permissionStorage) { + SpResourceManager resourceManager) { this.passwordEncoder = passwordEncoder; - this.userDetailsService = new SpUserDetailsService(permissionStorage); + this.userDetailsService = new SpUserDetailsService( + resourceManager.managePermissions().getDb(), + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage()); this.env = Environments.getEnvironment(); - this.permissionStorage = permissionStorage; + this.resourceManager = resourceManager; } @Autowired @@ -154,13 +158,13 @@ public class WebSecurityConfig { ); } - http.addFilterBefore(tokenAuthenticationFilter(coreConfigurationStorage), UsernamePasswordAuthenticationFilter.class); + http.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } - public TokenAuthenticationFilter tokenAuthenticationFilter(ISpCoreConfigurationStorage coreConfigurationStorage) { - return new TokenAuthenticationFilter(permissionStorage, coreConfigurationStorage); + public TokenAuthenticationFilter tokenAuthenticationFilter() { + return new TokenAuthenticationFilter(resourceManager); } @Bean(BeanIds.USER_DETAILS_SERVICE) diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/extensions/ExtensionServiceRequestConfiguration.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/extensions/ExtensionServiceRequestConfiguration.java index 0808c1305c..95f4d68a29 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/extensions/ExtensionServiceRequestConfiguration.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/extensions/ExtensionServiceRequestConfiguration.java @@ -32,6 +32,8 @@ import org.apache.streampipes.storage.api.system.IAssetStorage; import org.apache.streampipes.storage.api.system.IFileMetadataStorage; import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,7 +102,9 @@ public class ExtensionServiceRequestConfiguration { IPipelineStorage pipelineStorage, IDataLakeMeasureStorage datasetStorage, ISpCoreConfigurationStorage coreConfigurationStorage, - IFileMetadataStorage fileMetadataStorage) { + IFileMetadataStorage fileMetadataStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { return new SpResourceManager( permissionStorage, chartStorage, @@ -110,7 +114,9 @@ public class ExtensionServiceRequestConfiguration { pipelineStorage, datasetStorage, coreConfigurationStorage, - fileMetadataStorage + fileMetadataStorage, + roleStorage, + userGroupStorage ); } diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java index a79f6824ef..4314f2297c 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java @@ -23,8 +23,7 @@ import org.apache.streampipes.model.client.user.DefaultRole; import org.apache.streampipes.model.client.user.Principal; import org.apache.streampipes.model.client.user.ServiceAccount; import org.apache.streampipes.model.client.user.UserAccount; -import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; -import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.resource.management.SpResourceManager; import org.apache.streampipes.storage.api.user.IUserStorage; import org.apache.streampipes.storage.management.StorageDispatcher; import org.apache.streampipes.user.management.encryption.SecretEncryptionManager; @@ -63,7 +62,7 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { private final JwtTokenProvider tokenProvider; private final IUserStorage userStorage; - private final IPermissionStorage permissionStorage; + private final SpResourceManager resourceManager; private final List<String> supportedBasicAuthPaths = List.of( "/actuator/prometheus" @@ -73,11 +72,14 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { private static final Logger logger = LoggerFactory.getLogger(TokenAuthenticationFilter.class); - public TokenAuthenticationFilter(IPermissionStorage permissionStorage, - ISpCoreConfigurationStorage coreConfigurationStorage) { - this.tokenProvider = new JwtTokenProvider(coreConfigurationStorage); + public TokenAuthenticationFilter(SpResourceManager resourceManager) { + this.tokenProvider = new JwtTokenProvider( + resourceManager.getCoreConfigurationStorage(), + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ); this.userStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI(); - this.permissionStorage = permissionStorage; + this.resourceManager = resourceManager; } @Override @@ -160,8 +162,18 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { } private PrincipalUserDetails<?> makeDetails(Principal user) { - return user instanceof UserAccount ? new UserAccountDetails((UserAccount) user, permissionStorage) : - new ServiceAccountDetails((ServiceAccount) user, permissionStorage); + return user instanceof UserAccount ? new UserAccountDetails( + (UserAccount) user, + resourceManager.managePermissions().getDb(), + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ) : + new ServiceAccountDetails( + (ServiceAccount) user, + resourceManager.managePermissions().getDb(), + resourceManager.getRoleStorage(), + resourceManager.getUserGroupStorage() + ); } private boolean isAdminUser(PrincipalUserDetails<?> userDetails) { diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java index ea58e06ac3..be8f8aadd2 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java @@ -48,6 +48,8 @@ import org.apache.streampipes.storage.api.pipeline.IPipelineStorage; import org.apache.streampipes.storage.api.system.IAssetStorage; import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import java.util.Arrays; import java.util.List; @@ -62,6 +64,8 @@ public class AvailableMigrations { private final IPipelineStorage pipelineStorage; private final IDataLakeMeasureStorage datasetStorage; private final ISpCoreConfigurationStorage coreConfigStorage; + private final IRoleStorage roleStorage; + private final IUserGroupStorage userGroupStorage; public AvailableMigrations(SpResourceManager resourceManager) { this.chartStorage = resourceManager.manageCharts().getDb(); @@ -72,6 +76,8 @@ public class AvailableMigrations { this.pipelineStorage = resourceManager.managePipelines().getDb(); this.datasetStorage = resourceManager.manageDataLakeMeasures().getDb(); this.coreConfigStorage = resourceManager.getCoreConfigurationStorage(); + this.roleStorage = resourceManager.getRoleStorage(); + this.userGroupStorage = resourceManager.getUserGroupStorage(); } public List<Migration> getAvailableMigrations() { @@ -94,7 +100,7 @@ public class AvailableMigrations { new RemoveDuplicatedAssetPermissions(permissionStorage, assetStorage), new AddFunctionStateViewMigration(), new AddRefreshTokenViewsMigration(), - new RemoveAssetUserRoleMigration(), + new RemoveAssetUserRoleMigration(roleStorage, userGroupStorage), new RemoveInternalNotificationSinkMigration(pipelineStorage) ); } diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/RemoveAssetUserRoleMigration.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/RemoveAssetUserRoleMigration.java index 49d1f3488a..08f9b714a4 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/RemoveAssetUserRoleMigration.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/RemoveAssetUserRoleMigration.java @@ -36,10 +36,11 @@ public class RemoveAssetUserRoleMigration implements Migration { private final IUserStorage userStorage; private final IUserGroupStorage userGroupStorage; - public RemoveAssetUserRoleMigration() { - this.roleStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getRoleStorage(); + public RemoveAssetUserRoleMigration(IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { + this.roleStorage = roleStorage; this.userStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI(); - this.userGroupStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getUserGroupStorage(); + this.userGroupStorage = userGroupStorage; } @Override diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/OAuth2AuthenticationSuccessHandler.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/OAuth2AuthenticationSuccessHandler.java index 61e8d7b5cb..ab2c7849e2 100755 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/OAuth2AuthenticationSuccessHandler.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/OAuth2AuthenticationSuccessHandler.java @@ -24,6 +24,8 @@ import org.apache.streampipes.model.client.user.Principal; import org.apache.streampipes.rest.shared.exception.BadRequestException; import org.apache.streampipes.service.core.oauth2.util.CookieUtils; import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.user.management.jwt.JwtTokenProvider; import org.apache.streampipes.user.management.model.PrincipalUserDetails; import org.apache.streampipes.user.management.service.RefreshTokenService; @@ -60,8 +62,10 @@ public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS @Autowired OAuth2AuthenticationSuccessHandler(HttpCookieOAuth2AuthorizationRequestRepository httpCookieOAuth2AuthorizationRequestRepository, - ISpCoreConfigurationStorage coreConfigurationStorage) { - this.tokenProvider = new JwtTokenProvider(coreConfigurationStorage); + ISpCoreConfigurationStorage coreConfigurationStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { + this.tokenProvider = new JwtTokenProvider(coreConfigurationStorage, roleStorage, userGroupStorage); this.httpCookieOAuth2AuthorizationRequestRepository = httpCookieOAuth2AuthorizationRequestRepository; this.env = Environments.getEnvironment(); } diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/OidcUserAccountDetails.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/OidcUserAccountDetails.java index 671adbad20..9958fedb61 100755 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/OidcUserAccountDetails.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/OidcUserAccountDetails.java @@ -20,6 +20,8 @@ package org.apache.streampipes.service.core.oauth2; import org.apache.streampipes.model.client.user.UserAccount; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.user.management.model.UserAccountDetails; import org.springframework.security.oauth2.core.oidc.OidcIdToken; @@ -38,8 +40,10 @@ public class OidcUserAccountDetails extends UserAccountDetails implements OAuth2 public OidcUserAccountDetails(UserAccount user, OidcIdToken idToken, OidcUserInfo userInfo, - IPermissionStorage permissionStorage) { - super(user, permissionStorage); + IPermissionStorage permissionStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { + super(user, permissionStorage, roleStorage, userGroupStorage); this.idToken = idToken; this.userInfo = userInfo; } @@ -48,8 +52,12 @@ public class OidcUserAccountDetails extends UserAccountDetails implements OAuth2 Map<String, Object> attributes, OidcIdToken idToken, OidcUserInfo userInfo, - IPermissionStorage permissionStorage) { - OidcUserAccountDetails localUser = new OidcUserAccountDetails(user, idToken, userInfo, permissionStorage); + IPermissionStorage permissionStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { + OidcUserAccountDetails localUser = new OidcUserAccountDetails( + user, idToken, userInfo, permissionStorage, roleStorage, userGroupStorage + ); localUser.setAttributes(attributes); return localUser; } diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/UserService.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/UserService.java index c3754be18a..2972bb6c67 100755 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/UserService.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/UserService.java @@ -21,7 +21,6 @@ package org.apache.streampipes.service.core.oauth2; import org.apache.streampipes.commons.environment.Environment; import org.apache.streampipes.commons.environment.Environments; import org.apache.streampipes.commons.environment.model.OAuthConfiguration; -import org.apache.streampipes.model.client.user.Group; import org.apache.streampipes.model.client.user.Role; import org.apache.streampipes.model.client.user.UserAccount; import org.apache.streampipes.resource.management.SpResourceManager; @@ -54,17 +53,14 @@ public class UserService { private final IRoleStorage roleStorage; private final IUserGroupStorage groupStorage; private final Environment env; - private List<Role> allRoles; - private List<Group> allGroups; private final IPermissionStorage permissionStorage; private final ISpCoreConfigurationStorage configurationStorage; public UserService(SpResourceManager resourceManager) { this.userStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI(); - this.roleStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getRoleStorage(); - this.groupStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getUserGroupStorage(); - this.allGroups = this.groupStorage.findAll(); - this.allRoles = this.roleStorage.findAll(); + this.roleStorage = resourceManager.getRoleStorage(); + this.groupStorage = resourceManager.getUserGroupStorage(); + this.env = Environments.getEnvironment(); this.permissionStorage = resourceManager.managePermissions().getDb(); this.configurationStorage = resourceManager.getCoreConfigurationStorage(); @@ -110,7 +106,8 @@ public class UserService { } user = (UserAccount) userStorage.getUserById(principalId); - return OidcUserAccountDetails.create(user, attributes, idToken, userInfo, permissionStorage); + return OidcUserAccountDetails + .create(user, attributes, idToken, userInfo, permissionStorage, roleStorage, groupStorage); } else { throw new OAuth2AuthenticationProcessingException( String.format("No config found for provider %s", registrationId) @@ -122,13 +119,13 @@ public class UserService { OAuthConfiguration oAuthConfig, Map<String, Object> attributes, boolean newUser) { + var allRoles = roleStorage.findAll(); if (oAuthConfig.getRoleAttributeName() != null) { Object rolesObject = attributes.get(oAuthConfig.getRoleAttributeName()); - + var allGroups = groupStorage.findAll(); if (rolesObject instanceof List<?> rolesList) { Set<String> roles = extractRoleOrGroup("ROLE", rolesList); Set<String> groups = convertGroup(extractRoleOrGroup("GROUP", rolesList)); - allRoles.forEach(role -> { if (Objects.nonNull(role.getAlternateIds())) { role.getAlternateIds().forEach(a -> { @@ -158,17 +155,18 @@ public class UserService { oAuthConfig.getRoleAttributeName(), Objects.nonNull(rolesObject) ? rolesObject.getClass().getName() : "null" ); - applyDefaultRole(user, oAuthConfig.getDefaultRoles(), newUser); + applyDefaultRole(user, oAuthConfig.getDefaultRoles(), newUser, allRoles); } } else { LOG.warn("Applying default roles as no role attribute is configured"); - applyDefaultRole(user, oAuthConfig.getDefaultRoles(), newUser); + applyDefaultRole(user, oAuthConfig.getDefaultRoles(), newUser, allRoles); } } private void applyDefaultRole(UserAccount user, Set<String> defaultRoles, - boolean newUser) { + boolean newUser, + List<Role> allRoles) { if (newUser) { user.setRoles( defaultRoles diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/storage/StorageApiConfiguration.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/storage/StorageApiConfiguration.java index 6aea14cbf7..fcd54adc84 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/storage/StorageApiConfiguration.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/storage/StorageApiConfiguration.java @@ -29,6 +29,8 @@ import org.apache.streampipes.storage.api.system.IAssetStorage; import org.apache.streampipes.storage.api.system.IFileMetadataStorage; import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.storage.couchdb.impl.connect.AdapterInstanceStorageImpl; import org.apache.streampipes.storage.couchdb.impl.explorer.ChartStorageImpl; import org.apache.streampipes.storage.couchdb.impl.explorer.DashboardStorageImpl; @@ -39,6 +41,8 @@ import org.apache.streampipes.storage.couchdb.impl.system.AssetStorageImpl; import org.apache.streampipes.storage.couchdb.impl.system.CoreConfigurationStorageImpl; import org.apache.streampipes.storage.couchdb.impl.system.FileMetadataStorageImpl; import org.apache.streampipes.storage.couchdb.impl.user.PermissionStorageImpl; +import org.apache.streampipes.storage.couchdb.impl.user.RoleStorageImpl; +import org.apache.streampipes.storage.couchdb.impl.user.UserGroupStorageImpl; import org.apache.streampipes.storage.couchdb.utils.Utils; import org.springframework.beans.factory.annotation.Value; @@ -131,4 +135,14 @@ public class StorageApiConfiguration { ); return dataLakeMeasureCacheEnabled ? new CachedDataLakeMeasureStorage(delegate, cacheManager) : delegate; } + + @Bean + public IRoleStorage roleStorage() { + return new RoleStorageImpl(); + } + + @Bean + public IUserGroupStorage userGroupStorage() { + return new UserGroupStorageImpl(); + } } diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/core/INoSqlStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/core/INoSqlStorage.java index 90fb043409..171a5cdf53 100644 --- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/core/INoSqlStorage.java +++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/core/INoSqlStorage.java @@ -35,9 +35,7 @@ import org.apache.streampipes.storage.api.system.ITransformationScriptTemplateSt import org.apache.streampipes.storage.api.user.IPasswordRecoveryTokenStorage; import org.apache.streampipes.storage.api.user.IPrivilegeStorage; import org.apache.streampipes.storage.api.user.IRefreshTokenStorage; -import org.apache.streampipes.storage.api.user.IRoleStorage; import org.apache.streampipes.storage.api.user.IUserActivationTokenStorage; -import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.storage.api.user.IUserStorage; public interface INoSqlStorage { @@ -48,8 +46,6 @@ public interface INoSqlStorage { IImageStorage getImageStorage(); - IUserGroupStorage getUserGroupStorage(); - IUserStorage getUserStorageAPI(); IFileMetadataStorage getFileMetadataStorage(); @@ -76,8 +72,6 @@ public interface INoSqlStorage { IExtensionsServiceConfigurationStorage getExtensionsServiceConfigurationStorage(); - IRoleStorage getRoleStorage(); - IPrivilegeStorage getPrivilegeStorage(); ICompactPipelineTemplateStorage getPipelineTemplateStorage(); diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java index 561eed5cca..4bb057acd3 100644 --- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java +++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java @@ -36,9 +36,7 @@ import org.apache.streampipes.storage.api.system.ITransformationScriptTemplateSt import org.apache.streampipes.storage.api.user.IPasswordRecoveryTokenStorage; import org.apache.streampipes.storage.api.user.IPrivilegeStorage; import org.apache.streampipes.storage.api.user.IRefreshTokenStorage; -import org.apache.streampipes.storage.api.user.IRoleStorage; import org.apache.streampipes.storage.api.user.IUserActivationTokenStorage; -import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.storage.api.user.IUserStorage; import org.apache.streampipes.storage.couchdb.impl.connect.AdapterDescriptionStorageImpl; import org.apache.streampipes.storage.couchdb.impl.pipeline.CompactPipelineTemplateStorageImpl; @@ -58,9 +56,7 @@ import org.apache.streampipes.storage.couchdb.impl.system.TransformationScriptTe import org.apache.streampipes.storage.couchdb.impl.user.PasswordRecoveryTokenStorageImpl; import org.apache.streampipes.storage.couchdb.impl.user.PrivilegeStorageImpl; import org.apache.streampipes.storage.couchdb.impl.user.RefreshTokenStorageImpl; -import org.apache.streampipes.storage.couchdb.impl.user.RoleStorageImpl; import org.apache.streampipes.storage.couchdb.impl.user.UserActivationTokenStorageImpl; -import org.apache.streampipes.storage.couchdb.impl.user.UserGroupStorageImpl; import org.apache.streampipes.storage.couchdb.impl.user.UserStorage; public class CouchDbStorageManager implements INoSqlStorage { @@ -80,11 +76,6 @@ public class CouchDbStorageManager implements INoSqlStorage { return new ImageStorageImpl(); } - @Override - public IUserGroupStorage getUserGroupStorage() { - return new UserGroupStorageImpl(); - } - @Override public IUserStorage getUserStorageAPI() { return new UserStorage(); @@ -150,11 +141,6 @@ public class CouchDbStorageManager implements INoSqlStorage { return new ExtensionsServiceConfigurationStorageImpl(); } - @Override - public IRoleStorage getRoleStorage() { - return new RoleStorageImpl(); - } - @Override public IPrivilegeStorage getPrivilegeStorage() { return new PrivilegeStorageImpl(); diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/authorization/RoleManager.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/authorization/RoleManager.java index aae43d3d95..27ab58b1e2 100644 --- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/authorization/RoleManager.java +++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/authorization/RoleManager.java @@ -22,7 +22,6 @@ import org.apache.streampipes.model.client.user.DefaultPrivilege; import org.apache.streampipes.model.client.user.DefaultRole; import org.apache.streampipes.model.client.user.Role; import org.apache.streampipes.storage.api.user.IRoleStorage; -import org.apache.streampipes.storage.management.StorageDispatcher; import java.util.List; import java.util.stream.Collectors; @@ -32,8 +31,8 @@ public class RoleManager { private final IRoleStorage storage; - public RoleManager() { - this.storage = StorageDispatcher.INSTANCE.getNoSqlStore().getRoleStorage(); + public RoleManager(IRoleStorage roleStorage) { + this.storage = roleStorage; } public List<Role> makeDefaultRoles() { diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/jwt/JwtTokenProvider.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/jwt/JwtTokenProvider.java index beb3bc76d3..c33ffbcb98 100644 --- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/jwt/JwtTokenProvider.java +++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/jwt/JwtTokenProvider.java @@ -27,6 +27,8 @@ import org.apache.streampipes.security.jwt.JwtTokenGenerator; import org.apache.streampipes.security.jwt.JwtTokenUtils; import org.apache.streampipes.security.jwt.JwtTokenValidator; import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.user.management.model.PrincipalUserDetails; import org.apache.streampipes.user.management.util.GrantedAuthoritiesBuilder; import org.apache.streampipes.user.management.util.UserInfoUtil; @@ -53,9 +55,15 @@ public class JwtTokenProvider { private static final Logger LOG = LoggerFactory.getLogger(JwtTokenProvider.class); private Environment env; private final ISpCoreConfigurationStorage coreConfigurationStorage; + private final IRoleStorage roleStorage; + private final IUserGroupStorage userGroupStorage; - public JwtTokenProvider(ISpCoreConfigurationStorage coreConfigurationStorage) { + public JwtTokenProvider(ISpCoreConfigurationStorage coreConfigurationStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { this.coreConfigurationStorage = coreConfigurationStorage; + this.roleStorage = roleStorage; + this.userGroupStorage = userGroupStorage; this.env = Environments.getEnvironment(); } @@ -73,7 +81,7 @@ public class JwtTokenProvider { } public String createToken(Principal userPrincipal) { - Set<String> roles = new GrantedAuthoritiesBuilder(userPrincipal).buildAllAuthorities(); + Set<String> roles = new GrantedAuthoritiesBuilder(userPrincipal, roleStorage, userGroupStorage).buildAllAuthorities(); return createToken(userPrincipal, roles); } diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/PrincipalUserDetails.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/PrincipalUserDetails.java index 7a029b2161..bf32421f89 100644 --- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/PrincipalUserDetails.java +++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/PrincipalUserDetails.java @@ -19,6 +19,8 @@ package org.apache.streampipes.user.management.model; import org.apache.streampipes.model.client.user.Principal; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.user.management.util.GrantedAuthoritiesBuilder; import org.apache.streampipes.user.management.util.GrantedPermissionsBuilder; @@ -37,9 +39,11 @@ public abstract class PrincipalUserDetails<T extends Principal> implements UserD private Set<String> allObjectPermissions; public PrincipalUserDetails(T details, - IPermissionStorage permissionStorage) { + IPermissionStorage permissionStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { this.details = details; - this.allAuthorities = new GrantedAuthoritiesBuilder(details).buildAllAuthorities(); + this.allAuthorities = new GrantedAuthoritiesBuilder(details, roleStorage, userGroupStorage).buildAllAuthorities(); this.allObjectPermissions = new GrantedPermissionsBuilder(details, permissionStorage).buildAllPermissions(); } diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/ServiceAccountDetails.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/ServiceAccountDetails.java index a5ae3758a2..443c6c66e0 100644 --- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/ServiceAccountDetails.java +++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/ServiceAccountDetails.java @@ -19,13 +19,17 @@ package org.apache.streampipes.user.management.model; import org.apache.streampipes.model.client.user.ServiceAccount; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; public class ServiceAccountDetails extends PrincipalUserDetails<ServiceAccount> { public ServiceAccountDetails(ServiceAccount details, - IPermissionStorage permissionStorage) { - super(details, permissionStorage); + IPermissionStorage permissionStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { + super(details, permissionStorage, roleStorage, userGroupStorage); } @Override diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/UserAccountDetails.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/UserAccountDetails.java index 08f4452098..43dab5bdda 100644 --- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/UserAccountDetails.java +++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/UserAccountDetails.java @@ -19,12 +19,16 @@ package org.apache.streampipes.user.management.model; import org.apache.streampipes.model.client.user.UserAccount; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; public class UserAccountDetails extends PrincipalUserDetails<UserAccount> { public UserAccountDetails(UserAccount details, - IPermissionStorage permissionStorage) { - super(details, permissionStorage); + IPermissionStorage permissionStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { + super(details, permissionStorage, roleStorage, userGroupStorage); } @Override diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/service/SpUserDetailsService.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/service/SpUserDetailsService.java index 5fd1bb74fb..c3392a0388 100644 --- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/service/SpUserDetailsService.java +++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/service/SpUserDetailsService.java @@ -21,6 +21,8 @@ import org.apache.streampipes.model.client.user.Principal; import org.apache.streampipes.model.client.user.ServiceAccount; import org.apache.streampipes.model.client.user.UserAccount; import org.apache.streampipes.storage.api.user.IPermissionStorage; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.storage.management.StorageDispatcher; import org.apache.streampipes.user.management.model.ServiceAccountDetails; import org.apache.streampipes.user.management.model.UserAccountDetails; @@ -32,15 +34,26 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; public class SpUserDetailsService implements UserDetailsService { private final IPermissionStorage permissionStorage; + private final IRoleStorage roleStorage; + private final IUserGroupStorage userGroupStorage; - public SpUserDetailsService(IPermissionStorage permissionStorage) { + public SpUserDetailsService(IPermissionStorage permissionStorage, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { this.permissionStorage = permissionStorage; + this.roleStorage = roleStorage; + this.userGroupStorage = userGroupStorage; } @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { Principal user = StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI().getUser(s); - return user instanceof UserAccount ? new UserAccountDetails((UserAccount) user, permissionStorage) : - new ServiceAccountDetails((ServiceAccount) user, permissionStorage); + return user instanceof UserAccount ? new UserAccountDetails( + (UserAccount) user, + permissionStorage, + roleStorage, + userGroupStorage + ) : + new ServiceAccountDetails((ServiceAccount) user, permissionStorage, roleStorage, userGroupStorage); } } diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedAuthoritiesBuilder.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedAuthoritiesBuilder.java index 057c4bd1aa..5652ea7299 100644 --- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedAuthoritiesBuilder.java +++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedAuthoritiesBuilder.java @@ -18,7 +18,8 @@ package org.apache.streampipes.user.management.util; import org.apache.streampipes.model.client.user.Principal; -import org.apache.streampipes.storage.management.StorageDispatcher; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; import org.apache.streampipes.user.management.authorization.RoleManager; import java.util.HashSet; @@ -28,10 +29,16 @@ public class GrantedAuthoritiesBuilder { private final Set<String> allAuthorities; private final Principal principal; + private final IRoleStorage roleStorage; + private final IUserGroupStorage userGroupStorage; - public GrantedAuthoritiesBuilder(Principal principal) { + public GrantedAuthoritiesBuilder(Principal principal, + IRoleStorage roleStorage, + IUserGroupStorage userGroupStorage) { this.allAuthorities = new HashSet<>(); this.principal = principal; + this.roleStorage = roleStorage; + this.userGroupStorage = userGroupStorage; } public Set<String> buildAllAuthorities() { @@ -48,8 +55,7 @@ public class GrantedAuthoritiesBuilder { private Set<String> buildAllGroupRoles() { Set<String> allRoles = new HashSet<>(); principal.getGroups().forEach(groupId -> { - Set<String> groupRoles = - StorageDispatcher.INSTANCE.getNoSqlStore().getUserGroupStorage().getElementById(groupId).getRoles(); + Set<String> groupRoles = userGroupStorage.getElementById(groupId).getRoles(); allRoles.addAll(buildAllRoles(groupRoles)); }); @@ -59,7 +65,7 @@ public class GrantedAuthoritiesBuilder { private Set<String> buildAllRoles(Set<String> originalRoles) { Set<String> roles = new HashSet<>(); originalRoles.forEach(role -> { - roles.addAll(new RoleManager().getPrivileges(role)); + roles.addAll(new RoleManager(roleStorage).getPrivileges(role)); }); return roles; }
