This is an automated email from the ASF dual-hosted git repository. riemer pushed a commit to branch remove-asset-user-role in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit a33e0bb5b19cf6abb945c49377bcb9cc21b36e20 Author: Dominik Riemer <[email protected]> AuthorDate: Fri Mar 6 11:07:36 2026 +0100 feat: Remove obsolete asset user role --- .../streampipes/model/client/user/DefaultRole.java | 2 - .../rest/impl/AssetManagementResource.java | 11 +-- .../core/migrations/AvailableMigrations.java | 4 +- .../v099/RemoveAssetUserRoleMigration.java | 90 ++++++++++++++++++++++ .../user/management/authorization/RoleManager.java | 6 -- .../userManagement/testUserRoleAssets.spec.ts | 2 +- ui/deployment/modules.yml | 2 +- .../asset-browser-toolbar.component.ts | 6 +- .../asset-browser/asset-browser.service.ts | 10 --- ui/src/app/_enums/user-role.enum.ts | 1 - .../chart-overview-table.component.ts | 3 - .../role-configuration.component.ts | 2 + .../existing-adapters.component.ts | 3 - .../dashboard-overview-table.component.ts | 3 - ui/src/app/pipelines/pipelines.component.ts | 3 - ui/src/app/services/available-roles.service.ts | 12 ++- 16 files changed, 111 insertions(+), 49 deletions(-) diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/DefaultRole.java b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/DefaultRole.java index 85223556b2..672f485b38 100644 --- a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/DefaultRole.java +++ b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/DefaultRole.java @@ -31,7 +31,6 @@ public enum DefaultRole { ROLE_DATA_EXPLORER_ADMIN(Constants.ROLE_DATA_EXPLORER_ADMIN_VALUE), ROLE_DATA_EXPLORER_USER(Constants.ROLE_DATA_EXPLORER_USER_VALUE), ROLE_CONNECT_ADMIN(Constants.ROLE_CONNECT_ADMIN_VALUE), - ROLE_ASSET_USER(Constants.ROLE_ASSET_USER_VALUE), ROLE_ASSET_ADMIN(Constants.ROLE_ASSET_ADMIN_VALUE); DefaultRole(String roleString) { @@ -47,7 +46,6 @@ public enum DefaultRole { public static final String ROLE_DASHBOARD_USER_VALUE = "ROLE_DASHBOARD_USER"; public static final String ROLE_DATA_EXPLORER_USER_VALUE = "ROLE_DATA_EXPLORER_USER"; public static final String ROLE_PIPELINE_USER_VALUE = "ROLE_PIPELINE_USER"; - public static final String ROLE_ASSET_USER_VALUE = "ROLE_ASSET_USER"; public static final String ROLE_ASSET_ADMIN_VALUE = "ROLE_ASSET_ADMIN"; } } diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AssetManagementResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AssetManagementResource.java index a4a3330535..897285c710 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AssetManagementResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AssetManagementResource.java @@ -55,7 +55,7 @@ public class AssetManagementResource extends AbstractAuthGuardedRestResource { } @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) - @PreAuthorize(AuthConstants.HAS_READ_ASSETS_PRIVILEGE) + @PreAuthorize(AuthConstants.IS_AUTHENTICATED) @PostFilter("hasPermission(filterObject.elementId, 'READ')") public List<SpAssetModel> getAll() { return resourceManager.findAll(); @@ -69,7 +69,7 @@ public class AssetManagementResource extends AbstractAuthGuardedRestResource { } @GetMapping(path = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) - @PreAuthorize("this.hasReadAuthority() and hasPermission(#elementId, 'READ')") + @PreAuthorize(AuthConstants.IS_AUTHENTICATED + " and hasPermission(#elementId, 'READ')") public ResponseEntity<SpAssetModel> getAsset(@PathVariable("id") String elementId) { var obj = resourceManager.find(elementId); if (obj != null) { @@ -98,13 +98,6 @@ public class AssetManagementResource extends AbstractAuthGuardedRestResource { return ok(); } - /** - * required by Spring expression - */ - public boolean hasReadAuthority() { - return isAdminOrHasAnyAuthority(DefaultPrivilege.Constants.PRIVILEGE_READ_ASSETS_VALUE); - } - /** * required by Spring expression */ 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 ecdbc1f292..e0d189ac59 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 @@ -33,6 +33,7 @@ import org.apache.streampipes.service.core.migrations.v099.CreateAssetPermission import org.apache.streampipes.service.core.migrations.v099.CreateDatasetPermissionMigration; import org.apache.streampipes.service.core.migrations.v099.ModifyAssetLinkIconMigration; import org.apache.streampipes.service.core.migrations.v099.MoveAssetContentMigration; +import org.apache.streampipes.service.core.migrations.v099.RemoveAssetUserRoleMigration; import org.apache.streampipes.service.core.migrations.v099.RemoveDuplicatedAssetPermissions; import org.apache.streampipes.service.core.migrations.v099.RemoveObsoletePrivilegesMigration; import org.apache.streampipes.service.core.migrations.v099.UniqueDashboardIdMigration; @@ -62,7 +63,8 @@ public class AvailableMigrations { new ModifyAssetLinkIconMigration(), new RemoveDuplicatedAssetPermissions(), new AddFunctionStateViewMigration(), - new AddRefreshTokenViewsMigration() + new AddRefreshTokenViewsMigration(), + new RemoveAssetUserRoleMigration() ); } } 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 new file mode 100644 index 0000000000..49d1f3488a --- /dev/null +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/RemoveAssetUserRoleMigration.java @@ -0,0 +1,90 @@ +/* + * 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.streampipes.service.core.migrations.v099; + +import org.apache.streampipes.model.client.user.Group; +import org.apache.streampipes.model.client.user.Principal; +import org.apache.streampipes.service.core.migrations.Migration; +import org.apache.streampipes.storage.api.user.IRoleStorage; +import org.apache.streampipes.storage.api.user.IUserGroupStorage; +import org.apache.streampipes.storage.api.user.IUserStorage; +import org.apache.streampipes.storage.management.StorageDispatcher; + +import java.io.IOException; + +public class RemoveAssetUserRoleMigration implements Migration { + + private static final String ROLE_ASSET_USER = "ROLE_ASSET_USER"; + + private final IRoleStorage roleStorage; + private final IUserStorage userStorage; + private final IUserGroupStorage userGroupStorage; + + public RemoveAssetUserRoleMigration() { + this.roleStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getRoleStorage(); + this.userStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI(); + this.userGroupStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getUserGroupStorage(); + } + + @Override + public boolean shouldExecute() { + return roleStorage.getElementById(ROLE_ASSET_USER) != null + || userStorage.getAllUsers().stream().anyMatch(this::hasAssetUserRole) + || userGroupStorage.findAll().stream().anyMatch(this::hasAssetUserRole); + } + + @Override + public void executeMigration() throws IOException { + userStorage.getAllUsers().stream() + .filter(this::hasAssetUserRole) + .forEach(this::removeAssetUserRole); + + userGroupStorage.findAll().stream() + .filter(this::hasAssetUserRole) + .forEach(this::removeAssetUserRole); + + var assetUserRole = roleStorage.getElementById(ROLE_ASSET_USER); + if (assetUserRole != null) { + roleStorage.deleteElement(assetUserRole); + } + } + + @Override + public String getDescription() { + return "Remove obsolete ROLE_ASSET_USER role and role assignments"; + } + + private boolean hasAssetUserRole(Principal principal) { + return principal.getRoles() != null && principal.getRoles().contains(ROLE_ASSET_USER); + } + + private void removeAssetUserRole(Principal principal) { + principal.getRoles().remove(ROLE_ASSET_USER); + userStorage.updateUser(principal); + } + + private boolean hasAssetUserRole(Group group) { + return group.getRoles() != null && group.getRoles().contains(ROLE_ASSET_USER); + } + + private void removeAssetUserRole(Group group) { + group.getRoles().remove(ROLE_ASSET_USER); + userGroupStorage.updateElement(group); + } +} 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 c0937fa43a..aae43d3d95 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 @@ -78,12 +78,6 @@ public class RoleManager { DefaultPrivilege.Constants.PRIVILEGE_READ_LABELS_VALUE, DefaultPrivilege.Constants.PRIVILEGE_WRITE_LABELS_VALUE )), - Role.createDefaultRole(DefaultRole.Constants.ROLE_ASSET_USER_VALUE, "Asset User", List.of( - DefaultPrivilege.Constants.PRIVILEGE_READ_GENERIC_STORAGE_VALUE, - DefaultPrivilege.Constants.PRIVILEGE_READ_ASSETS_VALUE, - DefaultPrivilege.Constants.PRIVILEGE_READ_LABELS_VALUE, - DefaultPrivilege.Constants.PRIVILEGE_READ_GENERIC_STORAGE_VALUE - )), Role.createDefaultRole(DefaultRole.Constants.ROLE_DATA_EXPLORER_ADMIN_VALUE, "Data Explorer Admin", List.of( DefaultPrivilege.Constants.PRIVILEGE_READ_DATA_EXPLORER_VIEW_VALUE, DefaultPrivilege.Constants.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW_VALUE, diff --git a/ui/cypress/tests/userManagement/testUserRoleAssets.spec.ts b/ui/cypress/tests/userManagement/testUserRoleAssets.spec.ts index f0d389592f..7435fd872c 100644 --- a/ui/cypress/tests/userManagement/testUserRoleAssets.spec.ts +++ b/ui/cypress/tests/userManagement/testUserRoleAssets.spec.ts @@ -34,7 +34,7 @@ describe('Test User Roles for Dashboards', () => { assetUser1 = UserUtils.createUser( 'assetUser1', - UserRole.ROLE_ASSET_USER, + UserRole.ROLE_PIPELINE_USER, ); assetAdmin1 = UserUtils.createUser( diff --git a/ui/deployment/modules.yml b/ui/deployment/modules.yml index b2ddfa2344..f8a7b05de1 100644 --- a/ui/deployment/modules.yml +++ b/ui/deployment/modules.yml @@ -19,7 +19,7 @@ spAssets: link: 'assets' title: 'Assets' icon: 'precision_manufacturing' - privileges: '[UserPrivilege.PRIVILEGE_READ_ASSETS, UserPrivilege.PRIVILEGE_WRITE_ASSETS]' + privileges: '[]' pageNames: 'PageName.ASSETS' showStatusBox: false category: 'management' diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/asset-browser/asset-browser-toolbar/asset-browser-toolbar.component.ts b/ui/projects/streampipes/shared-ui/src/lib/components/asset-browser/asset-browser-toolbar/asset-browser-toolbar.component.ts index 18ce7df345..4710ff4467 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/asset-browser/asset-browser-toolbar/asset-browser-toolbar.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/asset-browser/asset-browser-toolbar/asset-browser-toolbar.component.ts @@ -64,10 +64,8 @@ export class AssetBrowserToolbarComponent implements OnInit, OnDestroy { @ViewChild('menuTrigger') menu: MatMenuTrigger; ngOnInit() { - this.showAssetBrowser = this.currentUserService.hasAnyRole([ - 'PRIVILEGE_READ_ASSETS', - 'PRIVILEGE_WRITE_ASSETS', - ]); + this.showAssetBrowser = + this.currentUserService.getCurrentUser() !== undefined; if (this.showAssetBrowser) { this.assetBrowserData$ = this.assetBrowserService.assetData$.subscribe(assetData => { diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/asset-browser/asset-browser.service.ts b/ui/projects/streampipes/shared-ui/src/lib/components/asset-browser/asset-browser.service.ts index 678c00af81..cc0e150d4d 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/components/asset-browser/asset-browser.service.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/components/asset-browser/asset-browser.service.ts @@ -33,7 +33,6 @@ import { AssetFilter, FilterResult, } from './asset-browser.model'; -import { CurrentUserService } from '../../services/current-user.service'; import { LocalStorageService } from '../../services/local-storage-settings.service'; @Injectable({ providedIn: 'root' }) @@ -51,7 +50,6 @@ export class SpAssetBrowserService { private genericStorageService = inject(GenericStorageService); private typeService = inject(Isa95TypeService); private assetService = inject(AssetManagementService); - private currentUserService = inject(CurrentUserService); constructor() { this.loadAssetData(); @@ -331,12 +329,4 @@ export class SpAssetBrowserService { .filter(a => a.linkType === filteredLinkType) .map(a => a.resourceId); } - - hasNoAssetFilterPermission(): boolean { - return !this.currentUserService.hasAnyRole([ - 'ROLE_ADMIN', - 'ROLE_ASSET_ADMIN', - 'ROLE_ASSET_USER', - ]); - } } diff --git a/ui/src/app/_enums/user-role.enum.ts b/ui/src/app/_enums/user-role.enum.ts index 90471d6248..67b57f42b4 100644 --- a/ui/src/app/_enums/user-role.enum.ts +++ b/ui/src/app/_enums/user-role.enum.ts @@ -28,5 +28,4 @@ export enum UserRole { ROLE_DATA_EXPLORER_USER = 'ROLE_DATA_EXPLORER_USER', ROLE_PIPELINE_USER = 'ROLE_PIPELINE_USER', ROLE_APP_USER = 'ROLE_APP_USER', - ROLE_ASSET_USER = 'ROLE_ASSET_USER', } diff --git a/ui/src/app/chart/components/chart-overview/chart-overview-table/chart-overview-table.component.ts b/ui/src/app/chart/components/chart-overview/chart-overview-table/chart-overview-table.component.ts index f780b77949..efc6c5168c 100644 --- a/ui/src/app/chart/components/chart-overview/chart-overview-table/chart-overview-table.component.ts +++ b/ui/src/app/chart/components/chart-overview/chart-overview-table/chart-overview-table.component.ts @@ -194,9 +194,6 @@ export class ChartOverviewTableComponent implements OnInit { } applyChartFilters(elementIds: Set<string>): void { - if (this.assetFilterService.hasNoAssetFilterPermission()) { - elementIds = new Set<string>(); - } if (elementIds === undefined) { this.filteredCharts = []; } else if (elementIds.size === 0) { diff --git a/ui/src/app/configuration/security-configuration/role-configuration/role-configuration.component.ts b/ui/src/app/configuration/security-configuration/role-configuration/role-configuration.component.ts index 3447409f6b..41821972bf 100644 --- a/ui/src/app/configuration/security-configuration/role-configuration/role-configuration.component.ts +++ b/ui/src/app/configuration/security-configuration/role-configuration/role-configuration.component.ts @@ -71,6 +71,8 @@ import { MatTooltip } from '@angular/material/tooltip'; ], }) export class SecurityRoleConfigComponent implements OnInit { + private static readonly ASSET_USER_ROLE = 'ROLE_ASSET_USER'; + @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; diff --git a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.ts b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.ts index ec24f0f501..bd0e80bc78 100644 --- a/ui/src/app/connect/components/existing-adapters/existing-adapters.component.ts +++ b/ui/src/app/connect/components/existing-adapters/existing-adapters.component.ts @@ -360,9 +360,6 @@ export class ExistingAdaptersComponent implements OnInit, OnDestroy { } applyAdapterFilters(elementIds: Set<string>): void { - if (this.assetFilterService.hasNoAssetFilterPermission()) { - elementIds = new Set<string>(); - } this.currentFilterIds = elementIds; this.filteredAdapters = this.adapterFilter .transform(this.existingAdapters, this.currentFilter) diff --git a/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.ts b/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.ts index 8b869e6b28..2d1e0ead40 100644 --- a/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.ts +++ b/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.ts @@ -210,9 +210,6 @@ export class DashboardOverviewTableComponent implements OnInit, OnDestroy { } applyDashboardFilters(elementIds: Set<string>): void { - if (this.assetFilterService.hasNoAssetFilterPermission()) { - elementIds = new Set<string>(); - } if (elementIds == undefined) { this.filteredDashboards = []; } else if (elementIds.size == 0) { diff --git a/ui/src/app/pipelines/pipelines.component.ts b/ui/src/app/pipelines/pipelines.component.ts index 3d2dae8ac8..8409e1fef9 100644 --- a/ui/src/app/pipelines/pipelines.component.ts +++ b/ui/src/app/pipelines/pipelines.component.ts @@ -150,9 +150,6 @@ export class PipelinesComponent implements OnInit, OnDestroy { } applyPipelineFilters(elementIds: Set<string>) { - if (this.assetFilterService.hasNoAssetFilterPermission()) { - elementIds = new Set<string>(); - } this.currentFilters = elementIds; if (elementIds === undefined) { this.filteredPipelines = []; diff --git a/ui/src/app/services/available-roles.service.ts b/ui/src/app/services/available-roles.service.ts index 301ecfd4fa..f7e1f99424 100644 --- a/ui/src/app/services/available-roles.service.ts +++ b/ui/src/app/services/available-roles.service.ts @@ -18,10 +18,12 @@ import { Injectable } from '@angular/core'; import { Role, RoleService } from '@streampipes/platform-services'; -import { BehaviorSubject, Observable, shareReplay } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class AvailableRolesService { + private static readonly ASSET_USER_ROLE = 'ROLE_ASSET_USER'; + private availableRolesSubject: BehaviorSubject<Role[]> = new BehaviorSubject<Role[]>([]); public availableRoles$: Observable<Role[]> = @@ -33,7 +35,13 @@ export class AvailableRolesService { private loadRoles(): void { this.roleService.findAll().subscribe(roles => { - this.availableRolesSubject.next(roles); + this.availableRolesSubject.next( + roles.filter( + role => + role.elementId !== + AvailableRolesService.ASSET_USER_ROLE, + ), + ); }); }
