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/17 20:51:34 UTC
[incubator-streampipes] 02/02: [STREAMPIPES-426] Add initial draft
of permission management
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 df6d25b72ef06062a72c4a56b4ae5fa8132842be
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sun Oct 17 22:51:19 2021 +0200
[STREAMPIPES-426] Add initial draft of permission management
---
.../streampipes/commons/random/UUIDGenerator.java | 19 +---
.../streampipes/model/client/user/Group.java | 13 ++-
.../streampipes/model/client/user/Permission.java | 104 +++++++++++++++++++++
.../model/client/user/PermissionBuilder.java | 51 ++++++++++
.../streampipes/model/client/user/Principal.java | 12 +++
.../streampipes/model/client/user/Privilege.java | 52 ++++-------
.../apache/streampipes/model/client/user/Role.java | 6 +-
.../manager/permission/PermissionManager.java | 24 ++---
.../manager/pipeline/PipelineManager.java | 20 +++-
.../manager/setup/CouchDbInstallationStep.java | 18 +++-
.../base/impl/AbstractAuthGuardedRestResource.java | 11 +++
.../streampipes/rest/impl/PipelineResource.java | 8 +-
.../org/apache/streampipes/rest/impl/Version.java | 4 +-
.../rest/impl/security/AuthConstants.java | 1 +
.../rest/impl/security/SpPermissionEvaluator.java | 13 ++-
.../streampipes/storage/api/INoSqlStorage.java | 2 +
.../storage/api/IPermissionStorage.java | 27 +++---
.../streampipes/storage/api/IUserStorage.java | 6 +-
.../storage/couchdb/CouchDbStorageManager.java | 5 +
.../storage/couchdb/dao/AbstractDao.java | 28 ++----
.../couchdb/dao/{AbstractDao.java => CrudDao.java} | 22 ++---
.../dao/{FindAllCommand.java => CrudViewDao.java} | 19 ++--
.../storage/couchdb/dao/FindAllCommand.java | 10 +-
.../couchdb/impl/PermissionStorageImpl.java | 76 +++++++++++++++
.../storage/couchdb/impl/UserGroupStorageImpl.java | 18 ++--
.../storage/couchdb/impl/UserStorage.java | 41 +++-----
.../management/model/PrincipalUserDetails.java | 11 ++-
...Builder.java => GrantedAuthoritiesBuilder.java} | 4 +-
.../management/util/GrantedPermissionsBuilder.java | 44 ++++-----
29 files changed, 464 insertions(+), 205 deletions(-)
diff --git a/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java b/streampipes-commons/src/main/java/org/apache/streampipes/commons/random/UUIDGenerator.java
similarity index 63%
copy from streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
copy to streampipes-commons/src/main/java/org/apache/streampipes/commons/random/UUIDGenerator.java
index c42e0a4..5c0eb06 100644
--- a/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
+++ b/streampipes-commons/src/main/java/org/apache/streampipes/commons/random/UUIDGenerator.java
@@ -15,22 +15,13 @@
* limitations under the License.
*
*/
-package org.apache.streampipes.rest.core.base.impl;
+package org.apache.streampipes.commons.random;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.SecurityContext;
+import java.util.UUID;
-public class AbstractAuthGuardedRestResource extends AbstractRestResource {
+public class UUIDGenerator {
- @Context
- protected SecurityContext securityContext;
-
- protected boolean isAuthenticated() {
- return this.securityContext.getUserPrincipal() != null;
- }
-
- protected String getAuthenticatedUsername() {
- return this.securityContext.getUserPrincipal().getName();
+ public static String generateUuid() {
+ return UUID.randomUUID().toString().replace("-", "");
}
-
}
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Group.java b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Group.java
index 8ee6e90..8b319f0 100644
--- a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Group.java
+++ b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Group.java
@@ -17,11 +17,11 @@
*/
package org.apache.streampipes.model.client.user;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.gson.annotations.SerializedName;
import org.apache.streampipes.model.shared.annotation.TsModel;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
@TsModel
@@ -30,6 +30,9 @@ public class Group {
protected @SerializedName("_id") String groupId;
protected @SerializedName("_rev") String rev;
+ @JsonIgnore
+ private String $type = "group";
+
private String groupName;
private Set<Role> roles;
@@ -69,4 +72,12 @@ public class Group {
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
+
+ public String get$type() {
+ return $type;
+ }
+
+ public void set$type(String $type) {
+ this.$type = $type;
+ }
}
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Permission.java b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Permission.java
new file mode 100644
index 0000000..2c0f2cb
--- /dev/null
+++ b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Permission.java
@@ -0,0 +1,104 @@
+/*
+ * 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.model.client.user;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.gson.annotations.SerializedName;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Permission {
+
+ protected @SerializedName("_id") String permissionId;
+ protected @SerializedName("_rev") String rev;
+
+ @JsonIgnore
+ private String $type = "permission";
+
+ private String objectInstanceId;
+ private String objectClassName;
+
+ private String ownerSid;
+
+ private List<String> allowedSids;
+
+ public Permission() {
+ this.allowedSids = new ArrayList<>();
+ }
+
+ public String getPermissionId() {
+ return permissionId;
+ }
+
+ public void setPermissionId(String permissionId) {
+ this.permissionId = permissionId;
+ }
+
+ public String getRev() {
+ return rev;
+ }
+
+ public void setRev(String rev) {
+ this.rev = rev;
+ }
+
+ public String getObjectInstanceId() {
+ return objectInstanceId;
+ }
+
+ public void setObjectInstanceId(String objectInstanceId) {
+ this.objectInstanceId = objectInstanceId;
+ }
+
+ public String getObjectClassName() {
+ return objectClassName;
+ }
+
+ public void setObjectClassName(String objectClassName) {
+ this.objectClassName = objectClassName;
+ }
+
+ public String getOwnerSid() {
+ return ownerSid;
+ }
+
+ public void setOwnerSid(String ownerSid) {
+ this.ownerSid = ownerSid;
+ }
+
+ public void addAllowedSid(String sid) {
+ this.allowedSids.add(sid);
+ }
+
+ public List<String> getAllowedSids() {
+ return allowedSids;
+ }
+
+ public void setAllowedSids(List<String> allowedSids) {
+ this.allowedSids = allowedSids;
+ }
+
+ public String get$type() {
+ return $type;
+ }
+
+ public void set$type(String $type) {
+ this.$type = $type;
+ }
+}
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/PermissionBuilder.java b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/PermissionBuilder.java
new file mode 100644
index 0000000..70da030
--- /dev/null
+++ b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/PermissionBuilder.java
@@ -0,0 +1,51 @@
+/*
+ * 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.model.client.user;
+
+public class PermissionBuilder {
+
+ private Permission permission;
+
+ public static PermissionBuilder create(String objectInstanceId,
+ Class<?> objectInstanceClass,
+ String ownerSid) {
+ return new PermissionBuilder(
+ objectInstanceId,
+ objectInstanceClass,
+ ownerSid
+ );
+ }
+
+ private PermissionBuilder(String objectInstanceId,
+ Class<?> objectInstanceClass,
+ String ownerSid) {
+ this.permission = new Permission();
+ this.permission.setObjectInstanceId(objectInstanceId);
+ this.permission.setObjectClassName(objectInstanceClass.getCanonicalName());
+ this.permission.setOwnerSid(ownerSid);
+ }
+
+ public PermissionBuilder with(String sid) {
+ this.permission.addAllowedSid(sid);
+ return this;
+ }
+
+ public Permission build() {
+ return permission;
+ }
+}
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 777556a..0c06b40 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
@@ -18,6 +18,7 @@
package org.apache.streampipes.model.client.user;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
@@ -30,6 +31,9 @@ public abstract class Principal {
protected @SerializedName("_id") String principalId;
protected @SerializedName("_rev") String rev;
+ @JsonIgnore
+ private String $type = "principal";
+
private boolean accountEnabled;
private boolean accountLocked;
private boolean accountExpired;
@@ -189,4 +193,12 @@ public abstract class Principal {
public void setObjectPermissions(Set<String> objectPermissions) {
this.objectPermissions = objectPermissions;
}
+
+ public String get$type() {
+ return $type;
+ }
+
+ public void set$type(String $type) {
+ this.$type = $type;
+ }
}
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 4170e31..5950ba0 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
@@ -22,58 +22,50 @@ import org.apache.streampipes.model.shared.annotation.TsModel;
@TsModel
public enum Privilege {
// Pipelines
- 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_WRITE_PIPELINE(Constants.PRIVILEGE_WRITE_PIPELINE_VALUE),
PRIVILEGE_DELETE_PIPELINE(Constants.PRIVILEGE_DELETE_PIPELINE_VALUE),
// Adapters
- 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_WRITE_ADAPTER(Constants.PRIVILEGE_WRITE_ADAPTER_VALUE),
PRIVILEGE_DELETE_ADAPTER(Constants.PRIVILEGE_DELETE_ADAPTER_VALUE),
// Pipeline Elements
- 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_WRITE_PIPELINE_ELEMENT(Constants.PRIVILEGE_WRITE_PIPELINE_ELEMENT_VALUE),
PRIVILEGE_DELETE_PIPELINE_ELEMENT(Constants.PRIVILEGE_DELETE_PIPELINE_ELEMENT_VALUE),
// 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_WRITE_DASHBOARD(Constants.PRIVILEGE_WRITE_DASHBOARD_VALUE),
PRIVILEGE_DELETE_DASHBOARD(Constants.PRIVILEGE_DELETE_DASHBOARD_VALUE),
// 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_WRITE_DASHBOARD_WIDGET(Constants.PRIVILEGE_WRITE_DASHBOARD_WIDGET_VALUE),
PRIVILEGE_DELETE_DASHBOARD_WIDGET(Constants.PRIVILEGE_DELETE_DASHBOARD_WIDGET_VALUE),
// 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_WRITE_DATA_EXPLORER_VIEW(Constants.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW_VALUE),
PRIVILEGE_DELETE_DATA_EXPLORER_VIEW(Constants.PRIVILEGE_DELETE_DATA_EXPLORER_VIEW_VALUE),
// 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_WRITE_DATA_EXPLORER_WIDGET(Constants.PRIVILEGE_WRITE_DATA_EXPLORER_WIDGET_VALUE),
PRIVILEGE_DELETE_DATA_EXPLORER_WIDGET(Constants.PRIVILEGE_DELETE_DATA_EXPLORER_WIDGET_VALUE),
// Apps
PRIVILEGE_READ_APPS(Constants.PRIVILEGE_READ_APPS_VALUE),
- PRIVILEGE_UPDATE_APPS(Constants.PRIVILEGE_UPDATE_APPS_VALUE),
+ PRIVILEGE_WRITE_APPS(Constants.PRIVILEGE_WRITE_APPS_VALUE),
// NOTIFICATIONS
PRIVILEGE_READ_NOTIFICATIONS(Constants.PRIVILEGE_READ_NOTIFICATIONS_VALUE),
// 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_WRITE_FILES(Constants.PRIVILEGE_WRITE_FILES_VALUE),
PRIVILEGE_DELETE_FILES(Constants.PRIVILEGE_DELETE_FILES_VALUE);
private String privilegeString;
@@ -83,49 +75,41 @@ public enum Privilege {
}
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_WRITE_PIPELINE_VALUE = "PRIVILEGE_WRITE_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_WRITE_ADAPTER_VALUE = "PRIVILEGE_WRITE_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_WRITE_PIPELINE_ELEMENT_VALUE = "PRIVILEGE_WRITE_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_WRITE_DASHBOARD_VALUE = "PRIVILEGE_WRITE_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_WRITE_DASHBOARD_WIDGET_VALUE = "PRIVILEGE_WRITE_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_WRITE_DATA_EXPLORER_VIEW_VALUE = "PRIVILEGE_WRITE_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_WRITE_DATA_EXPLORER_WIDGET_VALUE = "PRIVILEGE_WRITE_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_WRITE_APPS_VALUE = "PRIVILEGE_WRITE_APPS";
public static final String PRIVILEGE_READ_NOTIFICATIONS_VALUE = "PRIVILEGE_READ_NOTIFICATIONS";
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_WRITE_FILES_VALUE = "PRIVILEGE_WRITE_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 11c5c2a..58adc39 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
@@ -30,17 +30,15 @@ public enum Role {
ROLE_PIPELINE_ADMIN(
Constants.ROLE_PIPELINE_ADMIN_VALUE,
- Privilege.PRIVILEGE_CREATE_PIPELINE,
Privilege.PRIVILEGE_READ_PIPELINE,
- Privilege.PRIVILEGE_UPDATE_PIPELINE,
+ Privilege.PRIVILEGE_WRITE_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_WRITE_DASHBOARD,
Privilege.PRIVILEGE_DELETE_DASHBOARD
),
diff --git a/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/permission/PermissionManager.java
similarity index 61%
copy from streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
copy to streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/permission/PermissionManager.java
index c42e0a4..0472dc7 100644
--- a/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/permission/PermissionManager.java
@@ -15,22 +15,18 @@
* limitations under the License.
*
*/
-package org.apache.streampipes.rest.core.base.impl;
+package org.apache.streampipes.manager.permission;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.SecurityContext;
+import org.apache.streampipes.model.client.user.Permission;
+import org.apache.streampipes.model.client.user.PermissionBuilder;
+import org.apache.streampipes.model.pipeline.Pipeline;
-public class AbstractAuthGuardedRestResource extends AbstractRestResource {
+public class PermissionManager {
- @Context
- protected SecurityContext securityContext;
-
- protected boolean isAuthenticated() {
- return this.securityContext.getUserPrincipal() != null;
- }
-
- protected String getAuthenticatedUsername() {
- return this.securityContext.getUserPrincipal().getName();
+ public Permission makePermission(Pipeline pipeline,
+ String ownerSid) {
+ return PermissionBuilder
+ .create(pipeline.getPipelineId(), pipeline.getClass(), ownerSid)
+ .build();
}
-
}
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 2e3172f..c1a0680 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
@@ -18,16 +18,19 @@
package org.apache.streampipes.manager.pipeline;
+import org.apache.streampipes.commons.random.UUIDGenerator;
import org.apache.streampipes.manager.operations.Operations;
+import org.apache.streampipes.manager.permission.PermissionManager;
import org.apache.streampipes.manager.storage.UserManagementService;
+import org.apache.streampipes.model.client.user.Permission;
import org.apache.streampipes.model.pipeline.Pipeline;
import org.apache.streampipes.model.pipeline.PipelineOperationStatus;
+import org.apache.streampipes.storage.api.IPermissionStorage;
import org.apache.streampipes.storage.api.IPipelineStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;
import java.util.Date;
import java.util.List;
-import java.util.UUID;
public class PipelineManager {
@@ -59,17 +62,20 @@ public class PipelineManager {
/**
* Adds a new pipeline for the user with the username to the storage
- * @param username
+ * @param principalSid the ID of the owner principal
* @param pipeline
* @return the pipelineId
*/
- public static String addPipeline(String username, Pipeline pipeline) {
+ public static String addPipeline(String principalSid, Pipeline pipeline) {
// call by reference bad smell
- String pipelineId = UUID.randomUUID().toString();
- preparePipelineBasics(username, pipeline, pipelineId);
+ String pipelineId = UUIDGenerator.generateUuid();
+ preparePipelineBasics(principalSid, pipeline, pipelineId);
Operations.storePipeline(pipeline);
+ Permission permission = new PermissionManager().makePermission(pipeline, principalSid);
+ getPermissionStorage().addPermission(permission);
+
return pipelineId;
}
@@ -121,4 +127,8 @@ public class PipelineManager {
private static IPipelineStorage getPipelineStorage() {
return StorageDispatcher.INSTANCE.getNoSqlStore().getPipelineStorageAPI();
}
+
+ private static IPermissionStorage getPermissionStorage() {
+ return StorageDispatcher.INSTANCE.getNoSqlStore().getPermissionStorage();
+ }
}
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java
index 7143075..c1a05f8 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java
@@ -142,17 +142,29 @@ public class CouchDbInstallationStep extends InstallationStep {
Map<String, MapReduce> views = new HashMap<>();
MapReduce passwordFunction = new MapReduce();
- passwordFunction.setMap("function(doc) { if(doc.username && doc.principalType === 'USER_ACCOUNT' && doc.password) { emit(doc.username, doc.password); } }");
+ passwordFunction.setMap("function(doc) { if(doc.properties.username && doc.properties.principalType === 'USER_ACCOUNT' && doc.properties.password) { emit(doc.properties.username, doc.properties.password); } }");
MapReduce usernameFunction = new MapReduce();
- usernameFunction.setMap("function(doc) { if(doc.username) { emit(doc.username, doc); } }");
+ usernameFunction.setMap("function(doc) { if(doc.properties.username) { emit(doc.properties.username, doc); } }");
+
+ MapReduce permissionFunction = new MapReduce();
+ permissionFunction.setMap("function(doc) { if(doc.$type === 'permission') { emit(doc._id, doc); } }");
+
+ MapReduce groupFunction = new MapReduce();
+ groupFunction.setMap("function(doc) { if(doc.$type === 'group') { emit(doc._id, doc); } }");
MapReduce tokenFunction = new MapReduce();
- tokenFunction.setMap("function(doc) { if (doc.userApiTokens) { doc.userApiTokens.forEach(function(token) { emit(token.hashedToken, doc.email); });}}");
+ tokenFunction.setMap("function(doc) { if (doc.properties.userApiTokens) { doc.properties.userApiTokens.forEach(function(token) { emit(token.properties.hashedToken, doc.properties.email); });}}");
+
+ MapReduce userPermissionFunction = new MapReduce();
+ userPermissionFunction.setMap("function(doc) { if (doc.$type === 'permission') {emit(doc.ownerSid, doc); for(var i = 0; i < doc.allowedSids.length; i++) {emit(doc.allowedSids[i],doc)}}}");
views.put("password", passwordFunction);
views.put("username", usernameFunction);
+ views.put("groups", groupFunction);
+ views.put("permissions", permissionFunction);
views.put("token", tokenFunction);
+ views.put("userpermissions", userPermissionFunction);
userDocument.setViews(views);
Response resp = Utils.getCouchDbUserClient().design().synchronizeWithDb(userDocument);
diff --git a/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java b/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
index c42e0a4..1e24ff5 100644
--- a/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
+++ b/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
@@ -17,6 +17,9 @@
*/
package org.apache.streampipes.rest.core.base.impl;
+import org.apache.streampipes.user.management.model.PrincipalUserDetails;
+import org.springframework.security.core.context.SecurityContextHolder;
+
import javax.ws.rs.core.Context;
import javax.ws.rs.core.SecurityContext;
@@ -33,4 +36,12 @@ public class AbstractAuthGuardedRestResource extends AbstractRestResource {
return this.securityContext.getUserPrincipal().getName();
}
+ protected PrincipalUserDetails<?> getPrincipal() {
+ return (PrincipalUserDetails<?>) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ }
+
+ protected String getAuthenticatedUserSid() {
+ return getPrincipal().getDetails().getPrincipalId();
+ }
+
}
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 d741409..55345c1 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
@@ -42,6 +42,7 @@ 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.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
@@ -68,11 +69,10 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
mediaType = "application/json",
array = @ArraySchema(schema = @Schema(implementation = Pipeline.class)))
})})
- @PreAuthorize(AuthConstants.IS_ADMIN_ROLE)
+ @PreAuthorize(AuthConstants.HAS_READ_PIPELINE_PRIVILEGE)
+ @PostFilter("hasPermission(filterObject.pipelineId, 'READ')")
public List<Pipeline> getOwn() {
return PipelineManager.getAllPipelines();
- //return ok(PipelineManager.getOwnPipelines(getAuthenticatedUsername()));
-
}
@GET
@@ -165,7 +165,7 @@ public class PipelineResource extends AbstractAuthGuardedRestResource {
@PreAuthorize(AuthConstants.HAS_CREATE_PIPELINE_PRIVILEGE)
public Response addPipeline(Pipeline pipeline) {
- String pipelineId = PipelineManager.addPipeline(getAuthenticatedUsername(), pipeline);
+ String pipelineId = PipelineManager.addPipeline(getAuthenticatedUserSid(), pipeline);
SuccessMessage message = Notifications.success("Pipeline stored");
message.addNotification(new Notification("id", pipelineId));
return ok(message);
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/Version.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/Version.java
index 733b434..d56851b 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/Version.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/Version.java
@@ -19,7 +19,7 @@ package org.apache.streampipes.rest.impl;
import org.apache.streampipes.manager.info.SystemInfoProvider;
import org.apache.streampipes.manager.info.VersionInfoProvider;
-import org.apache.streampipes.rest.core.base.impl.AbstractRestResource;
+import org.apache.streampipes.rest.core.base.impl.AbstractAuthGuardedRestResource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -28,7 +28,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/v2/info")
-public class Version extends AbstractRestResource {
+public class Version extends AbstractAuthGuardedRestResource {
@GET
@Path("/versions")
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
index 7ee6da7..f457f47 100644
--- 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
@@ -43,5 +43,6 @@ public class AuthConstants {
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;
+ public static final String IS_AUTHENTICATED = "isAuthenticated()";
}
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/SpPermissionEvaluator.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/SpPermissionEvaluator.java
index 6769d51..d33c153 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/SpPermissionEvaluator.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/security/SpPermissionEvaluator.java
@@ -17,6 +17,7 @@
*/
package org.apache.streampipes.rest.impl.security;
+import org.apache.streampipes.user.management.model.PrincipalUserDetails;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
@@ -27,14 +28,18 @@ import java.io.Serializable;
public class SpPermissionEvaluator implements PermissionEvaluator {
@Override
- public boolean hasPermission(Authentication authentication, Object o, Object o1) {
+ public boolean hasPermission(Authentication authentication, Object o, Object permission) {
+ String objectInstanceId = (String) o;
- return true;
+ return getUserDetails(authentication).getAllObjectPermissions().contains(objectInstanceId);
}
@Override
- public boolean hasPermission(Authentication authentication, Serializable serializable, String s, Object o) {
+ public boolean hasPermission(Authentication authentication, Serializable serializable, String s, Object permission) {
+ return getUserDetails(authentication).getAllObjectPermissions().contains(serializable.toString());
+ }
- return true;
+ private PrincipalUserDetails<?> getUserDetails(Authentication authentication) {
+ return (PrincipalUserDetails<?>) authentication.getPrincipal();
}
}
diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
index e2ce843..8b99e42 100644
--- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
+++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
@@ -65,4 +65,6 @@ public interface INoSqlStorage {
IPipelineElementDescriptionStorageCache getPipelineElementDescriptionStorage();
+ IPermissionStorage getPermissionStorage();
+
}
diff --git a/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IPermissionStorage.java
similarity index 62%
copy from streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
copy to streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IPermissionStorage.java
index c42e0a4..65ac07c 100644
--- a/streampipes-rest-core-base/src/main/java/org/apache/streampipes/rest/core/base/impl/AbstractAuthGuardedRestResource.java
+++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IPermissionStorage.java
@@ -15,22 +15,25 @@
* limitations under the License.
*
*/
-package org.apache.streampipes.rest.core.base.impl;
+package org.apache.streampipes.storage.api;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.SecurityContext;
+import org.apache.streampipes.model.client.user.Permission;
-public class AbstractAuthGuardedRestResource extends AbstractRestResource {
+import java.util.List;
+import java.util.Set;
- @Context
- protected SecurityContext securityContext;
+public interface IPermissionStorage {
- protected boolean isAuthenticated() {
- return this.securityContext.getUserPrincipal() != null;
- }
+ List<Permission> getAllPermissions();
- protected String getAuthenticatedUsername() {
- return this.securityContext.getUserPrincipal().getName();
- }
+ Permission getPermissionById(String permissionId);
+
+ void addPermission(Permission permission);
+
+ void updatePermission(Permission permission);
+
+ void deletePermission(String permissionId);
+
+ Set<String> getObjectPermissions(List<String> sids);
}
diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IUserStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IUserStorage.java
index d7f996a..be374cf 100644
--- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IUserStorage.java
+++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IUserStorage.java
@@ -17,13 +17,12 @@
*/
package org.apache.streampipes.storage.api;
-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.model.client.user.*;
import java.util.List;
public interface IUserStorage {
+
List<Principal> getAllUsers();
List<UserAccount> getAllUserAccounts();
@@ -47,4 +46,5 @@ public interface IUserStorage {
void deleteUser(String principalId);
Principal getUserById(String principalId);
+
}
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 e47f3fa..dba767e 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
@@ -135,4 +135,9 @@ public enum CouchDbStorageManager implements INoSqlStorage {
public IPipelineElementDescriptionStorageCache getPipelineElementDescriptionStorage() {
return new PipelineElementDescriptionStorageImpl();
}
+
+ @Override
+ public IPermissionStorage getPermissionStorage() {
+ return new PermissionStorageImpl();
+ }
}
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/AbstractDao.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/AbstractDao.java
index 5f88886..2e26b30 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/AbstractDao.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/AbstractDao.java
@@ -24,47 +24,39 @@ import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
-public class AbstractDao<T> {
+public class AbstractDao<T> extends CrudDao {
+
+ private static final String ALL_DOCS = "_all_docs";
- protected Supplier<CouchDbClient> couchDbClientSupplier;
protected Class<T> clazz;
public AbstractDao(Supplier<CouchDbClient> couchDbClientSupplier, Class<T> clazz) {
- this.couchDbClientSupplier = couchDbClientSupplier;
+ super(couchDbClientSupplier);
this.clazz = clazz;
}
public Tuple2<Boolean, String> persist(T objToPersist) {
- DbCommand<Tuple2<Boolean, String>, T> cmd = new PersistCommand<>(couchDbClientSupplier,
- objToPersist,
- clazz);
- return cmd.execute();
+ return persist(objToPersist, clazz);
}
public Boolean delete(String key) {
- DbCommand<Boolean, T> cmd = new DeleteCommand<>(couchDbClientSupplier, key, clazz);
- return cmd.execute();
+ return delete(key, clazz);
}
public Boolean update(T objToUpdate) {
- DbCommand<Boolean, T> cmd = new UpdateCommand<>(couchDbClientSupplier, objToUpdate, clazz);
- return cmd.execute();
+ return update(objToUpdate, clazz);
}
public Optional<T> find(String id) {
- DbCommand<Optional<T>, T> cmd = new FindCommand<>(couchDbClientSupplier, id, clazz);
- return cmd.execute();
+ return find(id, clazz);
}
public List<T> findAll() {
- DbCommand<List<T>, T> cmd = new FindAllCommand<>(couchDbClientSupplier, clazz);
- return cmd.execute();
+ return findAll(ALL_DOCS, clazz);
}
public T findWithNullIfEmpty(String id) {
- DbCommand<Optional<T>, T> cmd = new FindCommand<>(couchDbClientSupplier, id, clazz);
- return cmd.execute().orElse(null);
+ return findWithNullIfEmpty(id, clazz);
}
-
}
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/AbstractDao.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/CrudDao.java
similarity index 79%
copy from streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/AbstractDao.java
copy to streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/CrudDao.java
index 5f88886..05e8c16 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/AbstractDao.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/CrudDao.java
@@ -24,47 +24,43 @@ import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
-public class AbstractDao<T> {
+public class CrudDao {
protected Supplier<CouchDbClient> couchDbClientSupplier;
- protected Class<T> clazz;
- public AbstractDao(Supplier<CouchDbClient> couchDbClientSupplier, Class<T> clazz) {
+ public CrudDao(Supplier<CouchDbClient> couchDbClientSupplier) {
this.couchDbClientSupplier = couchDbClientSupplier;
- this.clazz = clazz;
}
- public Tuple2<Boolean, String> persist(T objToPersist) {
+ public <T> Tuple2<Boolean, String> persist(T objToPersist, Class<T> clazz) {
DbCommand<Tuple2<Boolean, String>, T> cmd = new PersistCommand<>(couchDbClientSupplier,
objToPersist,
clazz);
return cmd.execute();
}
- public Boolean delete(String key) {
+ public <T> Boolean delete(String key, Class<T> clazz) {
DbCommand<Boolean, T> cmd = new DeleteCommand<>(couchDbClientSupplier, key, clazz);
return cmd.execute();
}
- public Boolean update(T objToUpdate) {
+ public <T> Boolean update(T objToUpdate, Class<T> clazz) {
DbCommand<Boolean, T> cmd = new UpdateCommand<>(couchDbClientSupplier, objToUpdate, clazz);
return cmd.execute();
}
- public Optional<T> find(String id) {
+ public <T> Optional<T> find(String id, Class<T> clazz) {
DbCommand<Optional<T>, T> cmd = new FindCommand<>(couchDbClientSupplier, id, clazz);
return cmd.execute();
}
- public List<T> findAll() {
- DbCommand<List<T>, T> cmd = new FindAllCommand<>(couchDbClientSupplier, clazz);
+ public <T> List<T> findAll(String viewName, Class<T> clazz) {
+ DbCommand<List<T>, T> cmd = new FindAllCommand<>(couchDbClientSupplier, clazz, viewName);
return cmd.execute();
}
- public T findWithNullIfEmpty(String id) {
+ public <T> T findWithNullIfEmpty(String id, Class<T> clazz) {
DbCommand<Optional<T>, T> cmd = new FindCommand<>(couchDbClientSupplier, id, clazz);
return cmd.execute().orElse(null);
}
-
-
}
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/FindAllCommand.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/CrudViewDao.java
similarity index 71%
copy from streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/FindAllCommand.java
copy to streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/CrudViewDao.java
index b5830ba..5f61635 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/FindAllCommand.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/CrudViewDao.java
@@ -19,22 +19,23 @@ package org.apache.streampipes.storage.couchdb.dao;
import org.lightcouch.CouchDbClient;
-import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
-public class FindAllCommand<T> extends DbCommand<List<T>, T> {
+public class CrudViewDao extends CrudDao {
- public FindAllCommand(Supplier<CouchDbClient> couchDbClient, Class<T> clazz) {
- super(couchDbClient, clazz);
+ public CrudViewDao(Supplier<CouchDbClient> couchDbClientSupplier) {
+ super(couchDbClientSupplier);
}
- @Override
- protected List<T> executeCommand(CouchDbClient couchDbClient) {
- List<T> allResults = couchDbClient.view("_all_docs")
+ public <T> List<T> findByKey(String viewName,
+ String key,
+ Class<T> clazz) {
+ return couchDbClientSupplier
+ .get()
+ .view(viewName)
+ .key(key)
.includeDocs(true)
.query(clazz);
-
- return allResults != null ? allResults : Collections.emptyList();
}
}
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/FindAllCommand.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/FindAllCommand.java
index b5830ba..186dd64 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/FindAllCommand.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/FindAllCommand.java
@@ -25,13 +25,19 @@ import java.util.function.Supplier;
public class FindAllCommand<T> extends DbCommand<List<T>, T> {
- public FindAllCommand(Supplier<CouchDbClient> couchDbClient, Class<T> clazz) {
+ private String viewName;
+
+ public FindAllCommand(Supplier<CouchDbClient> couchDbClient,
+ Class<T> clazz,
+ String viewName) {
super(couchDbClient, clazz);
+ this.viewName = viewName;
}
@Override
protected List<T> executeCommand(CouchDbClient couchDbClient) {
- List<T> allResults = couchDbClient.view("_all_docs")
+ List<T> allResults = couchDbClient
+ .view(viewName)
.includeDocs(true)
.query(clazz);
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/PermissionStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/PermissionStorageImpl.java
new file mode 100644
index 0000000..b518c4a
--- /dev/null
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/PermissionStorageImpl.java
@@ -0,0 +1,76 @@
+/*
+ * 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.storage.couchdb.impl;
+
+import org.apache.streampipes.model.client.user.Permission;
+import org.apache.streampipes.storage.api.IPermissionStorage;
+import org.apache.streampipes.storage.couchdb.dao.CrudDao;
+import org.apache.streampipes.storage.couchdb.utils.Utils;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class PermissionStorageImpl extends CrudDao implements IPermissionStorage {
+
+ private String viewName = "users/permissions";
+
+ public PermissionStorageImpl() {
+ super(Utils::getCouchDbUserClient);
+ }
+
+ @Override
+ public List<Permission> getAllPermissions() {
+ return findAll(viewName, Permission.class);
+ }
+
+ @Override
+ public Permission getPermissionById(String permissionId) {
+ return findWithNullIfEmpty(permissionId, Permission.class);
+ }
+
+ @Override
+ public void addPermission(Permission permission) {
+ persist(permission, Permission.class);
+ }
+
+ @Override
+ public void updatePermission(Permission permission) {
+ update(permission, Permission.class);
+ }
+
+ @Override
+ public void deletePermission(String permissionId) {
+ delete(permissionId, Permission.class);
+ }
+
+ public Set<String> getObjectPermissions(List<String> principalSids) {
+ List<Permission> objectInstanceSids = couchDbClientSupplier
+ .get()
+ .view("users/userpermissions")
+ .keys(principalSids)
+ .includeDocs(true)
+ .query(Permission.class);
+
+ return toPermissionSet(objectInstanceSids);
+ }
+
+ private Set<String> toPermissionSet(List<Permission> permissions) {
+ return permissions.stream().map(Permission::getObjectInstanceId).collect(Collectors.toSet());
+ }
+}
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/UserGroupStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/UserGroupStorageImpl.java
index ef1db56..992f773 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/UserGroupStorageImpl.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/UserGroupStorageImpl.java
@@ -19,40 +19,42 @@ package org.apache.streampipes.storage.couchdb.impl;
import org.apache.streampipes.model.client.user.Group;
import org.apache.streampipes.storage.api.IUserGroupStorage;
-import org.apache.streampipes.storage.couchdb.dao.AbstractDao;
+import org.apache.streampipes.storage.couchdb.dao.CrudDao;
import org.apache.streampipes.storage.couchdb.utils.Utils;
import java.util.List;
-public class UserGroupStorageImpl extends AbstractDao<Group> implements IUserGroupStorage {
+public class UserGroupStorageImpl extends CrudDao implements IUserGroupStorage {
+
+ private static final String viewName = "users/groups";
public UserGroupStorageImpl() {
- super(Utils::getCouchDbUserGroupStorage, Group.class);
+ super(Utils::getCouchDbUserClient);
}
@Override
public List<Group> getAll() {
- return findAll();
+ return findAll(viewName, Group.class);
}
@Override
public void createElement(Group element) {
- persist(element);
+ persist(element, Group.class);
}
@Override
public Group getElementById(String s) {
- return findWithNullIfEmpty(s);
+ return findWithNullIfEmpty(s, Group.class);
}
@Override
public Group updateElement(Group element) {
- update(element);
+ update(element, Group.class);
return getElementById(element.getGroupId());
}
@Override
public void deleteElement(Group element) {
- delete(element.getGroupId());
+ delete(element.getGroupId(), Group.class);
}
}
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/UserStorage.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/UserStorage.java
index 5e1b157..a9e8c40 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/UserStorage.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/UserStorage.java
@@ -22,13 +22,11 @@ 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.IUserStorage;
-import org.apache.streampipes.storage.couchdb.dao.AbstractDao;
+import org.apache.streampipes.storage.couchdb.dao.CrudViewDao;
import org.apache.streampipes.storage.couchdb.utils.Utils;
-import org.lightcouch.CouchDbClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -36,22 +34,18 @@ import java.util.stream.Collectors;
* User Storage.
* Handles operations on user including user-specified pipelines.
*/
-public class UserStorage extends AbstractDao<Principal> implements IUserStorage {
+public class UserStorage extends CrudViewDao implements IUserStorage {
- Logger LOG = LoggerFactory.getLogger(UserStorage.class);
+ private static final Logger LOG = LoggerFactory.getLogger(UserStorage.class);
+ private static final String viewName = "users/username";
public UserStorage() {
- super(Utils::getCouchDbUserClient, Principal.class);
+ super(Utils::getCouchDbUserClient);
}
@Override
public List<Principal> getAllUsers() {
- List<Principal> users = couchDbClientSupplier
- .get()
- .view("users/username")
- .includeDocs(true)
- .query(Principal.class);
- return new ArrayList<>(users);
+ return findAll(viewName, Principal.class);
}
@Override
@@ -74,13 +68,7 @@ public class UserStorage extends AbstractDao<Principal> implements IUserStorage
@Override
public Principal getUser(String username) {
- // TODO improve
- CouchDbClient couchDbClient = couchDbClientSupplier.get();
- List<Principal> users = couchDbClient
- .view("users/username")
- .key(username)
- .includeDocs(true)
- .query(Principal.class);
+ List<Principal> users = findByKey(viewName, username, Principal.class);
if (users.size() != 1) {
LOG.error("None or to many users with matching username");
}
@@ -99,12 +87,12 @@ public class UserStorage extends AbstractDao<Principal> implements IUserStorage
@Override
public void storeUser(Principal user) {
- persist(user);
+ persist(user, Principal.class);
}
@Override
public void updateUser(Principal user) {
- update(user);
+ update(user, Principal.class);
}
@Override
@@ -122,24 +110,19 @@ public class UserStorage extends AbstractDao<Principal> implements IUserStorage
*/
@Override
public boolean checkUser(String username) {
- List<Principal> users = couchDbClientSupplier
- .get()
- .view("users/username")
- .key(username)
- .includeDocs(true)
- .query(Principal.class);
+ List<Principal> users = findByKey(viewName, username, Principal.class);
return users.size() == 1;
}
@Override
public void deleteUser(String principalId) {
- delete(principalId);
+ delete(principalId, Principal.class);
}
@Override
public Principal getUserById(String principalId) {
- return findWithNullIfEmpty(principalId);
+ return findWithNullIfEmpty(principalId, Principal.class);
}
}
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 6810f6a..fc4e20c 100644
--- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/PrincipalUserDetails.java
+++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/model/PrincipalUserDetails.java
@@ -19,7 +19,8 @@ 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.user.management.util.AuthorityBuilder;
+import org.apache.streampipes.user.management.util.GrantedAuthoritiesBuilder;
+import org.apache.streampipes.user.management.util.GrantedPermissionsBuilder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
@@ -31,10 +32,12 @@ public abstract class PrincipalUserDetails<T extends Principal> implements UserD
protected T details;
private Set<String> allAuthorities;
+ private Set<String> allObjectPermissions;
public PrincipalUserDetails(T details) {
this.details = details;
- this.allAuthorities = new AuthorityBuilder(details).buildAllAuthorities();
+ this.allAuthorities = new GrantedAuthoritiesBuilder(details).buildAllAuthorities();
+ this.allObjectPermissions = new GrantedPermissionsBuilder(details).buildAllPermissions();
}
public T getDetails() {
@@ -76,4 +79,8 @@ public abstract class PrincipalUserDetails<T extends Principal> implements UserD
return allAuthorities.stream().map(r -> (GrantedAuthority) () -> r).collect(Collectors.toList());
}
+ @JsonIgnore
+ public Set<String> getAllObjectPermissions() {
+ return allObjectPermissions;
+ }
}
diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/AuthorityBuilder.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedAuthoritiesBuilder.java
similarity index 95%
rename from streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/AuthorityBuilder.java
rename to streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedAuthoritiesBuilder.java
index 9d9e13c..0eb2d5c 100644
--- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/AuthorityBuilder.java
+++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedAuthoritiesBuilder.java
@@ -24,12 +24,12 @@ import org.apache.streampipes.storage.management.StorageDispatcher;
import java.util.HashSet;
import java.util.Set;
-public class AuthorityBuilder {
+public class GrantedAuthoritiesBuilder {
private Set<String> allAuthorities;
private Principal principal;
- public AuthorityBuilder(Principal principal) {
+ public GrantedAuthoritiesBuilder(Principal principal) {
this.allAuthorities = new HashSet<>();
this.principal = principal;
}
diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IUserStorage.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedPermissionsBuilder.java
similarity index 53%
copy from streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IUserStorage.java
copy to streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedPermissionsBuilder.java
index d7f996a..fa1d673 100644
--- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IUserStorage.java
+++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedPermissionsBuilder.java
@@ -15,36 +15,36 @@
* limitations under the License.
*
*/
-package org.apache.streampipes.storage.api;
+package org.apache.streampipes.user.management.util;
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.management.StorageDispatcher;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
-public interface IUserStorage {
- List<Principal> getAllUsers();
+public class GrantedPermissionsBuilder {
- List<UserAccount> getAllUserAccounts();
+ private Principal principal;
- List<ServiceAccount> getAllServiceAccounts();
+ public GrantedPermissionsBuilder(Principal principal) {
+ this.principal = principal;
+ }
- Principal getUser(String username);
+ public Set<String> buildAllPermissions() {
+ Set<String> sids = extractSids();
- UserAccount getUserAccount(String username);
+ return StorageDispatcher
+ .INSTANCE
+ .getNoSqlStore()
+ .getPermissionStorage()
+ .getObjectPermissions(new ArrayList<>(sids));
+ }
- ServiceAccount getServiceAccount(String username);
+ private Set<String> extractSids() {
+ Set<String> groupSids = principal.getGroups();
+ groupSids.add(principal.getPrincipalId());
- void storeUser(Principal user);
-
- void updateUser(Principal user);
-
- boolean emailExists(String email);
-
- boolean checkUser(String username);
-
- void deleteUser(String principalId);
-
- Principal getUserById(String principalId);
+ return groupSids;
+ }
}