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 2021/10/12 11:47:11 UTC
[incubator-streampipes] 03/03: [STREAMPIPES-426] Add initial parts
of authorization system
This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch STREAMPIPES-426
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
commit c81b92dfbca69e4e66a2effcfdcdcb59eceb7ad3
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Tue Oct 12 13:43:43 2021 +0200
[STREAMPIPES-426] Add initial parts of authorization system
---
.../backend/StreamPipesBackendApplication.java | 9 +-
.../streampipes/model/client/user/Principal.java | 10 ++
.../streampipes/model/client/user/Privilege.java | 126 +++++++++++++++------
.../apache/streampipes/model/client/user/Role.java | 83 ++++++++++++--
.../manager/pipeline/PipelineManager.java | 8 ++
.../setup/UserRegistrationInstallationStep.java | 2 +-
streampipes-rest/pom.xml | 4 -
.../streampipes/rest/impl/PipelineResource.java | 23 +++-
.../rest/impl/SemanticEventProducer.java | 2 +
.../apache/streampipes/rest/impl/UserResource.java | 2 +-
.../rest/impl/admin/PermissionResource.java | 17 ++-
.../rest/impl/security/AuthConstants.java | 47 ++++++++
.../rest/impl/security/SpPermissionEvaluator.java | 30 +++--
.../management/model/PrincipalUserDetails.java | 21 ++--
.../management/model/ServiceAccountDetails.java | 11 --
.../user/management/model/UserAccountDetails.java | 9 --
.../AuthorityBuilder.java} | 62 +++++-----
ui/deployment/appng5.module.mst | 2 +
ui/src/app/_enums/user-role.enum.ts | 18 +--
.../Role.java => ui/src/app/_models/auth.model.ts | 18 ++-
.../edit-group-dialog.component.html | 6 +-
.../edit-group-dialog.component.ts | 7 +-
.../edit-user-dialog.component.html | 6 +-
.../edit-user-dialog/edit-user-dialog.component.ts | 16 +--
.../app/core-model/gen/streampipes-model-client.ts | 40 ++-----
ui/src/app/services/auth.service.ts | 31 ++---
ui/src/app/services/available-roles.service.ts | 42 +++++++
27 files changed, 435 insertions(+), 217 deletions(-)
diff --git a/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesBackendApplication.java b/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesBackendApplication.java
index 721c159..844bad1 100644
--- a/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesBackendApplication.java
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesBackendApplication.java
@@ -25,6 +25,7 @@ import org.apache.streampipes.manager.operations.Operations;
import org.apache.streampipes.manager.setup.AutoInstallation;
import org.apache.streampipes.model.pipeline.Pipeline;
import org.apache.streampipes.model.pipeline.PipelineOperationStatus;
+import org.apache.streampipes.rest.impl.security.SpPermissionEvaluator;
import org.apache.streampipes.rest.notifications.NotificationListener;
import org.apache.streampipes.storage.api.IPipelineStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;
@@ -36,6 +37,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -54,7 +56,12 @@ import java.util.stream.Collectors;
@Configuration
@EnableAutoConfiguration
-@Import({StreamPipesResourceConfig.class, WelcomePageController.class, WebSecurityConfig.class})
+@Import({StreamPipesResourceConfig.class,
+ WelcomePageController.class,
+ WebSecurityConfig.class,
+ SpPermissionEvaluator.class
+})
+@ComponentScan({"org.apache.streampipes.rest.*"})
public class StreamPipesBackendApplication extends StreamPipesServiceBase {
private static final Logger LOG = LoggerFactory.getLogger(StreamPipesBackendApplication.class.getCanonicalName());
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Principal.java b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Principal.java
index 462df3c..777556a 100644
--- a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Principal.java
+++ b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Principal.java
@@ -39,6 +39,7 @@ public abstract class Principal {
protected List<Element> ownSources;
protected List<Element> ownSepas;
protected List<Element> ownActions;
+ protected Set<String> objectPermissions;
protected Set<Role> roles;
protected Set<String> groups;
@@ -52,6 +53,7 @@ public abstract class Principal {
this.ownSources = new ArrayList<>();
this.roles = new HashSet<>();
this.groups = new HashSet<>();
+ this.objectPermissions = new HashSet<>();
}
public List<Element> getOwnSources() {
@@ -179,4 +181,12 @@ public abstract class Principal {
public String getUsername() {
return username;
}
+
+ public Set<String> getObjectPermissions() {
+ return objectPermissions;
+ }
+
+ public void setObjectPermissions(Set<String> objectPermissions) {
+ this.objectPermissions = objectPermissions;
+ }
}
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Privilege.java b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Privilege.java
index 3bf9649..4170e31 100644
--- a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Privilege.java
+++ b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Privilege.java
@@ -17,61 +17,115 @@
*/
package org.apache.streampipes.model.client.user;
+import org.apache.streampipes.model.shared.annotation.TsModel;
+
+@TsModel
public enum Privilege {
// Pipelines
- PRIVILEGE_CREATE_PIPELINE,
- PRIVILEGE_READ_PIPELINE,
- PRIVILEGE_UPDATE_PIPELINE,
- PRIVILEGE_DELETE_PIPELINE,
+ PRIVILEGE_CREATE_PIPELINE(Constants.PRIVILEGE_CREATE_PIPELINE_VALUE),
+ PRIVILEGE_READ_PIPELINE(Constants.PRIVILEGE_READ_PIPELINE_VALUE),
+ PRIVILEGE_UPDATE_PIPELINE(Constants.PRIVILEGE_UPDATE_PIPELINE_VALUE),
+ PRIVILEGE_DELETE_PIPELINE(Constants.PRIVILEGE_DELETE_PIPELINE_VALUE),
// Adapters
- PRIVILEGE_CREATE_ADAPTER,
- PRIVILEGE_READ_ADAPTER,
- PRIVILEGE_UPDATE_ADAPTER,
- PRIVILEGE_DELETE_ADAPTER,
+ PRIVILEGE_CREATE_ADAPTER(Constants.PRIVILEGE_CREATE_ADAPTER_VALUE),
+ PRIVILEGE_READ_ADAPTER(Constants.PRIVILEGE_READ_ADAPTER_VALUE),
+ PRIVILEGE_UPDATE_ADAPTER(Constants.PRIVILEGE_UPDATE_ADAPTER_VALUE),
+ PRIVILEGE_DELETE_ADAPTER(Constants.PRIVILEGE_DELETE_ADAPTER_VALUE),
// Pipeline Elements
- PRIVILEGE_CREATE_PIPELINE_ELEMENT,
- PRIVILEGE_READ_PIPELINE_ELEMENT,
- PRIVILEGE_UPDATE_PIPELINE_ELEMENT,
- PRIVILEGE_DELETE_PIPELINE_ELEMENT,
+ PRIVILEGE_CREATE_PIPELINE_ELEMENT(Constants.PRIVILEGE_CREATE_PIPELINE_ELEMENT_VALUE),
+ PRIVILEGE_READ_PIPELINE_ELEMENT(Constants.PRIVILEGE_READ_PIPELINE_ELEMENT_VALUE),
+ PRIVILEGE_UPDATE_PIPELINE_ELEMENT(Constants.PRIVILEGE_UPDATE_PIPELINE_ELEMENT_VALUE),
+ PRIVILEGE_DELETE_PIPELINE_ELEMENT(Constants.PRIVILEGE_DELETE_PIPELINE_ELEMENT_VALUE),
// Dashboard
- PRIVILEGE_CREATE_DASHBOARD,
- PRIVILEGE_READ_DASHBOARD,
- PRIVILEGE_UPDATE_DASHBOARD,
- PRIVILEGE_DELETE_DASHBOARD,
+ PRIVILEGE_CREATE_DASHBOARD(Constants.PRIVILEGE_CREATE_DASHBOARD_VALUE),
+ PRIVILEGE_READ_DASHBOARD(Constants.PRIVILEGE_READ_DASHBOARD_VALUE),
+ PRIVILEGE_UPDATE_DASHBOARD(Constants.PRIVILEGE_UPDATE_DASHBOARD_VALUE),
+ PRIVILEGE_DELETE_DASHBOARD(Constants.PRIVILEGE_DELETE_DASHBOARD_VALUE),
// Dashboard widget
- PRIVILEGE_CREATE_DASHBOARD_WIDGET,
- PRIVILEGE_READ_DASHBOARD_WIDGET,
- PRIVILEGE_UPDATE_DASHBOARD_WIDGET,
- PRIVILEGE_DELETE_DASHBOARD_WIDGET,
+ PRIVILEGE_CREATE_DASHBOARD_WIDGET(Constants.PRIVILEGE_CREATE_DASHBOARD_WIDGET_VALUE),
+ PRIVILEGE_READ_DASHBOARD_WIDGET(Constants.PRIVILEGE_READ_DASHBOARD_WIDGET_VALUE),
+ PRIVILEGE_UPDATE_DASHBOARD_WIDGET(Constants.PRIVILEGE_UPDATE_DASHBOARD_WIDGET_VALUE),
+ PRIVILEGE_DELETE_DASHBOARD_WIDGET(Constants.PRIVILEGE_DELETE_DASHBOARD_WIDGET_VALUE),
// Data Explorer view
- PRIVILEGE_CREATE_DATA_EXPLORER_VIEW,
- PRIVILEGE_READ_DATA_EXPLORER_VIEW,
- PRIVILEGE_UPDATE_DATA_EXPLORER_VIEW,
- PRIVILEGE_DELETE_DATA_EXPLORER_VIEW,
+ PRIVILEGE_CREATE_DATA_EXPLORER_VIEW(Constants.PRIVILEGE_CREATE_DATA_EXPLORER_VIEW_VALUE),
+ PRIVILEGE_READ_DATA_EXPLORER_VIEW(Constants.PRIVILEGE_READ_DATA_EXPLORER_VIEW_VALUE),
+ PRIVILEGE_UPDATE_DATA_EXPLORER_VIEW(Constants.PRIVILEGE_UPDATE_DATA_EXPLORER_VIEW_VALUE),
+ PRIVILEGE_DELETE_DATA_EXPLORER_VIEW(Constants.PRIVILEGE_DELETE_DATA_EXPLORER_VIEW_VALUE),
// Data Explorer widget
- PRIVILEGE_CREATE_DATA_EXPLORER_WIDGET,
- PRIVILEGE_READ_DATA_EXPLORER_WIDGET,
- PRIVILEGE_UPDATE_DATA_EXPLORER_WIDGET,
- PRIVILEGE_DELETE_DATA_EXPLORER_WIDGET,
+ PRIVILEGE_CREATE_DATA_EXPLORER_WIDGET(Constants.PRIVILEGE_CREATE_DATA_EXPLORER_WIDGET_VALUE),
+ PRIVILEGE_READ_DATA_EXPLORER_WIDGET(Constants.PRIVILEGE_READ_DATA_EXPLORER_WIDGET_VALUE),
+ PRIVILEGE_UPDATE_DATA_EXPLORER_WIDGET(Constants.PRIVILEGE_UPDATE_DATA_EXPLORER_WIDGET_VALUE),
+ PRIVILEGE_DELETE_DATA_EXPLORER_WIDGET(Constants.PRIVILEGE_DELETE_DATA_EXPLORER_WIDGET_VALUE),
// Apps
- PRIVILEGE_READ_APPS,
+ PRIVILEGE_READ_APPS(Constants.PRIVILEGE_READ_APPS_VALUE),
+ PRIVILEGE_UPDATE_APPS(Constants.PRIVILEGE_UPDATE_APPS_VALUE),
// NOTIFICATIONS
- PRIVILEGE_READ_NOTIFICATIONS,
+ PRIVILEGE_READ_NOTIFICATIONS(Constants.PRIVILEGE_READ_NOTIFICATIONS_VALUE),
// FILES
- PRIVILEGE_READ_FILES,
- PRIVILEGE_CREATE_FILES,
- PRIVILEGE_UPDATE_FILES,
- PRIVILEGE_DELETE_FILES,
+ PRIVILEGE_READ_FILES(Constants.PRIVILEGE_READ_FILES_VALUE),
+ PRIVILEGE_CREATE_FILES(Constants.PRIVILEGE_CREATE_FILES_VALUE),
+ PRIVILEGE_UPDATE_FILES(Constants.PRIVILEGE_UPDATE_FILES_VALUE),
+ PRIVILEGE_DELETE_FILES(Constants.PRIVILEGE_DELETE_FILES_VALUE);
+
+ private String privilegeString;
+
+ Privilege(String privilegeString) {
+ this.privilegeString = privilegeString;
+ }
+
+ public static final class Constants {
+ public static final String PRIVILEGE_CREATE_PIPELINE_VALUE = "PRIVILEGE_CREATE_PIPELINE";
+ public static final String PRIVILEGE_READ_PIPELINE_VALUE = "PRIVILEGE_READ_PIPELINE";
+ public static final String PRIVILEGE_UPDATE_PIPELINE_VALUE = "PRIVILEGE_UPDATE_PIPELINE";
+ public static final String PRIVILEGE_DELETE_PIPELINE_VALUE = "PRIVILEGE_DELETE_PIPELINE";
+
+ public static final String PRIVILEGE_CREATE_ADAPTER_VALUE = "PRIVILEGE_CREATE_ADAPTER";
+ public static final String PRIVILEGE_READ_ADAPTER_VALUE = "PRIVILEGE_READ_ADAPTER";
+ public static final String PRIVILEGE_UPDATE_ADAPTER_VALUE = "PRIVILEGE_UPDATE_ADAPTER";
+ public static final String PRIVILEGE_DELETE_ADAPTER_VALUE = "PRIVILEGE_DELETE_ADAPTER";
+
+ public static final String PRIVILEGE_CREATE_PIPELINE_ELEMENT_VALUE = "PRIVILEGE_CREATE_PIPELINE_ELEMENT";
+ public static final String PRIVILEGE_READ_PIPELINE_ELEMENT_VALUE = "PRIVILEGE_READ_PIPELINE_ELEMENT";
+ public static final String PRIVILEGE_UPDATE_PIPELINE_ELEMENT_VALUE = "PRIVILEGE_UPDATE_PIPELINE_ELEMENT";
+ public static final String PRIVILEGE_DELETE_PIPELINE_ELEMENT_VALUE = "PRIVILEGE_DELETE_PIPELINE_ELEMENT";
+
+ public static final String PRIVILEGE_CREATE_DASHBOARD_VALUE = "PRIVILEGE_CREATE_DASHBOARD";
+ public static final String PRIVILEGE_READ_DASHBOARD_VALUE = "PRIVILEGE_READ_DASHBOARD";
+ public static final String PRIVILEGE_UPDATE_DASHBOARD_VALUE = "PRIVILEGE_UPDATE_DASHBOARD";
+ public static final String PRIVILEGE_DELETE_DASHBOARD_VALUE = "PRIVILEGE_DELETE_DASHBOARD";
+
+ public static final String PRIVILEGE_CREATE_DASHBOARD_WIDGET_VALUE = "PRIVILEGE_CREATE_DASHBOARD_WIDGET";
+ public static final String PRIVILEGE_READ_DASHBOARD_WIDGET_VALUE = "PRIVILEGE_READ_DASHBOARD_WIDGET";
+ public static final String PRIVILEGE_UPDATE_DASHBOARD_WIDGET_VALUE = "PRIVILEGE_UPDATE_DASHBOARD_WIDGET";
+ public static final String PRIVILEGE_DELETE_DASHBOARD_WIDGET_VALUE = "PRIVILEGE_DELETE_DASHBOARD_WIDGET";
+
+ public static final String PRIVILEGE_CREATE_DATA_EXPLORER_VIEW_VALUE = "PRIVILEGE_CREATE_DATA_EXPLORER_VIEW";
+ public static final String PRIVILEGE_READ_DATA_EXPLORER_VIEW_VALUE = "PRIVILEGE_READ_DATA_EXPLORER_VIEW";
+ public static final String PRIVILEGE_UPDATE_DATA_EXPLORER_VIEW_VALUE = "PRIVILEGE_UPDATE_DATA_EXPLORER_VIEW";
+ public static final String PRIVILEGE_DELETE_DATA_EXPLORER_VIEW_VALUE = "PRIVILEGE_DELETE_DATA_EXPLORER_VIEW";
+
+ public static final String PRIVILEGE_CREATE_DATA_EXPLORER_WIDGET_VALUE = "PRIVILEGE_CREATE_DATA_EXPLORER_WIDGET";
+ public static final String PRIVILEGE_READ_DATA_EXPLORER_WIDGET_VALUE = "PRIVILEGE_READ_DATA_EXPLORER_WIDGET";
+ public static final String PRIVILEGE_UPDATE_DATA_EXPLORER_WIDGET_VALUE = "PRIVILEGE_UPDATE_DATA_EXPLORER_WIDGET";
+ public static final String PRIVILEGE_DELETE_DATA_EXPLORER_WIDGET_VALUE = "PRIVILEGE_DELETE_DATA_EXPLORER_WIDGET";
+
+ public static final String PRIVILEGE_READ_APPS_VALUE = "PRIVILEGE_READ_APPS";
+ public static final String PRIVILEGE_UPDATE_APPS_VALUE = "PRIVILEGE_UPDATE_APPS";
+
+ public static final String PRIVILEGE_READ_NOTIFICATIONS_VALUE = "PRIVILEGE_READ_NOTIFICATIONS";
- // Admin
- PRIVILEGE_ADMIN
+ public static final String PRIVILEGE_READ_FILES_VALUE = "PRIVILEGE_READ_FILES";
+ public static final String PRIVILEGE_CREATE_FILES_VALUE = "PRIVILEGE_CREATE_FILES";
+ public static final String PRIVILEGE_UPDATE_FILES_VALUE = "PRIVILEGE_UPDATE_FILES";
+ public static final String PRIVILEGE_DELETE_FILES_VALUE = "PRIVILEGE_DELETE_FILES";
+ }
}
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java
index ca87883..11c5c2a 100644
--- a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java
+++ b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java
@@ -18,15 +18,80 @@
package org.apache.streampipes.model.client.user;
+import org.apache.streampipes.model.shared.annotation.TsModel;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@TsModel
public enum Role {
- ADMIN,
- PIPELINE_ADMIN,
- DASHBOARD_ADMIN,
- DATA_EXPLORER_ADMIN,
- CONNECT_ADMIN,
- DASHBOARD_USER,
- DATA_EXPLORER_USER,
- PIPELINE_USER,
- APP_USER
+ ROLE_ADMIN(Constants.ROLE_ADMIN_VALUE),
+
+ ROLE_PIPELINE_ADMIN(
+ Constants.ROLE_PIPELINE_ADMIN_VALUE,
+ Privilege.PRIVILEGE_CREATE_PIPELINE,
+ Privilege.PRIVILEGE_READ_PIPELINE,
+ Privilege.PRIVILEGE_UPDATE_PIPELINE,
+ Privilege.PRIVILEGE_DELETE_PIPELINE
+ ),
+
+ ROLE_DASHBOARD_ADMIN(
+ Constants.ROLE_DASHBOARD_ADMIN_VALUE,
+ Privilege.PRIVILEGE_CREATE_DASHBOARD,
+ Privilege.PRIVILEGE_READ_DASHBOARD,
+ Privilege.PRIVILEGE_UPDATE_DASHBOARD,
+ Privilege.PRIVILEGE_DELETE_DASHBOARD
+ ),
+
+ ROLE_DATA_EXPLORER_ADMIN(
+ Constants.ROLE_DATA_EXPLORER_ADMIN_VALUE
+ ),
+ ROLE_CONNECT_ADMIN(
+ Constants.ROLE_CONNECT_ADMIN_VALUE
+ ),
+
+ ROLE_DASHBOARD_USER(
+ Constants.ROLE_DASHBOARD_USER_VALUE
+ ),
+
+ ROLE_DATA_EXPLORER_USER(
+ Constants.ROLE_DATA_EXPLORER_USER_VALUE
+ ),
+
+ ROLE_PIPELINE_USER(
+ Constants.ROLE_PIPELINE_USER_VALUE,
+ Privilege.PRIVILEGE_READ_PIPELINE
+ ),
+
+ ROLE_APP_USER(Constants.ROLE_APP_USER_VALUE);
+
+ private List<Privilege> privileges;
+ private String roleString;
+
+ Role(String roleString,
+ Privilege... privileges) {
+ this.roleString = roleString;
+ this.privileges = Arrays.asList(privileges);
+ }
+
+ public List<String> getPrivilegesAsString() {
+ return this.privileges.stream().map(Enum::name).collect(Collectors.toList());
+ }
+
+ public List<Privilege> getPrivileges() {
+ return privileges;
+ }
+ public static final class Constants {
+ public static final String ROLE_ADMIN_VALUE = "ROLE_ADMIN";
+ public static final String ROLE_PIPELINE_ADMIN_VALUE = "ROLE_PIPELINE_ADMIN";
+ public static final String ROLE_DASHBOARD_ADMIN_VALUE = "ROLE_DASHBOARD_ADMIN";
+ public static final String ROLE_DATA_EXPLORER_ADMIN_VALUE = "ROLE_DATA_EXPLORER_ADMIN";
+ public static final String ROLE_CONNECT_ADMIN_VALUE = "ROLE_CONNECT_ADMIN";
+ 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_APP_USER_VALUE = "ROLE_APP_USER";
+ }
}
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/pipeline/PipelineManager.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/pipeline/PipelineManager.java
index 833ed88..2e3172f 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/pipeline/PipelineManager.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/pipeline/PipelineManager.java
@@ -41,6 +41,14 @@ public class PipelineManager {
}
/**
+ * Returns all pipelines
+ * @return all pipelines
+ */
+ public static List<Pipeline> getAllPipelines() {
+ return StorageDispatcher.INSTANCE.getNoSqlStore().getPipelineStorageAPI().getAllPipelines();
+ }
+
+ /**
* Returns the stored pipeline with the given pipeline Id
* @param pipelineId
* @return pipeline
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/UserRegistrationInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/UserRegistrationInstallationStep.java
index 92737b1..f24ff50 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/UserRegistrationInstallationStep.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/UserRegistrationInstallationStep.java
@@ -47,7 +47,7 @@ public class UserRegistrationInstallationStep extends InstallationStep {
this.initialServiceAccountName = initialServiceAccountName;
this.initialServiceAccountSecret = initialServiceAccountSecret;
roles = new HashSet<>();
- roles.add(Role.ADMIN);
+ roles.add(Role.ROLE_ADMIN);
}
@Override
diff --git a/streampipes-rest/pom.xml b/streampipes-rest/pom.xml
index 58e1d13..332189d 100644
--- a/streampipes-rest/pom.xml
+++ b/streampipes-rest/pom.xml
@@ -116,10 +116,6 @@
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
- <groupId>org.glassfish.jersey.core</groupId>
- <artifactId>jersey-server</artifactId>
- </dependency>
- <dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
</dependency>
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/PipelineResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/PipelineResource.java
index 737757f..d741409 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/PipelineResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/PipelineResource.java
@@ -38,14 +38,19 @@ import org.apache.streampipes.model.message.SuccessMessage;
import org.apache.streampipes.model.pipeline.Pipeline;
import org.apache.streampipes.model.pipeline.PipelineOperationStatus;
import org.apache.streampipes.rest.core.base.impl.AbstractAuthGuardedRestResource;
+import org.apache.streampipes.rest.impl.security.AuthConstants;
import org.apache.streampipes.rest.shared.annotation.JacksonSerialized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import java.util.List;
+@Component
@Path("/v2/pipelines")
public class PipelineResource extends AbstractAuthGuardedRestResource {
@@ -63,8 +68,11 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
mediaType = "application/json",
array = @ArraySchema(schema = @Schema(implementation = Pipeline.class)))
})})
- public Response getOwn() {
- return ok(PipelineManager.getOwnPipelines(getAuthenticatedUsername()));
+ @PreAuthorize(AuthConstants.IS_ADMIN_ROLE)
+ public List<Pipeline> getOwn() {
+ return PipelineManager.getAllPipelines();
+ //return ok(PipelineManager.getOwnPipelines(getAuthenticatedUsername()));
+
}
@GET
@@ -73,6 +81,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@JacksonSerialized
@Operation(summary = "Get all system pipelines assigned to the current user",
tags = {"Pipeline"})
+ @PreAuthorize(AuthConstants.HAS_READ_PIPELINE_PRIVILEGE)
public Response getSystemPipelines() {
return ok(getPipelineStorage().getSystemPipelines());
}
@@ -83,6 +92,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@JacksonSerialized
@Operation(summary = "Get the pipeline status of a given pipeline",
tags = {"Pipeline"})
+ @PreAuthorize(AuthConstants.HAS_READ_PIPELINE_PRIVILEGE)
public Response getPipelineStatus(@PathParam("pipelineId") String pipelineId) {
return ok(PipelineStatusManager.getPipelineStatus(pipelineId, 5));
}
@@ -93,6 +103,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@JacksonSerialized
@Operation(summary = "Delete a pipeline with a given id",
tags = {"Pipeline"})
+ @PreAuthorize(AuthConstants.HAS_DELETE_PIPELINE_PRIVILEGE)
public Response removeOwn(@PathParam("pipelineId") String pipelineId) {
PipelineManager.deletePipeline(pipelineId);
return statusMessage(Notifications.success("Pipeline deleted"));
@@ -104,6 +115,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@JacksonSerialized
@Operation(summary = "Get a specific pipeline with the given id",
tags = {"Pipeline"})
+ @PreAuthorize(AuthConstants.HAS_READ_PIPELINE_PRIVILEGE)
public Response getElement(@PathParam("pipelineId") String pipelineId) {
return ok(PipelineManager.getPipeline(pipelineId));
}
@@ -114,6 +126,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@JacksonSerialized
@Operation(summary = "Start the pipeline with the given id",
tags = {"Pipeline"})
+ @PreAuthorize(AuthConstants.HAS_UPDATE_PIPELINE_PRIVILEGE)
public Response start(@PathParam("pipelineId") String pipelineId) {
try {
PipelineOperationStatus status = PipelineManager.startPipeline(pipelineId);
@@ -131,6 +144,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@JacksonSerialized
@Operation(summary = "Stop the pipeline with the given id",
tags = {"Pipeline"})
+ @PreAuthorize(AuthConstants.HAS_UPDATE_PIPELINE_PRIVILEGE)
public Response stop(@PathParam("pipelineId") String pipelineId,
@QueryParam("forceStop") @DefaultValue("false") boolean forceStop) {
try {
@@ -148,6 +162,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@JacksonSerialized
@Operation(summary = "Store a new pipeline",
tags = {"Pipeline"})
+ @PreAuthorize(AuthConstants.HAS_CREATE_PIPELINE_PRIVILEGE)
public Response addPipeline(Pipeline pipeline) {
String pipelineId = PipelineManager.addPipeline(getAuthenticatedUsername(), pipeline);
@@ -161,6 +176,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@Produces(MediaType.APPLICATION_JSON)
@JacksonSerialized
@Hidden
+ @PreAuthorize(AuthConstants.HAS_CREATE_PIPELINE_PRIVILEGE)
public Response recommend(Pipeline pipeline) {
try {
return ok(Operations.findRecommendedElements(getAuthenticatedUsername(), pipeline));
@@ -183,6 +199,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@Consumes(MediaType.APPLICATION_JSON)
@JacksonSerialized
@Hidden
+ @PreAuthorize(AuthConstants.HAS_CREATE_PIPELINE_PRIVILEGE)
public Response updateDataSet(SpDataSet spDataSet) {
return ok(Operations.updateDataSet(spDataSet));
}
@@ -193,6 +210,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@Consumes(MediaType.APPLICATION_JSON)
@JacksonSerialized
@Hidden
+ @PreAuthorize(AuthConstants.HAS_CREATE_PIPELINE_PRIVILEGE)
public Response update(Pipeline pipeline) {
try {
return ok(Operations.validatePipeline(pipeline, true));
@@ -226,6 +244,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@JacksonSerialized
@Operation(summary = "Update an existing pipeline",
tags = {"Pipeline"})
+ @PreAuthorize(AuthConstants.HAS_UPDATE_PIPELINE_PRIVILEGE)
public Response overwritePipeline(@PathParam("pipelineId") String pipelineId,
Pipeline pipeline) {
Pipeline storedPipeline = getPipelineStorage().getPipeline(pipelineId);
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/SemanticEventProducer.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/SemanticEventProducer.java
index 284761d..bf5c921 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/SemanticEventProducer.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/SemanticEventProducer.java
@@ -28,6 +28,7 @@ import org.apache.streampipes.rest.shared.annotation.GsonWithIds;
import org.apache.streampipes.rest.shared.annotation.JacksonSerialized;
import org.apache.streampipes.rest.shared.util.SpMediaType;
import org.apache.streampipes.storage.couchdb.utils.Filter;
+import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
@@ -35,6 +36,7 @@ import javax.ws.rs.core.Response;
import java.util.List;
import java.util.stream.Collectors;
+@Component
@Path("/v2/streams")
public class SemanticEventProducer extends AbstractAuthGuardedRestResource implements IPipelineElement {
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/UserResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/UserResource.java
index 95a452e..c34b0ae 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/UserResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/UserResource.java
@@ -184,7 +184,7 @@ public class UserResource extends AbstractAuthGuardedRestResource {
}
private boolean isAdmin() {
- return SecurityContextHolder.getContext().getAuthentication().getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(Role.ADMIN.name()));
+ return SecurityContextHolder.getContext().getAuthentication().getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(Role.ROLE_ADMIN.name()));
}
private void updateUser(UserAccount existingUser, UserAccount user) {
diff --git a/ui/src/app/_enums/user-role.enum.ts b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/PermissionResource.java
similarity index 82%
copy from ui/src/app/_enums/user-role.enum.ts
copy to streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/PermissionResource.java
index 681f625..3c8cfd7 100644
--- a/ui/src/app/_enums/user-role.enum.ts
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/PermissionResource.java
@@ -15,15 +15,12 @@
* limitations under the License.
*
*/
+package org.apache.streampipes.rest.impl.admin;
+
+import javax.ws.rs.Path;
+
+@Path("/v2/admin/permissions")
+public class PermissionResource {
+
-export enum UserRole {
- ADMIN,
- PIPELINE_ADMIN,
- DASHBOARD_ADMIN,
- DATA_EXPLORER_ADMIN,
- CONNECT_ADMIN,
- DASHBOARD_USER,
- DATA_EXPLORER_USER,
- PIPELINE_USER,
- APP_USER
}
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/AuthConstants.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/AuthConstants.java
new file mode 100644
index 0000000..7ee6da7
--- /dev/null
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/AuthConstants.java
@@ -0,0 +1,47 @@
+/*
+ * 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.rest.impl.security;
+
+import static org.apache.streampipes.model.client.user.Privilege.Constants.*;
+import static org.apache.streampipes.model.client.user.Role.Constants.*;
+
+public class AuthConstants {
+
+ private static final String HAS_ANY_AUTHORITY = "hasAnyAuthority('";
+ private static final String HAS_ANY_ROLE = "hasAnyRole('";
+ private static final String Q = "'";
+ private static final String BS = "(";
+ private static final String BE = ")";
+ private static final String BE2 = "))";
+ private static final String OR = " or ";
+
+ public static final String IS_ADMIN_ROLE = HAS_ANY_AUTHORITY + ROLE_ADMIN_VALUE + Q + BE;
+
+ public static final String IS_PIPELINE_ADMIN_ROLE = HAS_ANY_ROLE + ROLE_PIPELINE_ADMIN_VALUE + Q + BE;
+ public static final String IS_PIPELINE_USER_ROLE = HAS_ANY_ROLE + ROLE_PIPELINE_USER_VALUE + Q + BE;
+
+ public static final String IS_DASHBOARD_ADMIN_ROLE = HAS_ANY_ROLE + ROLE_DASHBOARD_ADMIN_VALUE + Q + BE;
+ public static final String IS_DASHBOARD_USER_ROLE = HAS_ANY_ROLE + ROLE_DASHBOARD_USER_VALUE + Q + BE;
+
+ public static final String HAS_READ_PIPELINE_PRIVILEGE = BS + IS_ADMIN_ROLE + OR + HAS_ANY_AUTHORITY + PRIVILEGE_READ_PIPELINE_VALUE + Q + BE2;
+ public static final String HAS_CREATE_PIPELINE_PRIVILEGE = BS + IS_ADMIN_ROLE + OR + HAS_ANY_AUTHORITY + PRIVILEGE_CREATE_PIPELINE_VALUE + Q + BE2;
+ public static final String HAS_UPDATE_PIPELINE_PRIVILEGE = BS + IS_ADMIN_ROLE + OR + HAS_ANY_AUTHORITY + PRIVILEGE_UPDATE_PIPELINE_VALUE + Q + BE2;
+ public static final String HAS_DELETE_PIPELINE_PRIVILEGE = BS + IS_ADMIN_ROLE + OR + HAS_ANY_AUTHORITY + PRIVILEGE_DELETE_PIPELINE_VALUE + Q + BE2;
+
+
+}
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/SpPermissionEvaluator.java
similarity index 56%
copy from streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java
copy to streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/SpPermissionEvaluator.java
index ca87883..6769d51 100644
--- a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/SpPermissionEvaluator.java
@@ -15,18 +15,26 @@
* limitations under the License.
*
*/
+package org.apache.streampipes.rest.impl.security;
-package org.apache.streampipes.model.client.user;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.access.PermissionEvaluator;
+import org.springframework.security.core.Authentication;
-public enum Role {
- ADMIN,
- PIPELINE_ADMIN,
- DASHBOARD_ADMIN,
- DATA_EXPLORER_ADMIN,
- CONNECT_ADMIN,
- DASHBOARD_USER,
- DATA_EXPLORER_USER,
- PIPELINE_USER,
- APP_USER
+import java.io.Serializable;
+@Configuration
+public class SpPermissionEvaluator implements PermissionEvaluator {
+
+ @Override
+ public boolean hasPermission(Authentication authentication, Object o, Object o1) {
+
+ return true;
+ }
+
+ @Override
+ public boolean hasPermission(Authentication authentication, Serializable serializable, String s, Object o) {
+
+ return true;
+ }
}
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 5aa5353..6810f6a 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
@@ -17,25 +17,24 @@
*/
package org.apache.streampipes.user.management.model;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.streampipes.model.client.user.Principal;
-import org.apache.streampipes.model.client.user.Role;
-import org.apache.streampipes.storage.management.StorageDispatcher;
+import org.apache.streampipes.user.management.util.AuthorityBuilder;
+import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
+import java.util.Collection;
import java.util.Set;
+import java.util.stream.Collectors;
public abstract class PrincipalUserDetails<T extends Principal> implements UserDetails {
protected T details;
- private Set<Role> allRoles;
+ private Set<String> allAuthorities;
public PrincipalUserDetails(T details) {
this.details = details;
- this.allRoles = this.details.getRoles();
- details.getGroups().forEach(groupId -> {
- Set<Role> groupRoles = StorageDispatcher.INSTANCE.getNoSqlStore().getUserGroupStorage().getElementById(groupId).getRoles();
- allRoles.addAll(groupRoles);
- });
+ this.allAuthorities = new AuthorityBuilder(details).buildAllAuthorities();
}
public T getDetails() {
@@ -71,4 +70,10 @@ public abstract class PrincipalUserDetails<T extends Principal> implements UserD
return this.details.getUsername();
}
+ @JsonIgnore
+ @Override
+ public Collection<? extends GrantedAuthority> getAuthorities() {
+ return allAuthorities.stream().map(r -> (GrantedAuthority) () -> r).collect(Collectors.toList());
+ }
+
}
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 4fe13e5..fee4703 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
@@ -17,12 +17,7 @@
*/
package org.apache.streampipes.user.management.model;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.streampipes.model.client.user.ServiceAccount;
-import org.springframework.security.core.GrantedAuthority;
-
-import java.util.Collection;
-import java.util.stream.Collectors;
public class ServiceAccountDetails extends PrincipalUserDetails<ServiceAccount> {
@@ -31,12 +26,6 @@ public class ServiceAccountDetails extends PrincipalUserDetails<ServiceAccount>
super(details);
}
- @JsonIgnore
- @Override
- public Collection<? extends GrantedAuthority> getAuthorities() {
- return details.getRoles().stream().map(Enum::toString).map(r -> (GrantedAuthority) () -> r).collect(Collectors.toList());
- }
-
@Override
public String getPassword() {
return null;
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 0a3702d..da24050 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,10 +18,6 @@
package org.apache.streampipes.user.management.model;
import org.apache.streampipes.model.client.user.UserAccount;
-import org.springframework.security.core.GrantedAuthority;
-
-import java.util.Collection;
-import java.util.stream.Collectors;
public class UserAccountDetails extends PrincipalUserDetails<UserAccount> {
@@ -30,11 +26,6 @@ public class UserAccountDetails extends PrincipalUserDetails<UserAccount> {
}
@Override
- public Collection<? extends GrantedAuthority> getAuthorities() {
- return details.getRoles().stream().map(Enum::toString).map(r -> (GrantedAuthority) () -> r).collect(Collectors.toList());
- }
-
- @Override
public String getPassword() {
return details.getPassword();
}
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/util/AuthorityBuilder.java
similarity index 53%
copy from streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/PrincipalUserDetails.java
copy to streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/AuthorityBuilder.java
index 5aa5353..9d9e13c 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/util/AuthorityBuilder.java
@@ -15,60 +15,54 @@
* limitations under the License.
*
*/
-package org.apache.streampipes.user.management.model;
+package org.apache.streampipes.user.management.util;
import org.apache.streampipes.model.client.user.Principal;
import org.apache.streampipes.model.client.user.Role;
import org.apache.streampipes.storage.management.StorageDispatcher;
-import org.springframework.security.core.userdetails.UserDetails;
+import java.util.HashSet;
import java.util.Set;
-public abstract class PrincipalUserDetails<T extends Principal> implements UserDetails {
+public class AuthorityBuilder {
- protected T details;
- private Set<Role> allRoles;
+ private Set<String> allAuthorities;
+ private Principal principal;
- public PrincipalUserDetails(T details) {
- this.details = details;
- this.allRoles = this.details.getRoles();
- details.getGroups().forEach(groupId -> {
- Set<Role> groupRoles = StorageDispatcher.INSTANCE.getNoSqlStore().getUserGroupStorage().getElementById(groupId).getRoles();
- allRoles.addAll(groupRoles);
- });
+ public AuthorityBuilder(Principal principal) {
+ this.allAuthorities = new HashSet<>();
+ this.principal = principal;
}
- public T getDetails() {
- return details;
- }
+ public Set<String> buildAllAuthorities() {
+ allAuthorities.addAll(buildAllUserRoles());
+ allAuthorities.addAll(buildAllGroupRoles());
- public void setDetails(T details) {
- this.details = details;
+ return allAuthorities;
}
- @Override
- public boolean isAccountNonExpired() {
- return !this.details.isAccountExpired();
+ private Set<String> buildAllUserRoles() {
+ return buildAllRoles(principal.getRoles());
}
- @Override
- public boolean isAccountNonLocked() {
- return !this.details.isAccountLocked();
- }
+ private Set<String> buildAllGroupRoles() {
+ Set<String> allRoles = new HashSet<>();
+ principal.getGroups().forEach(groupId -> {
+ Set<Role> groupRoles = StorageDispatcher.INSTANCE.getNoSqlStore().getUserGroupStorage().getElementById(groupId).getRoles();
+ allRoles.addAll(buildAllRoles(groupRoles));
+ });
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
+ return allRoles;
}
- @Override
- public boolean isEnabled() {
- return this.details.isAccountEnabled();
- }
+ private Set<String> buildAllRoles(Set<Role> originalRoles) {
+ Set<String> roles = new HashSet<>();
+ originalRoles.forEach(role -> {
+ roles.add(role.name());
+ role.getPrivileges().forEach(p -> roles.add(p.name()));
+ });
- @Override
- public String getUsername() {
- return this.details.getUsername();
+ return roles;
}
}
diff --git a/ui/deployment/appng5.module.mst b/ui/deployment/appng5.module.mst
index 9fd3b77..f153598 100644
--- a/ui/deployment/appng5.module.mst
+++ b/ui/deployment/appng5.module.mst
@@ -56,6 +56,7 @@ import { PlatformServicesModule } from "./platform-services/platform.module";
import { ServicesModule } from "./services/services.module";
import { ApidocsModule } from "./apidocs/apidocs.module";
import { HttpInterceptorProvider } from './http-interceptor';
+import { AvailableRolesService } from './services/available-roles.service';
import * as $ from 'jquery';
@@ -92,6 +93,7 @@ import * as $ from 'jquery';
],
providers: [
AuthService,
+ AvailableRolesService,
NotificationCountService,
{ provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorProvider, multi: true },
{ provide: Logger, useClass: ConsoleLogService },
diff --git a/ui/src/app/_enums/user-role.enum.ts b/ui/src/app/_enums/user-role.enum.ts
index 681f625..68175f7 100644
--- a/ui/src/app/_enums/user-role.enum.ts
+++ b/ui/src/app/_enums/user-role.enum.ts
@@ -17,13 +17,13 @@
*/
export enum UserRole {
- ADMIN,
- PIPELINE_ADMIN,
- DASHBOARD_ADMIN,
- DATA_EXPLORER_ADMIN,
- CONNECT_ADMIN,
- DASHBOARD_USER,
- DATA_EXPLORER_USER,
- PIPELINE_USER,
- APP_USER
+ ROLE_ADMIN = 'ROLE_ADMIN',
+ ROLE_PIPELINE_ADMIN = 'ROLE_PIPELINE_ADMIN',
+ ROLE_DASHBOARD_ADMIN = 'ROLE_DASHBOARD_ADMIN',
+ ROLE_DATA_EXPLORER_ADMIN = 'ROLE_DATA_EXPLORER_ADMIN',
+ ROLE_CONNECT_ADMIN = 'ROLE_CONNECT_ADMIN',
+ ROLE_DASHBOARD_USER = 'ROLE_DASHBOARD_USER',
+ ROLE_DATA_EXPLORER_USER = 'ROLE_DATA_EXPLORER_USER',
+ ROLE_PIPELINE_USER = 'ROLE_PIPELINE_USER',
+ ROLE_APP_USER = 'ROLE_APP_USER'
}
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java b/ui/src/app/_models/auth.model.ts
similarity index 74%
copy from streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java
copy to ui/src/app/_models/auth.model.ts
index ca87883..3ff3c31 100644
--- a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Role.java
+++ b/ui/src/app/_models/auth.model.ts
@@ -16,17 +16,13 @@
*
*/
-package org.apache.streampipes.model.client.user;
+import { Privilege, Role } from '../core-model/gen/streampipes-model-client';
+import { UserRole } from '../_enums/user-role.enum';
-public enum Role {
- ADMIN,
- PIPELINE_ADMIN,
- DASHBOARD_ADMIN,
- DATA_EXPLORER_ADMIN,
- CONNECT_ADMIN,
- DASHBOARD_USER,
- DATA_EXPLORER_USER,
- PIPELINE_USER,
- APP_USER
+export type RoleModel = Privilege | Role;
+export interface RoleDescription {
+ role: UserRole;
+ roleTitle: string;
+ roleDescription: string;
}
diff --git a/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.html b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.html
index f16b0fe..1b80f65 100644
--- a/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.html
+++ b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.html
@@ -31,9 +31,9 @@
</div>
<div fxLayout="column" class="general-options-panel">
<span class="general-options-header">Roles</span>
- <mat-checkbox *ngFor="let role of availableRoles" [value]="role"
- [checked]="group.roles.indexOf(role) > -1" (change)="changeRoleAssignment($event)">
- {{role}}
+ <mat-checkbox *ngFor="let role of availableRoles" [value]="role.role"
+ [checked]="group.roles.indexOf(role.role) > -1" (change)="changeRoleAssignment($event)">
+ {{role.roleTitle}}
</mat-checkbox>
</div>
</form>
diff --git a/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.ts b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.ts
index f58a2da..745081c 100644
--- a/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.ts
+++ b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.ts
@@ -23,6 +23,8 @@ import { UserRole } from '../../../_enums/user-role.enum';
import { DialogRef } from '../../../core-ui/dialog/base-dialog/dialog-ref';
import { UserGroupService } from '../../../platform-services/apis/user-group.service';
import { MatCheckboxChange } from '@angular/material/checkbox';
+import { RoleDescription } from '../../../_models/auth.model';
+import { AvailableRolesService } from '../../../services/available-roles.service';
@Component({
selector: 'sp-edit-group-dialog',
@@ -39,15 +41,16 @@ export class EditGroupDialogComponent implements OnInit {
editMode: boolean;
parentForm: FormGroup;
- availableRoles: string[];
+ availableRoles: RoleDescription[];
clonedGroup: Group;
constructor(private fb: FormBuilder,
+ private availableRolesService: AvailableRolesService,
private dialogRef: DialogRef<EditGroupDialogComponent>,
private userGroupService: UserGroupService) {}
ngOnInit(): void {
- this.availableRoles = Object.values(UserRole).filter(value => typeof value === 'string') as string[];
+ this.availableRoles = this.availableRolesService.getAvailableRoles();
this.clonedGroup = Group.fromData(this.group, new Group());
this.parentForm = this.fb.group({});
this.parentForm.addControl('groupName', new FormControl(this.clonedGroup.groupName, Validators.required));
diff --git a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
index 3e5427a..ea3017d 100644
--- a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
+++ b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
@@ -74,9 +74,9 @@
</div>
<div fxLayout="column" class="general-options-panel">
<span class="general-options-header">Roles</span>
- <mat-checkbox *ngFor="let role of availableRoles" [value]="role"
- [checked]="user.roles.indexOf(role) > -1" (change)="changeRoleAssignment($event)">
- {{role}}
+ <mat-checkbox *ngFor="let role of availableRoles" [value]="role.role"
+ [checked]="user.roles.indexOf(role.role) > -1" (change)="changeRoleAssignment($event)">
+ {{role.roleTitle}}
</mat-checkbox>
</div>
<div fxLayout="column" class="general-options-panel">
diff --git a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.ts b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.ts
index 60b5a0e..b6357db 100644
--- a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.ts
+++ b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.ts
@@ -37,6 +37,8 @@ import { UserRole } from '../../../_enums/user-role.enum';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { UserService } from '../../../platform-services/apis/user.service';
import { UserGroupService } from '../../../platform-services/apis/user-group.service';
+import { RoleDescription } from '../../../_models/auth.model';
+import { AvailableRolesService } from '../../../services/available-roles.service';
@Component({
selector: 'sp-edit-user-dialog',
@@ -56,17 +58,18 @@ export class EditUserDialogComponent implements OnInit {
parentForm: FormGroup;
clonedUser: UserAccount | ServiceAccount;
- availableRoles: string[];
+ availableRoles: RoleDescription[];
availableGroups: Group[] = [];
constructor(private dialogRef: DialogRef<EditUserDialogComponent>,
+ private availableRolesService: AvailableRolesService,
private fb: FormBuilder,
private userService: UserService,
private userGroupService: UserGroupService) {
}
ngOnInit(): void {
- this.availableRoles = Object.values(UserRole).filter(value => typeof value === 'string') as string[];
+ this.availableRoles = this.availableRolesService.availableRoles;
this.userGroupService.getAllUserGroups().subscribe(response => {
this.availableGroups = response;
});
@@ -83,7 +86,7 @@ export class EditUserDialogComponent implements OnInit {
this.parentForm.addControl('clientSecret', new FormControl(this.clonedUser.clientSecret));
}
- if (!this.editMode && this.isUserAccount) {
+ if (!this.editMode && this.clonedUser instanceof UserAccount) {
this.parentForm.addControl('password', new FormControl(this.clonedUser.password, Validators.required));
this.parentForm.addControl('repeatPassword', new FormControl());
this.parentForm.setValidators(this.checkPasswords);
@@ -96,14 +99,13 @@ export class EditUserDialogComponent implements OnInit {
if (this.clonedUser instanceof UserAccount) {
this.clonedUser.email = v.email;
this.clonedUser.fullName = v.fullName;
+ if (!this.editMode) {
+ this.clonedUser.password = v.password;
+ }
} else {
this.clonedUser.clientSecret = v.clientSecret;
}
- if (!this.editMode) {
- this.clonedUser.password = v.password;
- }
});
-
}
checkPasswords: ValidatorFn = (group: AbstractControl): ValidationErrors | null => {
diff --git a/ui/src/app/core-model/gen/streampipes-model-client.ts b/ui/src/app/core-model/gen/streampipes-model-client.ts
index b99c706..93841c1 100644
--- a/ui/src/app/core-model/gen/streampipes-model-client.ts
+++ b/ui/src/app/core-model/gen/streampipes-model-client.ts
@@ -19,7 +19,7 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
-// Generated using typescript-generator version 2.27.744 on 2021-10-05 10:08:33.
+// Generated using typescript-generator version 2.27.744 on 2021-10-12 09:29:49.
export class Element {
elementId: string;
@@ -98,10 +98,6 @@ export class FileMetadata {
}
}
-export interface GrantedAuthority {
- authority: string;
-}
-
export class Group {
groupId: string;
groupName: string;
@@ -144,20 +140,15 @@ export class MatchingResultMessage {
}
}
-export class Principal implements UserDetails {
+export class Principal {
accountEnabled: boolean;
accountExpired: boolean;
accountLocked: boolean;
- accountNonExpired: boolean;
- accountNonLocked: boolean;
- authorities: GrantedAuthority[];
- credentialsNonExpired: boolean;
- enabled: boolean;
groups: string[];
+ objectPermissions: string[];
ownActions: Element[];
ownSepas: Element[];
ownSources: Element[];
- password: string;
principalId: string;
principalType: PrincipalType;
rev: string;
@@ -169,21 +160,16 @@ export class Principal implements UserDetails {
return data;
}
const instance = target || new Principal();
- instance.enabled = data.enabled;
- instance.username = data.username;
- instance.password = data.password;
- instance.accountNonExpired = data.accountNonExpired;
- instance.accountNonLocked = data.accountNonLocked;
- instance.credentialsNonExpired = data.credentialsNonExpired;
- instance.authorities = __getCopyArrayFn(__identity<GrantedAuthority>())(data.authorities);
instance.principalId = data.principalId;
instance.rev = data.rev;
instance.accountEnabled = data.accountEnabled;
instance.accountLocked = data.accountLocked;
instance.accountExpired = data.accountExpired;
+ instance.username = data.username;
instance.ownSources = __getCopyArrayFn(Element.fromData)(data.ownSources);
instance.ownSepas = __getCopyArrayFn(Element.fromData)(data.ownSepas);
instance.ownActions = __getCopyArrayFn(Element.fromData)(data.ownActions);
+ instance.objectPermissions = __getCopyArrayFn(__identity<string>())(data.objectPermissions);
instance.roles = __getCopyArrayFn(__identity<Role>())(data.roles);
instance.groups = __getCopyArrayFn(__identity<string>())(data.groups);
instance.principalType = data.principalType;
@@ -229,6 +215,7 @@ export class UserAccount extends Principal {
email: string;
fullName: string;
hideTutorial: boolean;
+ password: string;
preferredDataProcessors: string[];
preferredDataSinks: string[];
preferredDataStreams: string[];
@@ -242,6 +229,7 @@ export class UserAccount extends Principal {
super.fromData(data, instance);
instance.email = data.email;
instance.fullName = data.fullName;
+ instance.password = data.password;
instance.preferredDataStreams = __getCopyArrayFn(__identity<string>())(data.preferredDataStreams);
instance.preferredDataProcessors = __getCopyArrayFn(__identity<string>())(data.preferredDataProcessors);
instance.preferredDataSinks = __getCopyArrayFn(__identity<string>())(data.preferredDataSinks);
@@ -267,16 +255,6 @@ export class UserApiToken {
}
}
-export interface UserDetails {
- accountNonExpired: boolean;
- accountNonLocked: boolean;
- authorities: GrantedAuthority[];
- credentialsNonExpired: boolean;
- enabled: boolean;
- password: string;
- username: string;
-}
-
export class UserInfo {
darkMode: boolean;
displayName: string;
@@ -302,7 +280,9 @@ export class UserInfo {
export type PrincipalType = "USER_ACCOUNT" | "SERVICE_ACCOUNT";
-export type Role = "ADMIN" | "PIPELINE_ADMIN" | "DASHBOARD_ADMIN" | "DATA_EXPLORER_ADMIN" | "CONNECT_ADMIN" | "DASHBOARD_USER" | "DATA_EXPLORER_USER" | "PIPELINE_USER" | "APP_USER";
+export type Privilege = "PRIVILEGE_CREATE_PIPELINE" | "PRIVILEGE_READ_PIPELINE" | "PRIVILEGE_UPDATE_PIPELINE" | "PRIVILEGE_DELETE_PIPELINE" | "PRIVILEGE_CREATE_ADAPTER" | "PRIVILEGE_READ_ADAPTER" | "PRIVILEGE_UPDATE_ADAPTER" | "PRIVILEGE_DELETE_ADAPTER" | "PRIVILEGE_CREATE_PIPELINE_ELEMENT" | "PRIVILEGE_READ_PIPELINE_ELEMENT" | "PRIVILEGE_UPDATE_PIPELINE_ELEMENT" | "PRIVILEGE_DELETE_PIPELINE_ELEMENT" | "PRIVILEGE_CREATE_DASHBOARD" | "PRIVILEGE_READ_DASHBOARD" | "PRIVILEGE_UPDATE_DASHBOAR [...]
+
+export type Role = "ROLE_ADMIN" | "ROLE_PIPELINE_ADMIN" | "ROLE_DASHBOARD_ADMIN" | "ROLE_DATA_EXPLORER_ADMIN" | "ROLE_CONNECT_ADMIN" | "ROLE_DASHBOARD_USER" | "ROLE_DATA_EXPLORER_USER" | "ROLE_PIPELINE_USER" | "ROLE_APP_USER";
function __getCopyArrayFn<T>(itemCopyFn: (item: T) => T): (array: T[]) => T[] {
return (array: T[]) => __copyArray(array, itemCopyFn);
diff --git a/ui/src/app/services/auth.service.ts b/ui/src/app/services/auth.service.ts
index c6eff77..42fe5e3 100644
--- a/ui/src/app/services/auth.service.ts
+++ b/ui/src/app/services/auth.service.ts
@@ -26,7 +26,7 @@ import { filter, map, switchMap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { LoginService } from '../login/services/login.service';
import { PageName } from '../_enums/page-name.enum';
-import { UserRole } from '../_enums/user-role.enum';
+import { RoleModel } from '../_models/auth.model';
@Injectable()
export class AuthService {
@@ -56,6 +56,7 @@ export class AuthService {
const jwtHelper: JwtHelperService = new JwtHelperService({});
const decodedToken = jwtHelper.decodeToken(data.accessToken);
this.tokenStorage.saveToken(data.accessToken);
+ console.log(decodedToken.user);
this.tokenStorage.saveUser(decodedToken.user);
this.authToken$.next(data.accessToken);
this.user$.next(decodedToken.user);
@@ -123,13 +124,13 @@ export class AuthService {
return this.getCurrentUser().roles;
}
- public hasRole(role: UserRole): boolean {
- return this.getUserRoles().includes(UserRole[role]);
+ public hasRole(role: RoleModel): boolean {
+ return this.getUserRoles().includes(role);
}
- public hasAnyRole(roles: UserRole[]): boolean {
+ public hasAnyRole(roles: RoleModel[]): boolean {
if (Array.isArray(roles)) {
- return roles.reduce((aggregator: false, role: UserRole) => aggregator || this.hasRole(role), false);
+ return roles.reduce((aggregator: false, role: RoleModel) => aggregator || this.hasRole(role), false);
}
return false;
@@ -148,30 +149,30 @@ export class AuthService {
}
isAccessGranted(pageName: PageName) {
- if (this.hasRole(UserRole.ADMIN)) {
+ if (this.hasRole('ROLE_ADMIN')) {
return true;
}
switch (pageName) {
case PageName.HOME:
return true;
case PageName.PIPELINE_EDITOR:
- return this.hasAnyRole([UserRole.PIPELINE_ADMIN]);
+ return this.hasAnyRole([]);
case PageName.PIPELINE_OVERVIEW:
- return this.hasAnyRole([UserRole.PIPELINE_ADMIN]);
+ return this.hasAnyRole(['ROLE_PIPELINE_ADMIN']);
case PageName.CONNECT:
- return this.hasAnyRole([UserRole.CONNECT_ADMIN]);
+ return this.hasAnyRole(['ROLE_CONNECT_ADMIN']);
case PageName.DASHBOARD:
- return this.hasAnyRole([UserRole.DASHBOARD_USER, UserRole.DASHBOARD_ADMIN]);
+ return this.hasAnyRole(['ROLE_DASHBOARD_USER', 'ROLE_DASHBOARD_ADMIN']);
case PageName.DATA_EXPLORER:
- return this.hasAnyRole([UserRole.DATA_EXPLORER_ADMIN, UserRole.DATA_EXPLORER_USER]);
+ return this.hasAnyRole(['ROLE_DATA_EXPLORER_ADMIN', 'ROLE_DATA_EXPLORER_USER']);
case PageName.APPS:
- return this.hasAnyRole([UserRole.APP_USER]);
+ return this.hasAnyRole(['ROLE_APP_USER']);
case PageName.FILE_UPLOAD:
- return this.hasAnyRole([UserRole.CONNECT_ADMIN, UserRole.PIPELINE_ADMIN]);
+ return this.hasAnyRole(['ROLE_CONNECT_ADMIN', 'ROLE_PIPELINE_ADMIN']);
case PageName.INSTALL_PIPELINE_ELEMENTS:
- return this.hasAnyRole([UserRole.ADMIN]);
+ return this.hasAnyRole(['ROLE_ADMIN']);
case PageName.SETTINGS:
- return this.hasAnyRole([UserRole.ADMIN]);
+ return this.hasAnyRole(['ROLE_ADMIN']);
default:
return true;
}
diff --git a/ui/src/app/services/available-roles.service.ts b/ui/src/app/services/available-roles.service.ts
new file mode 100644
index 0000000..e6b3024
--- /dev/null
+++ b/ui/src/app/services/available-roles.service.ts
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ *
+ */
+
+import { Injectable } from '@angular/core';
+import { RoleDescription } from '../_models/auth.model';
+import { UserRole } from '../_enums/user-role.enum';
+
+@Injectable()
+export class AvailableRolesService {
+
+ availableRoles: RoleDescription[] = [
+ {role: UserRole.ROLE_ADMIN, roleTitle: 'Admin', roleDescription: ''},
+ {role: UserRole.ROLE_APP_USER, roleTitle: 'App User', roleDescription: ''},
+ {role: UserRole.ROLE_DASHBOARD_USER, roleTitle: 'Dashboard User', roleDescription: ''},
+ {role: UserRole.ROLE_DASHBOARD_ADMIN, roleTitle: 'Dashboard Admin', roleDescription: ''},
+ {role: UserRole.ROLE_DATA_EXPLORER_USER, roleTitle: 'Data Explorer User', roleDescription: ''},
+ {role: UserRole.ROLE_DATA_EXPLORER_ADMIN, roleTitle: 'Data Explorer Admin', roleDescription: ''},
+ {role: UserRole.ROLE_CONNECT_ADMIN, roleTitle: 'Connect Admin', roleDescription: ''},
+ {role: UserRole.ROLE_PIPELINE_USER, roleTitle: 'Pipeline User', roleDescription: ''},
+ {role: UserRole.ROLE_PIPELINE_ADMIN, roleTitle: 'Pipeline Admin', roleDescription: ''},
+ ];
+
+
+ public getAvailableRoles(): RoleDescription[] {
+ return this.availableRoles;
+ }
+}