You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2026/06/18 16:46:53 UTC
(streampipes) 03/04: Add permission cache
This is an automated email from the ASF dual-hosted git repository.
dominikriemer pushed a commit to branch introduce-storage-cache
in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 8a0610629b742d1e06f5e84c02b6b0e3d24c9f7d
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Thu Jun 18 17:30:26 2026 +0200
Add permission cache
---
.../dataexplorer/api/IDataExplorerManager.java | 4 +-
.../influx/DataExplorerManagerInflux.java | 6 +-
.../iotdb/DataExplorerManagerIotDb.java | 8 +-
.../loadbalance/unit/InvokeHttpRequest.java | 3 +-
.../AbstractPipelineElementResourceManager.java | 3 +-
.../management/AdapterResourceManager.java | 9 +-
.../resource/management/AssetResourceManager.java | 4 +-
.../resource/management/CrudResourceManager.java | 2 +-
.../management/DataLakeMeasureResourceManager.java | 4 +-
.../management/PermissionResourceManager.java | 5 -
.../resource/management/SpResourceManager.java | 6 +-
.../permission/SpPermissionEvaluator.java | 5 +-
.../management/AdapterResourceManagerTest.java | 2 +-
.../apache/streampipes/rest/ResetManagement.java | 2 +-
.../rest/impl/AdapterMonitoringResource.java | 2 +-
.../rest/impl/connect/AdapterResource.java | 2 +-
.../impl/datalake/AbstractDataLakeResource.java | 10 +-
.../impl/datalake/DataLakeMeasureResource.java | 2 +-
.../rest/impl/datalake/DataLakeResource.java | 6 +-
.../datalake/KioskDashboardDataLakeResource.java | 10 +-
.../datalake/importer/DataLakeImportResource.java | 6 +-
.../service/core/WebSecurityConfig.java | 11 +-
.../core/filter/TokenAuthenticationFilter.java | 9 +-
.../core/oauth2/CustomOAuth2UserService.java | 9 +-
.../service/core/oauth2/CustomOidcUserService.java | 8 +-
.../core/oauth2/OidcUserAccountDetails.java | 11 +-
.../service/core/oauth2/UserService.java | 33 +--
.../service/core/scheduler/DataLakeScheduler.java | 6 +-
.../core/storage/CachedPermissionStorage.java | 236 +++++++++++++++++++++
.../core/storage/StorageApiConfiguration.java | 7 +-
.../src/main/resources/application.properties | 2 +-
.../core/storage/CachedPermissionStorageTest.java | 122 +++++++++++
.../storage/api/core/INoSqlStorage.java | 3 -
.../storage/couchdb/CouchDbStorageManager.java | 7 -
.../management/model/PrincipalUserDetails.java | 6 +-
.../management/model/ServiceAccountDetails.java | 6 +-
.../user/management/model/UserAccountDetails.java | 6 +-
.../management/service/SpUserDetailsService.java | 11 +-
.../management/util/GrantedPermissionsBuilder.java | 12 +-
39 files changed, 504 insertions(+), 102 deletions(-)
diff --git a/streampipes-data-explorer-api/src/main/java/org/apache/streampipes/dataexplorer/api/IDataExplorerManager.java b/streampipes-data-explorer-api/src/main/java/org/apache/streampipes/dataexplorer/api/IDataExplorerManager.java
index 3de231ca5f..3f87b4b5f5 100644
--- a/streampipes-data-explorer-api/src/main/java/org/apache/streampipes/dataexplorer/api/IDataExplorerManager.java
+++ b/streampipes-data-explorer-api/src/main/java/org/apache/streampipes/dataexplorer/api/IDataExplorerManager.java
@@ -21,6 +21,7 @@ package org.apache.streampipes.dataexplorer.api;
import org.apache.streampipes.client.api.IStreamPipesClient;
import org.apache.streampipes.manager.pipeline.update.ChartSchemaUpdateCoordinator;
import org.apache.streampipes.model.datalake.DataLakeMeasure;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
import java.util.List;
@@ -42,7 +43,8 @@ public interface IDataExplorerManager {
IDataExplorerQueryManagement getQueryManagement(IDataExplorerSchemaManagement dataExplorerSchemaManagement);
- IDataExplorerSchemaManagement getSchemaManagement(ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator);
+ IDataExplorerSchemaManagement getSchemaManagement(ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator,
+ IPermissionStorage permissionStorage);
default ITimeSeriesStorage getTimeseriesStorage(DataLakeMeasure measure) {
return getTimeseriesStorage(measure, false);
diff --git a/streampipes-data-explorer-influx/src/main/java/org/apache/streampipes/dataexplorer/influx/DataExplorerManagerInflux.java b/streampipes-data-explorer-influx/src/main/java/org/apache/streampipes/dataexplorer/influx/DataExplorerManagerInflux.java
index 8d600847d5..181ecb5be5 100644
--- a/streampipes-data-explorer-influx/src/main/java/org/apache/streampipes/dataexplorer/influx/DataExplorerManagerInflux.java
+++ b/streampipes-data-explorer-influx/src/main/java/org/apache/streampipes/dataexplorer/influx/DataExplorerManagerInflux.java
@@ -32,6 +32,7 @@ import org.apache.streampipes.dataexplorer.influx.sanitize.DataLakeMeasurementSa
import org.apache.streampipes.manager.permission.DataLakePermissionManager;
import org.apache.streampipes.manager.pipeline.update.ChartSchemaUpdateCoordinator;
import org.apache.streampipes.model.datalake.DataLakeMeasure;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;
import java.util.List;
@@ -57,12 +58,13 @@ public class DataExplorerManagerInflux implements IDataExplorerManager {
}
@Override
- public IDataExplorerSchemaManagement getSchemaManagement(ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator) {
+ public IDataExplorerSchemaManagement getSchemaManagement(ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator,
+ IPermissionStorage permissionStorage) {
return new DataExplorerSchemaManagement(StorageDispatcher.INSTANCE
.getNoSqlStore()
.getDataLakeStorage(),
new DataLakePermissionManager(
- StorageDispatcher.INSTANCE.getNoSqlStore().getPermissionStorage()
+ permissionStorage
),
chartSchemaUpdateCoordinator
);
diff --git a/streampipes-data-explorer-iotdb/src/main/java/org/apache/streampipes/dataexplorer/iotdb/DataExplorerManagerIotDb.java b/streampipes-data-explorer-iotdb/src/main/java/org/apache/streampipes/dataexplorer/iotdb/DataExplorerManagerIotDb.java
index 4db64664d7..a8c31313d9 100644
--- a/streampipes-data-explorer-iotdb/src/main/java/org/apache/streampipes/dataexplorer/iotdb/DataExplorerManagerIotDb.java
+++ b/streampipes-data-explorer-iotdb/src/main/java/org/apache/streampipes/dataexplorer/iotdb/DataExplorerManagerIotDb.java
@@ -31,6 +31,7 @@ import org.apache.streampipes.dataexplorer.iotdb.sanitize.DataLakeMeasurementSan
import org.apache.streampipes.manager.permission.DataLakePermissionManager;
import org.apache.streampipes.manager.pipeline.update.ChartSchemaUpdateCoordinator;
import org.apache.streampipes.model.datalake.DataLakeMeasure;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;
import java.util.List;
@@ -53,13 +54,12 @@ public class DataExplorerManagerIotDb implements IDataExplorerManager {
}
@Override
- public IDataExplorerSchemaManagement getSchemaManagement(ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator) {
+ public IDataExplorerSchemaManagement getSchemaManagement(ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator,
+ IPermissionStorage permissionStorage) {
return new DataExplorerSchemaManagement(StorageDispatcher.INSTANCE
.getNoSqlStore()
.getDataLakeStorage(),
- new DataLakePermissionManager(
- StorageDispatcher.INSTANCE.getNoSqlStore().getPermissionStorage()
- ),
+ new DataLakePermissionManager(permissionStorage),
chartSchemaUpdateCoordinator
);
}
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 ba7d6026c9..0af6c20bcd 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
@@ -23,6 +23,7 @@ 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.serializers.json.JacksonSerializer;
+import org.apache.streampipes.storage.couchdb.impl.user.PermissionStorageImpl;
import org.apache.streampipes.storage.management.StorageDispatcher;
import org.apache.streampipes.user.management.jwt.JwtTokenProvider;
@@ -121,7 +122,7 @@ public class InvokeHttpRequest{
}
private static String getOwnerSid(String resourceId) {
- return StorageDispatcher.INSTANCE.getNoSqlStore().getPermissionStorage().getUserPermissionsForObject(resourceId)
+ return new PermissionStorageImpl("users/permissions").getUserPermissionsForObject(resourceId)
.stream()
.findFirst()
.map(Permission::getOwnerSid)
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AbstractPipelineElementResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AbstractPipelineElementResourceManager.java
index 2e4ee34f18..4ca033cf56 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AbstractPipelineElementResourceManager.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AbstractPipelineElementResourceManager.java
@@ -78,8 +78,7 @@ public abstract class AbstractPipelineElementResourceManager<T extends CRUDStora
W existing = find(pipelineElement.getElementId());
if (existing == null) {
this.db.persist(pipelineElement);
- new PermissionResourceManager()
- .createDefault(pipelineElement.getElementId(), SpDataStream.class, principalSid, false);
+ permissionResourceManager.createDefault(pipelineElement.getElementId(), SpDataStream.class, principalSid, false);
} else {
throw new IllegalArgumentException("This pipeline element already exists");
}
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AdapterResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AdapterResourceManager.java
index f3ba00fc39..b4ff3cbed2 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AdapterResourceManager.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AdapterResourceManager.java
@@ -36,17 +36,18 @@ public class AdapterResourceManager extends AbstractResourceManager<IAdapterStor
private final SpPermissionEvaluator permissionEvaluator;
public AdapterResourceManager(IAdapterStorage adapterStorage,
- ICertificateStorage certificateStorage) {
+ ICertificateStorage certificateStorage,
+ PermissionResourceManager permissionResourceManager) {
super(adapterStorage);
this.certificateStorage = certificateStorage;
- this.permissionEvaluator = new SpPermissionEvaluator();
+ this.permissionEvaluator = new SpPermissionEvaluator(permissionResourceManager.getDb());
}
- public AdapterResourceManager() {
+ public AdapterResourceManager(PermissionResourceManager permissionResourceManager) {
super(StorageDispatcher.INSTANCE.getNoSqlStore()
.getAdapterInstanceStorage());
this.certificateStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getCertificateStorage();
- this.permissionEvaluator = new SpPermissionEvaluator();
+ this.permissionEvaluator = new SpPermissionEvaluator(permissionResourceManager.getDb());
}
public ResourceSummaryDto<AdapterSummaryDto> getSummary(Authentication auth) {
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AssetResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AssetResourceManager.java
index b8aa3a0ba4..ecd02ee85f 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AssetResourceManager.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AssetResourceManager.java
@@ -31,9 +31,9 @@ public class AssetResourceManager extends AbstractResourceManager<IAssetStorage>
private final SpPermissionEvaluator permissionEvaluator;
- public AssetResourceManager() {
+ public AssetResourceManager(PermissionResourceManager permissionResourceManager) {
super(StorageDispatcher.INSTANCE.getNoSqlStore().getAssetStorage());
- this.permissionEvaluator = new SpPermissionEvaluator();
+ this.permissionEvaluator = new SpPermissionEvaluator(permissionResourceManager.getDb());
}
public ResourceSummaryDto<AssetSummaryDto> getSummary(Authentication auth) {
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/CrudResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/CrudResourceManager.java
index 8951bbb6ad..edb0586267 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/CrudResourceManager.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/CrudResourceManager.java
@@ -37,7 +37,7 @@ public class CrudResourceManager<T extends Storable>
PermissionResourceManager permissionResourceManager) {
super(db);
this.elementClass = elementClass;
- this.permissionEvaluator = new SpPermissionEvaluator();
+ this.permissionEvaluator = new SpPermissionEvaluator(permissionResourceManager.getDb());
this.permissionResourceManager = permissionResourceManager;
}
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataLakeMeasureResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataLakeMeasureResourceManager.java
index a80c7280e1..ee8892818f 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataLakeMeasureResourceManager.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataLakeMeasureResourceManager.java
@@ -46,10 +46,10 @@ public class DataLakeMeasureResourceManager extends AbstractResourceManager<IDat
private final IPipelineStorage pipelineStorage;
private final SpPermissionEvaluator permissionEvaluator;
- public DataLakeMeasureResourceManager() {
+ public DataLakeMeasureResourceManager(PermissionResourceManager permissionResourceManager) {
super(StorageDispatcher.INSTANCE.getNoSqlStore().getDataLakeStorage());
this.pipelineStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getPipelineStorageAPI();
- this.permissionEvaluator = new SpPermissionEvaluator();
+ this.permissionEvaluator = new SpPermissionEvaluator(permissionResourceManager.getDb());
}
public ResourceSummaryDto<DatasetSummaryDto> getSummary(Authentication auth) {
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/PermissionResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/PermissionResourceManager.java
index b9b5751968..ea72f5b75c 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/PermissionResourceManager.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/PermissionResourceManager.java
@@ -21,7 +21,6 @@ import org.apache.streampipes.model.client.user.Permission;
import org.apache.streampipes.model.client.user.PermissionBuilder;
import org.apache.streampipes.model.dashboard.DashboardModel;
import org.apache.streampipes.storage.api.user.IPermissionStorage;
-import org.apache.streampipes.storage.management.StorageDispatcher;
import java.util.List;
@@ -31,10 +30,6 @@ public class PermissionResourceManager extends AbstractResourceManager<IPermissi
DashboardModel.class.getCanonicalName()
);
- public PermissionResourceManager() {
- super(StorageDispatcher.INSTANCE.getNoSqlStore().getPermissionStorage());
- }
-
public PermissionResourceManager(IPermissionStorage permissionStorage) {
super(permissionStorage);
}
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 83107b42e1..11a9e08d96 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
@@ -49,15 +49,15 @@ public class SpResourceManager {
}
public AssetResourceManager manageAssets() {
- return new AssetResourceManager();
+ return new AssetResourceManager(managePermissions());
}
public AdapterResourceManager manageAdapters() {
- return new AdapterResourceManager();
+ return new AdapterResourceManager(managePermissions());
}
public DataLakeMeasureResourceManager manageDataLakeMeasures() {
- return new DataLakeMeasureResourceManager();
+ return new DataLakeMeasureResourceManager(managePermissions());
}
public PermissionResourceManager managePermissions() {
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/permission/SpPermissionEvaluator.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/permission/SpPermissionEvaluator.java
index 0c208847c4..ce6f451c7d 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/permission/SpPermissionEvaluator.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/permission/SpPermissionEvaluator.java
@@ -22,7 +22,6 @@ import org.apache.streampipes.model.client.user.Permission;
import org.apache.streampipes.model.pipeline.PipelineElementRecommendation;
import org.apache.streampipes.model.pipeline.PipelineElementRecommendationMessage;
import org.apache.streampipes.storage.api.user.IPermissionStorage;
-import org.apache.streampipes.storage.management.StorageDispatcher;
import org.apache.streampipes.user.management.model.PrincipalUserDetails;
import org.springframework.security.access.PermissionEvaluator;
@@ -40,8 +39,8 @@ public class SpPermissionEvaluator implements PermissionEvaluator {
private final IPermissionStorage permissionStorage;
- public SpPermissionEvaluator() {
- this.permissionStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getPermissionStorage();
+ public SpPermissionEvaluator(IPermissionStorage permissionStorage) {
+ this.permissionStorage = permissionStorage;
}
/**
diff --git a/streampipes-resource-management/src/test/java/org/apache/streampipes/resource/management/AdapterResourceManagerTest.java b/streampipes-resource-management/src/test/java/org/apache/streampipes/resource/management/AdapterResourceManagerTest.java
index 3e0175c738..ec63f239b9 100644
--- a/streampipes-resource-management/src/test/java/org/apache/streampipes/resource/management/AdapterResourceManagerTest.java
+++ b/streampipes-resource-management/src/test/java/org/apache/streampipes/resource/management/AdapterResourceManagerTest.java
@@ -43,7 +43,7 @@ public class AdapterResourceManagerTest {
@BeforeEach
void setUp() {
storage = mock(IAdapterStorage.class);
- adapterResourceManager = new AdapterResourceManager(storage, null);
+ adapterResourceManager = new AdapterResourceManager(storage, null, null);
}
@Test
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java
index 9d3e764166..50065f2b22 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/ResetManagement.java
@@ -158,7 +158,7 @@ public class ResetManagement {
private void removeAllDataInDataLake() {
var dataLakeMeasureManagement = new DataExplorerDispatcher()
.getDataExplorerManager()
- .getSchemaManagement(chartSchemaUpdateCoordinator);
+ .getSchemaManagement(chartSchemaUpdateCoordinator, resourceManager.managePermissions().getDb());
var dataExplorerQueryManagement = new DataExplorerDispatcher()
.getDataExplorerManager()
.getQueryManagement(dataLakeMeasureManagement);
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AdapterMonitoringResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AdapterMonitoringResource.java
index cb13ff6e73..4fa53dbe19 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AdapterMonitoringResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AdapterMonitoringResource.java
@@ -130,7 +130,7 @@ public class AdapterMonitoringResource extends AbstractMonitoringResource {
*/
private boolean checkAdapterPermission(AdapterDescription adapterDescription,
String permission) {
- var spPermissionEvaluator = new SpPermissionEvaluator();
+ var spPermissionEvaluator = new SpPermissionEvaluator(resourceManager.managePermissions().getDb());
var authentication = SecurityContextHolder.getContext()
.getAuthentication();
return spPermissionEvaluator.hasPermission(
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
index da43b782af..86eae06dca 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
@@ -218,7 +218,7 @@ public class AdapterResource extends AbstractAdapterResource<AdapterMasterManage
*/
private boolean checkAdapterPermission(AdapterDescription adapterDescription,
String permission) {
- var spPermissionEvaluator = new SpPermissionEvaluator();
+ var spPermissionEvaluator = new SpPermissionEvaluator(resourceManager.managePermissions().getDb());
var authentication = SecurityContextHolder.getContext()
.getAuthentication();
return spPermissionEvaluator.hasPermission(
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/AbstractDataLakeResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/AbstractDataLakeResource.java
index b24717c1bd..ef9dab09b2 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/AbstractDataLakeResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/AbstractDataLakeResource.java
@@ -21,6 +21,7 @@ import org.apache.streampipes.dataexplorer.api.IDataExplorerSchemaManagement;
import org.apache.streampipes.dataexplorer.management.DataExplorerDispatcher;
import org.apache.streampipes.manager.pipeline.update.ChartSchemaUpdateCoordinator;
import org.apache.streampipes.model.client.user.DefaultPrivilege;
+import org.apache.streampipes.resource.management.SpResourceManager;
import org.apache.streampipes.resource.management.permission.SpPermissionEvaluator;
import org.apache.streampipes.rest.core.base.impl.AbstractAuthGuardedRestResource;
import org.apache.streampipes.storage.api.explorer.IDataLakeMeasureStorage;
@@ -36,11 +37,14 @@ public class AbstractDataLakeResource extends AbstractAuthGuardedRestResource {
private final IDataLakeMeasureStorage dataLakeMeasureStorage =
StorageDispatcher.INSTANCE.getNoSqlStore().getDataLakeStorage();
protected final ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator;
+ private final SpResourceManager resourceManager;
- public AbstractDataLakeResource(ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator) {
+ public AbstractDataLakeResource(ChartSchemaUpdateCoordinator chartSchemaUpdateCoordinator,
+ SpResourceManager resourceManager) {
this.chartSchemaUpdateCoordinator = chartSchemaUpdateCoordinator;
+ this.resourceManager = resourceManager;
this.dataLakeMeasureManagement = new DataExplorerDispatcher().getDataExplorerManager()
- .getSchemaManagement(chartSchemaUpdateCoordinator);
+ .getSchemaManagement(chartSchemaUpdateCoordinator, resourceManager.managePermissions().getDb());
}
/**
@@ -72,7 +76,7 @@ public class AbstractDataLakeResource extends AbstractAuthGuardedRestResource {
var measure = dataLakeMeasureStorage.getByMeasureName(measurementName);
if (Objects.nonNull(measure)) {
- var spPermissionEvaluator = new SpPermissionEvaluator();
+ var spPermissionEvaluator = new SpPermissionEvaluator(resourceManager.managePermissions().getDb());
var authentication = SecurityContextHolder.getContext()
.getAuthentication();
return spPermissionEvaluator.hasPermission(
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeMeasureResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeMeasureResource.java
index bb6b2176c0..b490c591ae 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeMeasureResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeMeasureResource.java
@@ -55,7 +55,7 @@ public class DataLakeMeasureResource extends AbstractDataLakeResource {
public DataLakeMeasureResource(IDataExplorerWidgetStorage chartStorage,
SpResourceManager resourceManager) {
- super(new ChartSchemaUpdateCoordinator(chartStorage));
+ super(new ChartSchemaUpdateCoordinator(chartStorage), resourceManager);
this.resourceManager = resourceManager;
}
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeResource.java
index 1d6dd96d83..d2db088eab 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeResource.java
@@ -31,6 +31,7 @@ import org.apache.streampipes.model.datalake.SpQueryResult;
import org.apache.streampipes.model.datalake.param.ProvidedRestQueryParams;
import org.apache.streampipes.model.message.Notifications;
import org.apache.streampipes.model.monitoring.SpLogMessage;
+import org.apache.streampipes.resource.management.SpResourceManager;
import org.apache.streampipes.rest.security.AuthConstants;
import org.apache.streampipes.rest.shared.exception.SpMessageException;
import org.apache.streampipes.storage.api.explorer.IDataExplorerWidgetStorage;
@@ -97,8 +98,9 @@ public class DataLakeResource extends AbstractDataLakeResource {
private final IDataExplorerQueryManagement dataExplorerQueryManagement;
private final DataLakeExportManager dataLakeExportManager;
- public DataLakeResource(IDataExplorerWidgetStorage chartStorage) {
- super(new ChartSchemaUpdateCoordinator(chartStorage));
+ public DataLakeResource(IDataExplorerWidgetStorage chartStorage,
+ SpResourceManager resourceManager) {
+ super(new ChartSchemaUpdateCoordinator(chartStorage), resourceManager);
this.dataExplorerQueryManagement = new DataExplorerDispatcher()
.getDataExplorerManager()
.getQueryManagement(this.dataLakeMeasureManagement);
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/KioskDashboardDataLakeResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/KioskDashboardDataLakeResource.java
index 84305ad078..1c5b44daad 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/KioskDashboardDataLakeResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/KioskDashboardDataLakeResource.java
@@ -27,6 +27,7 @@ import org.apache.streampipes.model.datalake.DataExplorerWidgetModel;
import org.apache.streampipes.model.datalake.SpQueryResult;
import org.apache.streampipes.model.datalake.param.ProvidedRestQueryParams;
import org.apache.streampipes.model.monitoring.SpLogMessage;
+import org.apache.streampipes.resource.management.SpResourceManager;
import org.apache.streampipes.rest.core.base.impl.AbstractAuthGuardedRestResource;
import org.apache.streampipes.storage.api.explorer.IDataExplorerDashboardStorage;
import org.apache.streampipes.storage.api.explorer.IDataExplorerWidgetStorage;
@@ -56,15 +57,18 @@ public class KioskDashboardDataLakeResource extends AbstractAuthGuardedRestResou
private final IPermissionStorage permissionStorage;
public KioskDashboardDataLakeResource(IDataExplorerWidgetStorage dataExplorerWidgetStorage,
- IPermissionStorage permissionStorage) {
+ SpResourceManager resourceManager) {
IDataExplorerSchemaManagement dataExplorerSchemaManagement = new DataExplorerDispatcher()
.getDataExplorerManager()
- .getSchemaManagement(new ChartSchemaUpdateCoordinator(dataExplorerWidgetStorage));
+ .getSchemaManagement(
+ new ChartSchemaUpdateCoordinator(dataExplorerWidgetStorage),
+ resourceManager.managePermissions().getDb()
+ );
this.dataExplorerQueryManagement = new DataExplorerDispatcher()
.getDataExplorerManager()
.getQueryManagement(dataExplorerSchemaManagement);
this.dataExplorerWidgetStorage = dataExplorerWidgetStorage;
- this.permissionStorage = permissionStorage;
+ this.permissionStorage = resourceManager.managePermissions().getDb();
}
@PostMapping(path = "/{dashboardId}/{widgetId}/data",
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/importer/DataLakeImportResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/importer/DataLakeImportResource.java
index 54a9840f3c..338e8e5762 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/importer/DataLakeImportResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/importer/DataLakeImportResource.java
@@ -26,6 +26,7 @@ import org.apache.streampipes.model.datalake.importer.CsvImportResult;
import org.apache.streampipes.model.datalake.importer.CsvImportSchemaValidationRequest;
import org.apache.streampipes.model.datalake.importer.CsvImportSchemaValidationResult;
import org.apache.streampipes.model.datalake.importer.CsvImportTargetMode;
+import org.apache.streampipes.resource.management.SpResourceManager;
import org.apache.streampipes.rest.impl.datalake.AbstractDataLakeResource;
import org.apache.streampipes.storage.api.explorer.IDataExplorerWidgetStorage;
@@ -48,8 +49,9 @@ public class DataLakeImportResource extends AbstractDataLakeResource {
private final CsvDataLakeImportService importService;
- public DataLakeImportResource(IDataExplorerWidgetStorage chartStorage) {
- super(new ChartSchemaUpdateCoordinator(chartStorage));
+ public DataLakeImportResource(IDataExplorerWidgetStorage chartStorage,
+ SpResourceManager resourceManager) {
+ super(new ChartSchemaUpdateCoordinator(chartStorage), resourceManager);
this.importService = new CsvDataLakeImportService(getDataLakeMeasureManagement());
}
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 229d03e167..eb25ed6f3c 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
@@ -30,6 +30,7 @@ import org.apache.streampipes.service.core.oauth2.OAuth2AccessTokenResponseConve
import org.apache.streampipes.service.core.oauth2.OAuth2AuthenticationFailureHandler;
import org.apache.streampipes.service.core.oauth2.OAuth2AuthenticationSuccessHandler;
import org.apache.streampipes.service.core.oauth2.OAuthEnabledCondition;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
import org.apache.streampipes.user.management.service.SpUserDetailsService;
import org.slf4j.Logger;
@@ -95,10 +96,14 @@ public class WebSecurityConfig {
@Autowired
private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler;
- public WebSecurityConfig(StreamPipesPasswordEncoder passwordEncoder) {
+ private final IPermissionStorage permissionStorage;
+
+ public WebSecurityConfig(StreamPipesPasswordEncoder passwordEncoder,
+ IPermissionStorage permissionStorage) {
this.passwordEncoder = passwordEncoder;
- this.userDetailsService = new SpUserDetailsService();
+ this.userDetailsService = new SpUserDetailsService(permissionStorage);
this.env = Environments.getEnvironment();
+ this.permissionStorage = permissionStorage;
}
@Autowired
@@ -153,7 +158,7 @@ public class WebSecurityConfig {
}
public TokenAuthenticationFilter tokenAuthenticationFilter() {
- return new TokenAuthenticationFilter();
+ return new TokenAuthenticationFilter(permissionStorage);
}
@Bean(BeanIds.USER_DETAILS_SERVICE)
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 6a14bd320f..e91c87e940 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,6 +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.user.IPermissionStorage;
import org.apache.streampipes.storage.api.user.IUserStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;
import org.apache.streampipes.user.management.encryption.SecretEncryptionManager;
@@ -61,6 +62,7 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
private final JwtTokenProvider tokenProvider;
private final IUserStorage userStorage;
+ private final IPermissionStorage permissionStorage;
private final List<String> supportedBasicAuthPaths = List.of(
"/actuator/prometheus"
@@ -70,9 +72,10 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
private static final Logger logger = LoggerFactory.getLogger(TokenAuthenticationFilter.class);
- public TokenAuthenticationFilter() {
+ public TokenAuthenticationFilter(IPermissionStorage permissionStorage) {
this.tokenProvider = new JwtTokenProvider();
this.userStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI();
+ this.permissionStorage = permissionStorage;
}
@Override
@@ -155,8 +158,8 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
}
private PrincipalUserDetails<?> makeDetails(Principal user) {
- return user instanceof UserAccount ? new UserAccountDetails((UserAccount) user) :
- new ServiceAccountDetails((ServiceAccount) user);
+ return user instanceof UserAccount ? new UserAccountDetails((UserAccount) user, permissionStorage) :
+ new ServiceAccountDetails((ServiceAccount) user, permissionStorage);
}
private boolean isAdminUser(PrincipalUserDetails<?> userDetails) {
diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/CustomOAuth2UserService.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/CustomOAuth2UserService.java
index 7715d1c668..0177814cb9 100755
--- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/CustomOAuth2UserService.java
+++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/CustomOAuth2UserService.java
@@ -19,6 +19,7 @@
package org.apache.streampipes.service.core.oauth2;
import org.apache.streampipes.rest.security.OAuth2AuthenticationProcessingException;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
@@ -32,13 +33,19 @@ import java.util.HashMap;
@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
+ private final IPermissionStorage permissionStorage;
+
+ public CustomOAuth2UserService(IPermissionStorage permissionStorage) {
+ this.permissionStorage = permissionStorage;
+ }
+
@Override
public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(oAuth2UserRequest);
try {
var attributes = new HashMap<>(oAuth2User.getAttributes());
var provider = oAuth2UserRequest.getClientRegistration().getRegistrationId();
- return new UserService().processUserRegistration(provider, attributes);
+ return new UserService(permissionStorage).processUserRegistration(provider, attributes);
} catch (AuthenticationException e) {
throw e;
} catch (Exception e) {
diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/CustomOidcUserService.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/CustomOidcUserService.java
index 558fb870c3..eb9371402d 100755
--- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/CustomOidcUserService.java
+++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/oauth2/CustomOidcUserService.java
@@ -21,6 +21,7 @@ package org.apache.streampipes.service.core.oauth2;
import org.apache.streampipes.commons.environment.Environments;
import org.apache.streampipes.rest.security.OAuth2AuthenticationProcessingException;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
@@ -34,7 +35,10 @@ import java.util.Objects;
@Service
public class CustomOidcUserService extends OidcUserService {
- public CustomOidcUserService() {
+ private final IPermissionStorage permissionStorage;
+
+ public CustomOidcUserService(IPermissionStorage permissionStorage) {
+ this.permissionStorage = permissionStorage;
var env = Environments.getEnvironment();
this.setRetrieveUserInfo(req -> {
var config = env.getOAuthConfigurations()
@@ -52,7 +56,7 @@ public class CustomOidcUserService extends OidcUserService {
OidcUser oidcUser = super.loadUser(userRequest);
try {
var provider = userRequest.getClientRegistration().getRegistrationId();
- return new UserService().processUserRegistration(
+ return new UserService(permissionStorage).processUserRegistration(
provider,
oidcUser.getAttributes(),
oidcUser.getIdToken(),
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 48b3fd5c4f..671adbad20 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
@@ -19,6 +19,7 @@
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.user.management.model.UserAccountDetails;
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
@@ -36,8 +37,9 @@ public class OidcUserAccountDetails extends UserAccountDetails implements OAuth2
public OidcUserAccountDetails(UserAccount user,
OidcIdToken idToken,
- OidcUserInfo userInfo) {
- super(user);
+ OidcUserInfo userInfo,
+ IPermissionStorage permissionStorage) {
+ super(user, permissionStorage);
this.idToken = idToken;
this.userInfo = userInfo;
}
@@ -45,8 +47,9 @@ public class OidcUserAccountDetails extends UserAccountDetails implements OAuth2
public static OidcUserAccountDetails create(UserAccount user,
Map<String, Object> attributes,
OidcIdToken idToken,
- OidcUserInfo userInfo) {
- OidcUserAccountDetails localUser = new OidcUserAccountDetails(user, idToken, userInfo);
+ OidcUserInfo userInfo,
+ IPermissionStorage permissionStorage) {
+ OidcUserAccountDetails localUser = new OidcUserAccountDetails(user, idToken, userInfo, permissionStorage);
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 bac55bb048..b2c2991134 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,14 +21,15 @@ 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.UserResourceManager;
-import org.apache.streampipes.rest.security.OAuth2AuthenticationProcessingException;
-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.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.UserResourceManager;
+import org.apache.streampipes.rest.security.OAuth2AuthenticationProcessingException;
+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.api.user.IUserStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;
import org.slf4j.Logger;
@@ -45,22 +46,24 @@ import java.util.stream.Collectors;
public class UserService {
- private static final Logger LOG = LoggerFactory.getLogger(UserService.class);
-
- private final IUserStorage userStorage;
- private final IRoleStorage roleStorage;
- private final IUserGroupStorage groupStorage;
+ private static final Logger LOG = LoggerFactory.getLogger(UserService.class);
+
+ private final IUserStorage userStorage;
+ private final IRoleStorage roleStorage;
+ private final IUserGroupStorage groupStorage;
private final Environment env;
private List<Role> allRoles;
private List<Group> allGroups;
+ private final IPermissionStorage permissionStorage;
- public UserService() {
+ public UserService(IPermissionStorage permissionStorage) {
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.env = Environments.getEnvironment();
+ this.permissionStorage = permissionStorage;
}
public OidcUserAccountDetails processUserRegistration(String registrationId,
@@ -103,7 +106,7 @@ public class UserService {
}
user = (UserAccount) userStorage.getUserById(principalId);
- return OidcUserAccountDetails.create(user, attributes, idToken, userInfo);
+ return OidcUserAccountDetails.create(user, attributes, idToken, userInfo, permissionStorage);
} else {
throw new OAuth2AuthenticationProcessingException(
String.format("No config found for provider %s", registrationId)
diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/scheduler/DataLakeScheduler.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/scheduler/DataLakeScheduler.java
index 3c2522234d..04c45cd1fa 100644
--- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/scheduler/DataLakeScheduler.java
+++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/scheduler/DataLakeScheduler.java
@@ -23,6 +23,7 @@ import org.apache.streampipes.dataexplorer.management.DataExplorerDispatcher;
import org.apache.streampipes.export.DataLakeExportManager;
import org.apache.streampipes.manager.pipeline.update.ChartSchemaUpdateCoordinator;
import org.apache.streampipes.model.datalake.DataLakeMeasure;
+import org.apache.streampipes.resource.management.SpResourceManager;
import org.apache.streampipes.storage.api.explorer.IDataExplorerWidgetStorage;
import org.slf4j.Logger;
@@ -42,11 +43,12 @@ public class DataLakeScheduler implements SchedulingConfigurer {
private final IDataExplorerSchemaManagement dataExplorerSchemaManagement;
- public DataLakeScheduler(IDataExplorerWidgetStorage chartStorage) {
+ public DataLakeScheduler(IDataExplorerWidgetStorage chartStorage,
+ SpResourceManager resourceManager) {
var chartSchemaUpdateCoordinator = new ChartSchemaUpdateCoordinator(chartStorage);
dataExplorerSchemaManagement = new DataExplorerDispatcher()
.getDataExplorerManager()
- .getSchemaManagement(chartSchemaUpdateCoordinator);
+ .getSchemaManagement(chartSchemaUpdateCoordinator, resourceManager.managePermissions().getDb());
this.dataLakeExportManager = new DataLakeExportManager(
dataExplorerSchemaManagement,
new DataExplorerDispatcher().getDataExplorerManager()
diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/storage/CachedPermissionStorage.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/storage/CachedPermissionStorage.java
new file mode 100644
index 0000000000..3076842bf2
--- /dev/null
+++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/storage/CachedPermissionStorage.java
@@ -0,0 +1,236 @@
+/*
+ * 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.storage;
+
+import org.apache.streampipes.model.Tuple2;
+import org.apache.streampipes.model.client.user.Permission;
+import org.apache.streampipes.serializers.json.JacksonSerializer;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+public class CachedPermissionStorage implements IPermissionStorage {
+
+ static final String CACHE_NAME = "permissions";
+ static final String FIND_ALL_CACHE_NAME = "permissionsAll";
+ static final String BY_OBJECT_CACHE_NAME = "permissionsByObject";
+ static final String BY_PRINCIPALS_CACHE_NAME = "objectPermissionsByPrincipals";
+
+ private static final Logger LOG = LoggerFactory.getLogger(CachedPermissionStorage.class);
+ private static final String FIND_ALL_CACHE_KEY = "all";
+ private static final TypeReference<List<Permission>> PERMISSION_LIST_TYPE = new TypeReference<>() {
+ };
+ private static final TypeReference<Set<String>> OBJECT_PERMISSION_SET_TYPE = new TypeReference<>() {
+ };
+
+ private final IPermissionStorage delegate;
+ private final Cache cache;
+ private final Cache findAllCache;
+ private final Cache byObjectCache;
+ private final Cache byPrincipalsCache;
+ private final ObjectMapper objectMapper;
+
+ public CachedPermissionStorage(IPermissionStorage delegate,
+ CacheManager cacheManager) {
+ this(delegate, cacheManager, JacksonSerializer.getObjectMapper());
+ }
+
+ CachedPermissionStorage(IPermissionStorage delegate,
+ CacheManager cacheManager,
+ ObjectMapper objectMapper) {
+ this.delegate = delegate;
+ this.cache = getCache(cacheManager, CACHE_NAME);
+ this.findAllCache = getCache(cacheManager, FIND_ALL_CACHE_NAME);
+ this.byObjectCache = getCache(cacheManager, BY_OBJECT_CACHE_NAME);
+ this.byPrincipalsCache = getCache(cacheManager, BY_PRINCIPALS_CACHE_NAME);
+ this.objectMapper = objectMapper;
+ }
+
+ @Override
+ public List<Permission> findAll() {
+ var cachedPermissions = getPermissionList(findAllCache, FIND_ALL_CACHE_KEY);
+ if (cachedPermissions != null) {
+ return cachedPermissions;
+ }
+
+ var permissions = delegate.findAll();
+ put(findAllCache, FIND_ALL_CACHE_KEY, permissions);
+ return permissions;
+ }
+
+ @Override
+ public Tuple2<Boolean, String> persist(Permission element) {
+ var result = delegate.persist(element);
+ if (Boolean.TRUE.equals(result.k)) {
+ clearCaches();
+ }
+ return result;
+ }
+
+ @Override
+ public Permission getElementById(String id) {
+ var cachedPermission = getPermission(id);
+ if (cachedPermission != null) {
+ return cachedPermission;
+ }
+
+ var permission = delegate.getElementById(id);
+ if (permission != null) {
+ put(cache, id, permission);
+ }
+ return permission;
+ }
+
+ @Override
+ public Permission updateElement(Permission element) {
+ var updatedElement = delegate.updateElement(element);
+ clearCaches();
+ return updatedElement;
+ }
+
+ @Override
+ public void deleteElement(Permission element) {
+ delegate.deleteElement(element);
+ clearCaches();
+ }
+
+ @Override
+ public void deleteElementById(String id) {
+ delegate.deleteElementById(id);
+ clearCaches();
+ }
+
+ @Override
+ public Set<String> getObjectPermissions(List<String> sids) {
+ var cacheKey = makePrincipalCacheKey(sids);
+ var cachedPermissions = getObjectPermissionSet(cacheKey);
+ if (cachedPermissions != null) {
+ return cachedPermissions;
+ }
+
+ var permissions = delegate.getObjectPermissions(sids);
+ put(byPrincipalsCache, cacheKey, permissions);
+ return permissions;
+ }
+
+ @Override
+ public List<Permission> getUserPermissionsForObject(String objectInstanceId) {
+ var cachedPermissions = getPermissionList(byObjectCache, objectInstanceId);
+ if (cachedPermissions != null) {
+ return cachedPermissions;
+ }
+
+ var permissions = delegate.getUserPermissionsForObject(objectInstanceId);
+ put(byObjectCache, objectInstanceId, permissions);
+ return permissions;
+ }
+
+ private Permission getPermission(String id) {
+ try {
+ var cachedValue = cache.get(id, String.class);
+ return cachedValue == null ? null : objectMapper.readValue(cachedValue, Permission.class);
+ } catch (JsonProcessingException | RuntimeException e) {
+ LOG.warn("Could not read permission {} from cache", id, e);
+ evict(cache, id);
+ return null;
+ }
+ }
+
+ private List<Permission> getPermissionList(Cache targetCache,
+ String key) {
+ try {
+ var cachedValue = targetCache.get(key, String.class);
+ return cachedValue == null ? null : objectMapper.readValue(cachedValue, PERMISSION_LIST_TYPE);
+ } catch (JsonProcessingException | RuntimeException e) {
+ LOG.warn("Could not read permissions from cache {}", targetCache.getName(), e);
+ evict(targetCache, key);
+ return null;
+ }
+ }
+
+ private Set<String> getObjectPermissionSet(String key) {
+ try {
+ var cachedValue = byPrincipalsCache.get(key, String.class);
+ return cachedValue == null ? null : objectMapper.readValue(cachedValue, OBJECT_PERMISSION_SET_TYPE);
+ } catch (JsonProcessingException | RuntimeException e) {
+ LOG.warn("Could not read object permissions from cache", e);
+ evict(byPrincipalsCache, key);
+ return null;
+ }
+ }
+
+ private String makePrincipalCacheKey(List<String> sids) {
+ var sortedSids = new ArrayList<>(sids);
+ sortedSids.sort(String::compareTo);
+ try {
+ return objectMapper.writeValueAsString(sortedSids);
+ } catch (JsonProcessingException e) {
+ throw new IllegalStateException("Could not create permission cache key", e);
+ }
+ }
+
+ private void put(Cache targetCache,
+ String key,
+ Object value) {
+ try {
+ targetCache.put(key, objectMapper.writeValueAsString(value));
+ } catch (JsonProcessingException | RuntimeException e) {
+ LOG.warn("Could not write permissions to cache {}", targetCache.getName(), e);
+ }
+ }
+
+ private void clearCaches() {
+ clear(cache);
+ clear(findAllCache);
+ clear(byObjectCache);
+ clear(byPrincipalsCache);
+ }
+
+ private void clear(Cache targetCache) {
+ try {
+ targetCache.clear();
+ } catch (RuntimeException e) {
+ LOG.warn("Could not clear permission cache {}", targetCache.getName(), e);
+ }
+ }
+
+ private void evict(Cache targetCache,
+ String key) {
+ try {
+ targetCache.evict(key);
+ } catch (RuntimeException e) {
+ LOG.warn("Could not evict permission cache entry from {}", targetCache.getName(), e);
+ }
+ }
+
+ private static Cache getCache(CacheManager cacheManager,
+ String cacheName) {
+ return Objects.requireNonNull(cacheManager.getCache(cacheName));
+ }
+}
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 cdfcffeada..002d6fcfae 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
@@ -48,7 +48,10 @@ public class StorageApiConfiguration {
}
@Bean
- public IPermissionStorage permissionStorage() {
- return new PermissionStorageImpl("users/permissions");
+ public IPermissionStorage permissionStorage(CacheManager cacheManager) {
+ return new CachedPermissionStorage(
+ new PermissionStorageImpl("users/permissions"),
+ cacheManager
+ );
}
}
diff --git a/streampipes-service-core/src/main/resources/application.properties b/streampipes-service-core/src/main/resources/application.properties
index ece15145a6..f48263acff 100644
--- a/streampipes-service-core/src/main/resources/application.properties
+++ b/streampipes-service-core/src/main/resources/application.properties
@@ -22,7 +22,7 @@ spring.servlet.multipart.max-request-size=5120MB
server.tomcat.additional-tld-skip-patterns=*.jar
spring.mvc.async.request-timeout=900000
spring.cache.type=caffeine
-spring.cache.cache-names=dataExplorerWidgets,dataExplorerWidgetsAll
+spring.cache.cache-names=dataExplorerWidgets,dataExplorerWidgetsAll,permissions,permissionsAll,permissionsByObject,objectPermissionsByPrincipals
spring.cache.caffeine.spec=maximumSize=10000,expireAfterWrite=10m
logging.config=classpath:logback.xml
spring.output.ansi.enabled=always
diff --git a/streampipes-service-core/src/test/java/org/apache/streampipes/service/core/storage/CachedPermissionStorageTest.java b/streampipes-service-core/src/test/java/org/apache/streampipes/service/core/storage/CachedPermissionStorageTest.java
new file mode 100644
index 0000000000..b276a9149e
--- /dev/null
+++ b/streampipes-service-core/src/test/java/org/apache/streampipes/service/core/storage/CachedPermissionStorageTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.storage;
+
+import org.apache.streampipes.model.client.user.Permission;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class CachedPermissionStorageTest {
+
+ private static final String PERMISSION_ID = "permission-id";
+ private static final String OBJECT_ID = "object-id";
+
+ private IPermissionStorage delegate;
+ private CachedPermissionStorage storage;
+
+ @BeforeEach
+ void setUp() {
+ delegate = mock(IPermissionStorage.class);
+ var cacheManager = new ConcurrentMapCacheManager(
+ CachedPermissionStorage.CACHE_NAME,
+ CachedPermissionStorage.FIND_ALL_CACHE_NAME,
+ CachedPermissionStorage.BY_OBJECT_CACHE_NAME,
+ CachedPermissionStorage.BY_PRINCIPALS_CACHE_NAME
+ );
+ storage = new CachedPermissionStorage(delegate, cacheManager);
+ }
+
+ @Test
+ void getUserPermissionsForObjectCachesSerializedCopies() {
+ var permission = makePermission("owner");
+ when(delegate.getUserPermissionsForObject(OBJECT_ID)).thenReturn(List.of(permission));
+
+ var firstResult = storage.getUserPermissionsForObject(OBJECT_ID);
+ firstResult.get(0).setOwnerSid("changed-owner");
+ var secondResult = storage.getUserPermissionsForObject(OBJECT_ID);
+
+ assertNotSame(firstResult, secondResult);
+ assertNotSame(firstResult.get(0), secondResult.get(0));
+ assertEquals("owner", secondResult.get(0).getOwnerSid());
+ verify(delegate, times(1)).getUserPermissionsForObject(OBJECT_ID);
+ }
+
+ @Test
+ void getObjectPermissionsUsesOrderIndependentPrincipalKey() {
+ var firstOrder = new ArrayList<>(List.of("user", "group"));
+ var secondOrder = new ArrayList<>(List.of("group", "user"));
+ when(delegate.getObjectPermissions(firstOrder)).thenReturn(Set.of(OBJECT_ID));
+
+ var firstResult = storage.getObjectPermissions(firstOrder);
+ var secondResult = storage.getObjectPermissions(secondOrder);
+
+ assertEquals(Set.of(OBJECT_ID), firstResult);
+ assertEquals(Set.of(OBJECT_ID), secondResult);
+ verify(delegate, times(1)).getObjectPermissions(firstOrder);
+ }
+
+ @Test
+ void updateElementClearsAllQueryCaches() {
+ var permission = makePermission("owner");
+ var updatedPermission = makePermission("updated-owner");
+ var sids = List.of("user");
+ when(delegate.getElementById(PERMISSION_ID)).thenReturn(permission, updatedPermission);
+ when(delegate.findAll()).thenReturn(List.of(permission), List.of(updatedPermission));
+ when(delegate.getUserPermissionsForObject(OBJECT_ID))
+ .thenReturn(List.of(permission), List.of(updatedPermission));
+ when(delegate.getObjectPermissions(sids)).thenReturn(Set.of("old-object"), Set.of("new-object"));
+ when(delegate.updateElement(updatedPermission)).thenReturn(updatedPermission);
+
+ storage.getElementById(PERMISSION_ID);
+ storage.findAll();
+ storage.getUserPermissionsForObject(OBJECT_ID);
+ storage.getObjectPermissions(sids);
+ storage.updateElement(updatedPermission);
+
+ assertEquals("updated-owner", storage.getElementById(PERMISSION_ID).getOwnerSid());
+ assertEquals("updated-owner", storage.findAll().get(0).getOwnerSid());
+ assertEquals("updated-owner", storage.getUserPermissionsForObject(OBJECT_ID).get(0).getOwnerSid());
+ assertEquals(Set.of("new-object"), storage.getObjectPermissions(sids));
+ verify(delegate, times(2)).getElementById(PERMISSION_ID);
+ verify(delegate, times(2)).findAll();
+ verify(delegate, times(2)).getUserPermissionsForObject(OBJECT_ID);
+ verify(delegate, times(2)).getObjectPermissions(sids);
+ }
+
+ private Permission makePermission(String ownerSid) {
+ var permission = new Permission();
+ permission.setPermissionId(PERMISSION_ID);
+ permission.setObjectInstanceId(OBJECT_ID);
+ permission.setOwnerSid(ownerSid);
+ return permission;
+ }
+}
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 de4ef4b597..c5891d7d85 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
@@ -38,7 +38,6 @@ import org.apache.streampipes.storage.api.system.IImageStorage;
import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage;
import org.apache.streampipes.storage.api.system.ITransformationScriptTemplateStorage;
import org.apache.streampipes.storage.api.user.IPasswordRecoveryTokenStorage;
-import org.apache.streampipes.storage.api.user.IPermissionStorage;
import org.apache.streampipes.storage.api.user.IPrivilegeStorage;
import org.apache.streampipes.storage.api.user.IRefreshTokenStorage;
import org.apache.streampipes.storage.api.user.IRoleStorage;
@@ -74,8 +73,6 @@ public interface INoSqlStorage {
IPipelineElementDescriptionStorage getPipelineElementDescriptionStorage();
- IPermissionStorage getPermissionStorage();
-
IDataProcessorStorage getDataProcessorStorage();
IDataSinkStorage getDataSinkStorage();
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 577b82b51f..e4fb7b29b4 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
@@ -40,7 +40,6 @@ import org.apache.streampipes.storage.api.system.IImageStorage;
import org.apache.streampipes.storage.api.system.ISpCoreConfigurationStorage;
import org.apache.streampipes.storage.api.system.ITransformationScriptTemplateStorage;
import org.apache.streampipes.storage.api.user.IPasswordRecoveryTokenStorage;
-import org.apache.streampipes.storage.api.user.IPermissionStorage;
import org.apache.streampipes.storage.api.user.IPrivilegeStorage;
import org.apache.streampipes.storage.api.user.IRefreshTokenStorage;
import org.apache.streampipes.storage.api.user.IRoleStorage;
@@ -69,7 +68,6 @@ import org.apache.streampipes.storage.couchdb.impl.system.GenericStorageImpl;
import org.apache.streampipes.storage.couchdb.impl.system.ImageStorageImpl;
import org.apache.streampipes.storage.couchdb.impl.system.TransformationScriptTemplateStorageImpl;
import org.apache.streampipes.storage.couchdb.impl.user.PasswordRecoveryTokenStorageImpl;
-import org.apache.streampipes.storage.couchdb.impl.user.PermissionStorageImpl;
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;
@@ -148,11 +146,6 @@ public class CouchDbStorageManager implements INoSqlStorage {
return new PipelineElementDescriptionStorageImpl();
}
- @Override
- public IPermissionStorage getPermissionStorage() {
- return new PermissionStorageImpl("users/permissions");
- }
-
@Override
public IDataProcessorStorage getDataProcessorStorage() {
return new DataProcessorStorageImpl();
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 a9c943822d..7a029b2161 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
@@ -18,6 +18,7 @@
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.user.management.util.GrantedAuthoritiesBuilder;
import org.apache.streampipes.user.management.util.GrantedPermissionsBuilder;
@@ -35,10 +36,11 @@ public abstract class PrincipalUserDetails<T extends Principal> implements UserD
private Set<String> allAuthorities;
private Set<String> allObjectPermissions;
- public PrincipalUserDetails(T details) {
+ public PrincipalUserDetails(T details,
+ IPermissionStorage permissionStorage) {
this.details = details;
this.allAuthorities = new GrantedAuthoritiesBuilder(details).buildAllAuthorities();
- this.allObjectPermissions = new GrantedPermissionsBuilder(details).buildAllPermissions();
+ this.allObjectPermissions = new GrantedPermissionsBuilder(details, permissionStorage).buildAllPermissions();
}
public T getDetails() {
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 fee4703089..a5ae3758a2 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
@@ -18,12 +18,14 @@
package org.apache.streampipes.user.management.model;
import org.apache.streampipes.model.client.user.ServiceAccount;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
public class ServiceAccountDetails extends PrincipalUserDetails<ServiceAccount> {
- public ServiceAccountDetails(ServiceAccount details) {
- super(details);
+ public ServiceAccountDetails(ServiceAccount details,
+ IPermissionStorage permissionStorage) {
+ super(details, permissionStorage);
}
@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 da2405066e..08f4452098 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
@@ -18,11 +18,13 @@
package org.apache.streampipes.user.management.model;
import org.apache.streampipes.model.client.user.UserAccount;
+import org.apache.streampipes.storage.api.user.IPermissionStorage;
public class UserAccountDetails extends PrincipalUserDetails<UserAccount> {
- public UserAccountDetails(UserAccount details) {
- super(details);
+ public UserAccountDetails(UserAccount details,
+ IPermissionStorage permissionStorage) {
+ super(details, permissionStorage);
}
@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 a113185810..5fd1bb74fb 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
@@ -20,6 +20,7 @@ package org.apache.streampipes.user.management.service;
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.management.StorageDispatcher;
import org.apache.streampipes.user.management.model.ServiceAccountDetails;
import org.apache.streampipes.user.management.model.UserAccountDetails;
@@ -30,10 +31,16 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class SpUserDetailsService implements UserDetailsService {
+ private final IPermissionStorage permissionStorage;
+
+ public SpUserDetailsService(IPermissionStorage permissionStorage) {
+ this.permissionStorage = permissionStorage;
+ }
+
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
Principal user = StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI().getUser(s);
- return user instanceof UserAccount ? new UserAccountDetails((UserAccount) user) :
- new ServiceAccountDetails((ServiceAccount) user);
+ return user instanceof UserAccount ? new UserAccountDetails((UserAccount) user, permissionStorage) :
+ new ServiceAccountDetails((ServiceAccount) user, permissionStorage);
}
}
diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedPermissionsBuilder.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedPermissionsBuilder.java
index 1674849767..90db32e7dd 100644
--- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedPermissionsBuilder.java
+++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedPermissionsBuilder.java
@@ -18,7 +18,7 @@
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.IPermissionStorage;
import java.util.ArrayList;
import java.util.Set;
@@ -26,18 +26,18 @@ import java.util.Set;
public class GrantedPermissionsBuilder {
private final Principal principal;
+ private final IPermissionStorage permissionStorage;
- public GrantedPermissionsBuilder(Principal principal) {
+ public GrantedPermissionsBuilder(Principal principal,
+ IPermissionStorage permissionStorage) {
this.principal = principal;
+ this.permissionStorage = permissionStorage;
}
public Set<String> buildAllPermissions() {
Set<String> sids = extractSids();
- return StorageDispatcher
- .INSTANCE
- .getNoSqlStore()
- .getPermissionStorage()
+ return permissionStorage
.getObjectPermissions(new ArrayList<>(sids));
}