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:32 UTC

[incubator-streampipes] branch STREAMPIPES-426 updated (c81b92d -> df6d25b)

This is an automated email from the ASF dual-hosted git repository.

riemer pushed a change to branch STREAMPIPES-426
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git.


    from c81b92d  [STREAMPIPES-426] Add initial parts of authorization system
     add 710e004  [hotfix] Fix stop adapters with multiple connect workers
     add 9cb08dc  [hotifx] Force delete adapter when endpoint is not available
     add 1077899  [hotfix] Fix layout in adapter start dialog
     add 46a220d  [hotfix] Fix data lake pipeline for generic adapters
     add bd30c24  Added e2e tests for MQTT and Influxdb
     add 0142944  [hotfix] Add e2e test for MySQL
     add 0813556  Provide "HTTP Server" adapter endpoints
     add a23865b  Merge pull request #50 from obermeier/patch-1
     add 0e89350  [STEAMPIPES-438] Remove adapter Id form backend
     add 676ff84  [STREAMPIPES-438] Start to move restart of adapters to AdapterHealthCheck
     add f326f39  Remove ConnectWorkerDescription from client
     add c87cec6  Working on simplifying adapters
     add 7c3d693  Remove protocol descriptions from connect interfaces
     add 6ac9bb7  Remove adapter template from ui
     add 9f283bb  Remova REST endpoint for adapter templates
     add a8717ec  Remove old wrapper classes representing lists
     add 5d85311  Remove DomainPropertyProbalilityList
     add 843719d  Remove old classes
     add edccbb3  Remove auto stop of pipelines from adapter
     add da36142  Replace ConnectWorkerContainer with lists of AdaperDescription
     add a721058  Working on recovery for adapters
     add 6207431  [STREAMPIPES-438] Harmonize Model Submitter
     add af1cab9  [STREAMPIPES-438] Minor code refactoring
     add 5897ade  [STREAMPIPES-438] Fix data set adapters
     add 3bdfe1d  [STREAMPIPES-438] Remove data stream source id from backend
     add 68d110d  [STREAMPIPES-438] Fix store in datalake
     add 3e4aec4  [STREAMPIPES-438] Harmonize Model Submitter
     add 7ac34e6  Merge branch 'STREAMPIPES-438' into dev
     add b1c1610  [hotfix] Add apache header to auto generated model file
     add 6127dc0  [hotfix] Fix cypress test
     add b554d3b  [hotfix] Add unique id for data stream
     add 795846c  [STREAMPIPES-387] Split StreamPipes Connect worker into two different services
     add a161768  [hotfix] Fix null pointer for data streams that are not generated by adapters
     add 11f0aab  [STREAMPIPES-444] Refactor asset dashboard to use updated pipeline data model
     add 9377083  [hotfix] Increase waiting time on pipeline invocation
     add 33fc197  Merge branch 'dev' of github.com:apache/incubator-streampipes into dev
     add 62e519a  [hotfix] Remove padding from pipeline editor panel
     add e1f215d  [STREAMPIPES-444] Allow modification of asset dashboards
     add dc2ede5  [STREAMPIPES-444] Links can be placed on asset dashboards
     add 0424e27  [STREAMPIPES-444] Improve link behaviour in asset dashboard
     add fd06d2f  [hotfix] Start set adapter in an own thread
     add 17e03d0  Merge branch 'dev' of github.com:apache/incubator-streampipes into dev
     add d3a8840  Merge branch 'dev' of github.com:apache/incubator-streampipes into dev
     new 209e3c4  Merge branch 'dev' into STREAMPIPES-426
     new df6d25b  [STREAMPIPES-426] Add initial draft of permission management

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .idea/runConfigurations/backend.xml                |   1 +
 .idea/runConfigurations/connect_adapters.xml       |   1 +
 .idea/runConfigurations/connect_adapters_iiot.xml  |  15 +
 .../backend/StreamPipesResourceConfig.java         |   1 -
 .../UUIDGenerator.java}                            |  10 +-
 .../master/health/AdapterHealthCheck.java          | 129 +++++++
 .../master/management/AdapterMasterManagement.java | 207 +++++++-----
 .../AdapterTemplateMasterManagement.java           | 106 ------
 .../master/management/DescriptionManagement.java   |  56 +---
 .../master/management/SourcesManagement.java       | 159 +++------
 .../master/management/UnitMasterManagement.java    |   7 +-
 .../management/WorkerAdministrationManagement.java |  73 ++--
 .../master/management/WorkerRestClient.java        |  78 +++--
 .../master/management/WorkerUrlProvider.java       |  61 +---
 .../master/util/AdapterEncryptionService.java      |   7 +-
 .../connect/container/master/util/Utils.java       |  29 --
 .../connect/container/master/util/WorkerPaths.java |  36 +-
 .../master/health/AdapterHealthCheckTest.java      |  87 +++++
 .../management/AdapterMasterManagementTest.java    |  16 +-
 .../AdapterTemplateMasterManagementTest.java       |  58 ----
 .../management/DescriptionManagementTest.java      |  10 +-
 .../master/management/SourcesManagementTest.java   |  78 +----
 .../master/management/WorkerRestClientTest.java    |  10 +-
 .../init/AdapterServiceResourceProvider.java       |   7 +-
 .../worker/init/AdapterWorkerContainer.java        |  64 ----
 .../init/ConnectWorkerDescriptionProvider.java     |  75 ++++-
 .../init/ConnectWorkerRegistrationService.java     |   7 +-
 .../worker/management/AdapterWorkerManagement.java |  78 +----
 .../worker/management/GuessManagement.java         |   8 -
 .../management/HttpServerAdapterManagement.java    |   3 +-
 .../worker/management/MasterRestClient.java        |   8 +-
 ...pterResource.java => AdapterAssetResource.java} |  28 +-
 ...kerResource.java => AdapterWorkerResource.java} |  30 +-
 .../container/worker/rest/GuessResource.java       |   5 +-
 .../container/worker/rest/ProtocolResource.java    |  75 -----
 .../container/worker/rest/WelcomePageWorker.java   | 108 ------
 .../container/worker/utils/AdapterUtils.java       |  28 +-
 .../management/AdapterWorkerManagementTest.java    |  26 +-
 .../container/worker/utils/AdapterUtilsTest.java   |  60 ----
 .../connect/container/worker/utils/Utils.java      |   6 +-
 .../connect/RunningAdapterInstances.java           |  21 +-
 .../adapter/guess/PropertyGuessResults.java        |  40 ---
 .../connect/adapter/guess/PropertyGuesses.java     |  54 ---
 .../connect/adapter/guess/SchemaGuesser.java       | 101 +-----
 .../model/generic/GenericDataSetAdapter.java       |   4 +-
 .../model/generic/GenericDataStreamAdapter.java    |   4 +-
 .../streampipes/connect/adapter/guess/Mock.java    |  26 --
 .../connect/adapter/guess/SchemaGuesserTest.java   | 132 --------
 .../extensions/ExtensionsModelSubmitter.java       |   2 +-
 .../standalone/init/StandaloneModelSubmitter.java  |   1 +
 .../container/util/ServiceDefinitionUtil.java      |   2 +-
 .../assetdashboard/AssetDashboardConfig.java       |   7 +-
 .../client/assetdashboard/CanvasAttributes.java    |  28 ++
 .../model/client/assetdashboard/CanvasElement.java |   7 +-
 .../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 +-
 .../org/apache/streampipes/model/SpDataSet.java    |   1 +
 .../org/apache/streampipes/model/SpDataStream.java |   1 +
 .../model/connect/adapter/AdapterDescription.java  |  38 +--
 .../connect/adapter/AdapterDescriptionList.java    |  49 ---
 .../connect/adapter/AdapterSetDescription.java     |  11 +-
 .../connect/adapter/AdapterStreamDescription.java  |   7 +-
 .../adapter/GenericAdapterSetDescription.java      |   1 -
 .../adapter/GenericAdapterStreamDescription.java   |   1 -
 .../model/connect/grounding/FormatDescription.java |  46 ---
 .../connect/grounding/FormatDescriptionList.java   |  63 ----
 .../connect/grounding/ProtocolDescription.java     |   2 -
 .../connect/grounding/ProtocolDescriptionList.java |  58 ----
 .../connect/guess/DomainPropertyProbability.java   |  53 ---
 .../guess/DomainPropertyProbabilityList.java       |  56 ----
 .../model/connect/guess/GuessSchema.java           |  30 +-
 .../connect/worker/ConnectWorkerContainer.java     |  95 ------
 streampipes-pipeline-management/pom.xml            |   2 +-
 .../manager/execution/http/GraphSubmitter.java     |   2 +-
 .../manager/execution/http/PipelineExecutor.java   |   6 +-
 .../manager/permission/PermissionManager.java      |  15 +-
 .../manager/pipeline/PipelineManager.java          |  20 +-
 .../manager/setup/CouchDbInstallationStep.java     |  26 +-
 .../base/impl/AbstractAuthGuardedRestResource.java |  11 +
 .../apache/streampipes/rest/ResetManagement.java   |   6 +-
 .../streampipes/rest/impl/AssetDashboard.java      |  17 +
 .../streampipes/rest/impl/PipelineResource.java    |   8 +-
 .../streampipes/rest/impl/PipelineTemplate.java    |   2 +-
 .../org/apache/streampipes/rest/impl/Version.java  |   4 +-
 .../rest/impl/connect/AdapterResource.java         |  31 +-
 .../rest/impl/connect/AdapterTemplateResource.java |  88 -----
 .../rest/impl/connect/DescriptionResource.java     |  50 +--
 .../rest/impl/connect/GuessResource.java           |   3 +-
 .../impl/connect/RuntimeResolvableResource.java    |   4 +-
 .../rest/impl/connect/SourcesResource.java         |  54 +--
 .../rest/impl/connect/WelcomePageMaster.java       |   4 +-
 .../impl/connect/WorkerAdministrationResource.java |  11 +-
 .../rest/impl/security/AuthConstants.java          |   1 +
 .../rest/impl/security/SpPermissionEvaluator.java  |  13 +-
 .../builder/adapter/AdapterDescriptionBuilder.java |   9 +-
 .../sdk/builder/adapter/GuessSchemaBuilder.java    |  10 -
 .../serializers/json/AdapterSerializer.java        |   4 +-
 .../svcdiscovery/api/model/SpServiceTagPrefix.java |   1 -
 .../api/model/SpServiceUrlProvider.java            |   3 +-
 .../storage/api/IAssetDashboardStorage.java        |   2 +
 .../api/IConnectWorkerContainerStorage.java        |  35 --
 .../streampipes/storage/api/INoSqlStorage.java     |   6 +-
 ...emplateStorage.java => IPermissionStorage.java} |  21 +-
 .../streampipes/storage/api/IUserStorage.java      |   6 +-
 .../storage/couchdb/CouchDbStorageManager.java     |  14 +-
 .../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 +-
 ...mpl.java => AdapterDescriptionStorageImpl.java} |  14 +-
 ...geImpl.java => AdapterInstanceStorageImpl.java} |  10 +-
 .../couchdb/impl/AdapterTemplateStorageImpl.java   |  70 ----
 .../couchdb/impl/AssetDashboardStorageImpl.java    |   5 +
 .../impl/ConnectionWorkerContainerStorageImpl.java |  71 ----
 .../couchdb/impl/PermissionStorageImpl.java        |  76 +++++
 .../storage/couchdb/impl/UserGroupStorageImpl.java |  18 +-
 .../storage/couchdb/impl/UserStorage.java          |  41 +--
 .../streampipes/storage/couchdb/utils/Utils.java   |   8 +-
 .../management/model/PrincipalUserDetails.java     |  11 +-
 ...Builder.java => GrantedAuthoritiesBuilder.java} |   4 +-
 .../management/util/GrantedPermissionsBuilder.java |  44 +--
 .../support/builder/GenericAdapterBuilder.ts       |  87 ++---
 ui/cypress/support/builder/PipelineBuilder.ts      |   1 +
 ui/cypress/support/utils/AdapterUtils.ts           |   4 +
 ui/cypress/support/utils/StaticPropertyUtils.ts    |  30 +-
 ui/cypress/tests/adapter/InfluxDbAdapter.ts        |  74 ++++
 ui/cypress/tests/adapter/KafkaAdapter.ts           |  72 ++++
 .../pipelineTest.ts => adapter/MqttAdapter.ts}     |  51 ++-
 .../pipelineTest.ts => adapter/MySQLDbAdapter.ts}  |  47 ++-
 ui/cypress/tests/adapter/machineDataSimulator.ts   |   1 +
 ui/cypress/tests/adapter/persistInDataLake.ts      |  18 +-
 .../tests/pipelineElement/AllPipelineElements.ts   |  32 +-
 ui/nginx_config/default.conf                       |  11 +
 ui/package.json                                    |   2 +-
 .../app-asset-monitoring.component.html            |   6 +-
 .../app-asset-monitoring.component.ts              |  11 +-
 .../app-asset-monitoring.module.ts                 |   4 +-
 .../create-asset/create-asset.component.css        |   5 +-
 .../create-asset/create-asset.component.html       |  46 ++-
 .../create-asset/create-asset.component.ts         | 252 +++++++++-----
 .../dashboard-overview.component.html              |   8 +-
 .../dashboard-overview.component.ts                |  15 +-
 .../components/view-asset/view-asset.component.css |   7 +-
 .../view-asset/view-asset.component.html           |   5 +-
 .../components/view-asset/view-asset.component.ts  |  50 ++-
 .../dialog/add-link/add-link-dialog.component.html |  54 +++
 .../add-link/add-link-dialog.component.scss}       |   5 +-
 .../dialog/add-link/add-link-dialog.component.ts   |  58 ++++
 .../add-pipeline/add-pipeline-dialog.component.css |  55 ---
 .../add-pipeline-dialog.component.html             |  91 +++--
 .../add-pipeline-dialog.component.scss}            |   4 +
 .../add-pipeline/add-pipeline-dialog.component.ts  |  90 +++--
 .../save-dashboard-dialog.component.css            |  55 ---
 .../save-dashboard-dialog.component.html           |  59 ++--
 .../save-dashboard-dialog.component.scss}          |   8 +-
 .../save-dashboard-dialog.component.ts             |  73 ++--
 .../model/dashboard-configuration.model.ts         |   9 +-
 .../app-asset-monitoring/model/image-info.model.ts |   4 +-
 .../model/selected-visualization-data.model.ts     |   9 +-
 .../app-asset-monitoring/services/rest.service.ts  |   4 +
 .../app-asset-monitoring/services/shape.service.ts |  91 +++--
 .../app/app-overview/app-overview.component.html   |   4 +-
 .../adapter-description.component.html             |  16 +-
 .../adapter-description.component.ts               |  78 ++---
 .../data-marketplace.component.html                |  10 +-
 .../data-marketplace/data-marketplace.component.ts | 373 +++++++++------------
 .../format-configuration.component.ts              |   5 +-
 .../start-adapter-configuration.component.html     |   9 +-
 .../start-adapter-configuration.component.ts       |  15 +-
 .../adapter-started-dialog.component.html          |  14 +-
 .../adapter-started-dialog.component.ts            | 106 +++---
 .../adapter-upload-dialog.component.ts             |  60 ++--
 .../connect/services/data-marketplace.service.ts   | 135 ++------
 ui/src/app/connect/services/rest.service.ts        |  79 ++---
 ui/src/app/core-model/gen/streampipes-model.ts     |  57 +---
 .../static-alternatives.component.html             |  12 +-
 ...c-runtime-resolvable-oneof-input.component.html |   8 +-
 .../static-secret-input.component.html             |  27 +-
 ui/src/app/dashboard/dashboard.component.html      |   2 +-
 .../app/data-explorer/data-explorer.component.html |   2 +-
 ui/src/app/editor/editor.component.html            |   2 +-
 .../pipeline-status-dialog.component.html          |  44 +--
 ui/src/scss/sp/main.scss                           |   4 +
 187 files changed, 2676 insertions(+), 3864 deletions(-)
 create mode 100644 .idea/runConfigurations/connect_adapters_iiot.xml
 copy streampipes-commons/src/main/java/org/apache/streampipes/commons/{parser/PrimitiveTypeParser.java => random/UUIDGenerator.java} (80%)
 create mode 100644 streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/health/AdapterHealthCheck.java
 delete mode 100644 streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/management/AdapterTemplateMasterManagement.java
 delete mode 100644 streampipes-connect-container-master/src/main/java/org/apache/streampipes/connect/container/master/util/Utils.java
 create mode 100644 streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/health/AdapterHealthCheckTest.java
 delete mode 100644 streampipes-connect-container-master/src/test/java/org/apache/streampipes/connect/container/master/management/AdapterTemplateMasterManagementTest.java
 delete mode 100644 streampipes-connect-container-worker/src/main/java/org/apache/streampipes/connect/container/worker/init/AdapterWorkerContainer.java
 rename streampipes-connect-container-worker/src/main/java/org/apache/streampipes/connect/container/worker/rest/{AdapterResource.java => AdapterAssetResource.java} (71%)
 rename streampipes-connect-container-worker/src/main/java/org/apache/streampipes/connect/container/worker/rest/{WorkerResource.java => AdapterWorkerResource.java} (87%)
 delete mode 100644 streampipes-connect-container-worker/src/main/java/org/apache/streampipes/connect/container/worker/rest/ProtocolResource.java
 delete mode 100644 streampipes-connect-container-worker/src/main/java/org/apache/streampipes/connect/container/worker/rest/WelcomePageWorker.java
 delete mode 100644 streampipes-connect-container-worker/src/test/java/org/apache/streampipes/connect/container/worker/utils/AdapterUtilsTest.java
 delete mode 100644 streampipes-connect/src/main/java/org/apache/streampipes/connect/adapter/guess/PropertyGuessResults.java
 delete mode 100644 streampipes-connect/src/main/java/org/apache/streampipes/connect/adapter/guess/PropertyGuesses.java
 delete mode 100644 streampipes-connect/src/test/java/org/apache/streampipes/connect/adapter/guess/Mock.java
 delete mode 100644 streampipes-connect/src/test/java/org/apache/streampipes/connect/adapter/guess/SchemaGuesserTest.java
 create mode 100644 streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/Permission.java
 create mode 100644 streampipes-model-client/src/main/java/org/apache/streampipes/model/client/user/PermissionBuilder.java
 delete mode 100644 streampipes-model/src/main/java/org/apache/streampipes/model/connect/adapter/AdapterDescriptionList.java
 delete mode 100644 streampipes-model/src/main/java/org/apache/streampipes/model/connect/grounding/FormatDescriptionList.java
 delete mode 100644 streampipes-model/src/main/java/org/apache/streampipes/model/connect/grounding/ProtocolDescriptionList.java
 delete mode 100644 streampipes-model/src/main/java/org/apache/streampipes/model/connect/guess/DomainPropertyProbability.java
 delete mode 100644 streampipes-model/src/main/java/org/apache/streampipes/model/connect/guess/DomainPropertyProbabilityList.java
 delete mode 100644 streampipes-model/src/main/java/org/apache/streampipes/model/connect/worker/ConnectWorkerContainer.java
 copy streampipes-wrapper-siddhi/src/main/java/org/apache/streampipes/wrapper/siddhi/query/expression/math/MathSubtractExpression.java => streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/permission/PermissionManager.java (66%)
 delete mode 100644 streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterTemplateResource.java
 delete mode 100644 streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IConnectWorkerContainerStorage.java
 rename streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/{IAdapterTemplateStorage.java => IPermissionStorage.java} (68%)
 copy streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/{AbstractDao.java => CrudDao.java} (79%)
 copy streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/dao/{FindAllCommand.java => CrudViewDao.java} (71%)
 copy streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/{AdapterStorageImpl.java => AdapterDescriptionStorageImpl.java} (86%)
 rename streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/{AdapterStorageImpl.java => AdapterInstanceStorageImpl.java} (86%)
 delete mode 100644 streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/AdapterTemplateStorageImpl.java
 delete mode 100644 streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/ConnectionWorkerContainerStorageImpl.java
 create mode 100644 streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/PermissionStorageImpl.java
 rename streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/{AuthorityBuilder.java => GrantedAuthoritiesBuilder.java} (95%)
 copy streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IUserStorage.java => streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/GrantedPermissionsBuilder.java (53%)
 create mode 100644 ui/cypress/tests/adapter/InfluxDbAdapter.ts
 create mode 100644 ui/cypress/tests/adapter/KafkaAdapter.ts
 copy ui/cypress/tests/{pipeline/pipelineTest.ts => adapter/MqttAdapter.ts} (53%)
 copy ui/cypress/tests/{pipeline/pipelineTest.ts => adapter/MySQLDbAdapter.ts} (55%)
 create mode 100644 ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.html
 copy ui/src/app/{editor/dialog/pipeline-element-discovery/pipeline-element-discovery.component.scss => app-asset-monitoring/dialog/add-link/add-link-dialog.component.scss} (94%)
 create mode 100644 ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.ts
 delete mode 100644 ui/src/app/app-asset-monitoring/dialog/add-pipeline/add-pipeline-dialog.component.css
 copy ui/src/app/{dashboard/dialogs/add-widget/add-visualization-dialog.component.scss => app-asset-monitoring/dialog/add-pipeline/add-pipeline-dialog.component.scss} (96%)
 delete mode 100644 ui/src/app/app-asset-monitoring/dialog/save-dashboard/save-dashboard-dialog.component.css
 copy ui/src/app/{data-explorer/dialogs/edit-dashboard/data-explorer-edit-data-view-dialog.component.scss => app-asset-monitoring/dialog/save-dashboard/save-dashboard-dialog.component.scss} (95%)

[incubator-streampipes] 01/02: Merge branch 'dev' into STREAMPIPES-426

Posted by ri...@apache.org.
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 209e3c4490837770de9a3ed12158fc59a9281aa0
Merge: c81b92d d3a8840
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Wed Oct 13 10:17:34 2021 +0200

    Merge branch 'dev' into STREAMPIPES-426

 .idea/runConfigurations/backend.xml                |   1 +
 .idea/runConfigurations/connect_adapters.xml       |   1 +
 .idea/runConfigurations/connect_adapters_iiot.xml  |  15 +
 .../backend/StreamPipesResourceConfig.java         |   1 -
 .../master/health/AdapterHealthCheck.java          | 129 +++++++
 .../master/management/AdapterMasterManagement.java | 207 +++++++-----
 .../AdapterTemplateMasterManagement.java           | 106 ------
 .../master/management/DescriptionManagement.java   |  56 +---
 .../master/management/SourcesManagement.java       | 159 +++------
 .../master/management/UnitMasterManagement.java    |   7 +-
 .../management/WorkerAdministrationManagement.java |  73 ++--
 .../master/management/WorkerRestClient.java        |  78 +++--
 .../master/management/WorkerUrlProvider.java       |  61 +---
 .../master/util/AdapterEncryptionService.java      |   7 +-
 .../connect/container/master/util/WorkerPaths.java |  36 +-
 .../master/health/AdapterHealthCheckTest.java      |  87 +++++
 .../management/AdapterMasterManagementTest.java    |  16 +-
 .../AdapterTemplateMasterManagementTest.java       |  58 ----
 .../management/DescriptionManagementTest.java      |  10 +-
 .../master/management/SourcesManagementTest.java   |  78 +----
 .../master/management/WorkerRestClientTest.java    |  10 +-
 .../init/AdapterServiceResourceProvider.java       |   7 +-
 .../worker/init/AdapterWorkerContainer.java        |  64 ----
 .../init/ConnectWorkerDescriptionProvider.java     |  75 ++++-
 .../init/ConnectWorkerRegistrationService.java     |   7 +-
 .../worker/management/AdapterWorkerManagement.java |  78 +----
 .../worker/management/GuessManagement.java         |   8 -
 .../management/HttpServerAdapterManagement.java    |   3 +-
 .../worker/management/MasterRestClient.java        |   8 +-
 ...pterResource.java => AdapterAssetResource.java} |  28 +-
 ...kerResource.java => AdapterWorkerResource.java} |  30 +-
 .../container/worker/rest/GuessResource.java       |   5 +-
 .../container/worker/rest/ProtocolResource.java    |  75 -----
 .../container/worker/rest/WelcomePageWorker.java   | 108 ------
 .../container/worker/utils/AdapterUtils.java       |  28 +-
 .../management/AdapterWorkerManagementTest.java    |  26 +-
 .../container/worker/utils/AdapterUtilsTest.java   |  60 ----
 .../connect/container/worker/utils/Utils.java      |   6 +-
 .../connect/RunningAdapterInstances.java           |  21 +-
 .../adapter/guess/PropertyGuessResults.java        |  40 ---
 .../connect/adapter/guess/PropertyGuesses.java     |  54 ---
 .../connect/adapter/guess/SchemaGuesser.java       | 101 +-----
 .../model/generic/GenericDataSetAdapter.java       |   4 +-
 .../model/generic/GenericDataStreamAdapter.java    |   4 +-
 .../connect/adapter/guess/SchemaGuesserTest.java   | 132 --------
 .../extensions/ExtensionsModelSubmitter.java       |   2 +-
 .../standalone/init/StandaloneModelSubmitter.java  |   1 +
 .../container/util/ServiceDefinitionUtil.java      |   2 +-
 .../assetdashboard/AssetDashboardConfig.java       |   7 +-
 .../client/assetdashboard/CanvasAttributes.java    |  28 ++
 .../model/client/assetdashboard/CanvasElement.java |   7 +-
 .../org/apache/streampipes/model/SpDataSet.java    |   1 +
 .../org/apache/streampipes/model/SpDataStream.java |   1 +
 .../model/connect/adapter/AdapterDescription.java  |  38 +--
 .../connect/adapter/AdapterDescriptionList.java    |  49 ---
 .../connect/adapter/AdapterSetDescription.java     |  11 +-
 .../connect/adapter/AdapterStreamDescription.java  |   7 +-
 .../adapter/GenericAdapterSetDescription.java      |   1 -
 .../adapter/GenericAdapterStreamDescription.java   |   1 -
 .../model/connect/grounding/FormatDescription.java |  46 ---
 .../connect/grounding/FormatDescriptionList.java   |  63 ----
 .../connect/grounding/ProtocolDescription.java     |   2 -
 .../connect/grounding/ProtocolDescriptionList.java |  58 ----
 .../connect/guess/DomainPropertyProbability.java   |  53 ---
 .../guess/DomainPropertyProbabilityList.java       |  56 ----
 .../model/connect/guess/GuessSchema.java           |  30 +-
 .../connect/worker/ConnectWorkerContainer.java     |  95 ------
 streampipes-pipeline-management/pom.xml            |   2 +-
 .../manager/execution/http/GraphSubmitter.java     |   2 +-
 .../manager/execution/http/PipelineExecutor.java   |   6 +-
 .../manager/setup/CouchDbInstallationStep.java     |   8 +-
 .../apache/streampipes/rest/ResetManagement.java   |   6 +-
 .../streampipes/rest/impl/AssetDashboard.java      |  17 +
 .../streampipes/rest/impl/PipelineTemplate.java    |   2 +-
 .../rest/impl/connect/AdapterResource.java         |  31 +-
 .../rest/impl/connect/AdapterTemplateResource.java |  88 -----
 .../rest/impl/connect/DescriptionResource.java     |  50 +--
 .../rest/impl/connect/GuessResource.java           |   3 +-
 .../impl/connect/RuntimeResolvableResource.java    |   4 +-
 .../rest/impl/connect/SourcesResource.java         |  54 +--
 .../rest/impl/connect/WelcomePageMaster.java       |   4 +-
 .../impl/connect/WorkerAdministrationResource.java |  11 +-
 .../builder/adapter/AdapterDescriptionBuilder.java |   9 +-
 .../sdk/builder/adapter/GuessSchemaBuilder.java    |  10 -
 .../serializers/json/AdapterSerializer.java        |   4 +-
 .../svcdiscovery/api/model/SpServiceTagPrefix.java |   1 -
 .../api/model/SpServiceUrlProvider.java            |   3 +-
 .../storage/api/IAdapterTemplateStorage.java       |  36 --
 .../storage/api/IAssetDashboardStorage.java        |   2 +
 .../api/IConnectWorkerContainerStorage.java        |  35 --
 .../streampipes/storage/api/INoSqlStorage.java     |   4 +-
 .../storage/couchdb/CouchDbStorageManager.java     |   9 +-
 ...mpl.java => AdapterDescriptionStorageImpl.java} |  14 +-
 ...geImpl.java => AdapterInstanceStorageImpl.java} |  10 +-
 .../couchdb/impl/AdapterTemplateStorageImpl.java   |  70 ----
 .../couchdb/impl/AssetDashboardStorageImpl.java    |   5 +
 .../impl/ConnectionWorkerContainerStorageImpl.java |  71 ----
 .../streampipes/storage/couchdb/utils/Utils.java   |   8 +-
 .../support/builder/GenericAdapterBuilder.ts       |  87 ++---
 ui/cypress/support/builder/PipelineBuilder.ts      |   1 +
 ui/cypress/support/utils/AdapterUtils.ts           |   4 +
 ui/cypress/support/utils/StaticPropertyUtils.ts    |  30 +-
 ui/cypress/tests/adapter/InfluxDbAdapter.ts        |  74 ++++
 ui/cypress/tests/adapter/KafkaAdapter.ts           |  72 ++++
 .../{persistInDataLake.ts => MqttAdapter.ts}       |  39 ++-
 .../{persistInDataLake.ts => MySQLDbAdapter.ts}    |  37 +-
 ui/cypress/tests/adapter/machineDataSimulator.ts   |   1 +
 ui/cypress/tests/adapter/persistInDataLake.ts      |  18 +-
 .../tests/pipelineElement/AllPipelineElements.ts   |  32 +-
 ui/nginx_config/default.conf                       |  11 +
 ui/package.json                                    |   2 +-
 .../app-asset-monitoring.component.html            |   6 +-
 .../app-asset-monitoring.component.ts              |  11 +-
 .../app-asset-monitoring.module.ts                 |   4 +-
 .../create-asset/create-asset.component.css        |   5 +-
 .../create-asset/create-asset.component.html       |  46 ++-
 .../create-asset/create-asset.component.ts         | 252 +++++++++-----
 .../dashboard-overview.component.html              |   8 +-
 .../dashboard-overview.component.ts                |  15 +-
 .../components/view-asset/view-asset.component.css |   7 +-
 .../view-asset/view-asset.component.html           |   5 +-
 .../components/view-asset/view-asset.component.ts  |  50 ++-
 .../dialog/add-link/add-link-dialog.component.html |  54 +++
 .../dialog/add-link/add-link-dialog.component.scss |   9 +-
 .../dialog/add-link/add-link-dialog.component.ts   |  58 ++++
 .../add-pipeline-dialog.component.html             |  91 +++--
 ...nent.css => add-pipeline-dialog.component.scss} |  45 ++-
 .../add-pipeline/add-pipeline-dialog.component.ts  |  90 +++--
 .../save-dashboard-dialog.component.css            |  55 ---
 .../save-dashboard-dialog.component.html           |  59 ++--
 .../save-dashboard-dialog.component.scss           |  17 +-
 .../save-dashboard-dialog.component.ts             |  73 ++--
 .../model/dashboard-configuration.model.ts         |   9 +-
 .../app-asset-monitoring/model/image-info.model.ts |   4 +-
 .../model/selected-visualization-data.model.ts     |   9 +-
 .../app-asset-monitoring/services/rest.service.ts  |   4 +
 .../app-asset-monitoring/services/shape.service.ts |  91 +++--
 .../app/app-overview/app-overview.component.html   |   4 +-
 .../adapter-description.component.html             |  16 +-
 .../adapter-description.component.ts               |  78 ++---
 .../data-marketplace.component.html                |  10 +-
 .../data-marketplace/data-marketplace.component.ts | 373 +++++++++------------
 .../format-configuration.component.ts              |   5 +-
 .../start-adapter-configuration.component.html     |   9 +-
 .../start-adapter-configuration.component.ts       |  15 +-
 .../adapter-started-dialog.component.html          |  14 +-
 .../adapter-started-dialog.component.ts            | 106 +++---
 .../adapter-upload-dialog.component.ts             |  60 ++--
 .../connect/services/data-marketplace.service.ts   | 135 ++------
 ui/src/app/connect/services/rest.service.ts        |  79 ++---
 ui/src/app/core-model/gen/streampipes-model.ts     |  57 +---
 .../static-alternatives.component.html             |  12 +-
 ...c-runtime-resolvable-oneof-input.component.html |   8 +-
 .../static-secret-input.component.html             |  27 +-
 ui/src/app/dashboard/dashboard.component.html      |   2 +-
 .../app/data-explorer/data-explorer.component.html |   2 +-
 ui/src/app/editor/editor.component.html            |   2 +-
 .../pipeline-status-dialog.component.html          |  44 +--
 ui/src/scss/sp/main.scss                           |   4 +
 159 files changed, 2236 insertions(+), 3617 deletions(-)

diff --cc streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java
index 3b6b803,444d54f..7143075
--- 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
@@@ -25,203 -27,192 +25,199 @@@ import org.lightcouch.DesignDocument
  import org.lightcouch.DesignDocument.MapReduce;
  import org.lightcouch.Response;
  
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
+ import java.util.*;
  
 -public class CouchDbInstallationStep implements InstallationStep {
 -
 -    private static List<String> initRdfEndpointPorts = new ArrayList<>();
 -    private static final String initRdfEndpointHost = "http://localhost:";
 -
 -    private static final String PREPARING_NOTIFICATIONS_TEXT = "Preparing database " +
 -            "'notifications'...";
 -    private static final String PREPARING_USERS_TEXT = "Preparing database 'users'...";
 -
 -    public CouchDbInstallationStep() {
 -
 -    }
 -
 -    @Override
 -    public List<Message> install() {
 -        List<Message> msgs = new ArrayList<>();
 -        msgs.addAll(createDatabases());
 -        msgs.addAll(createViews());
 -        msgs.add(addRdfEndpoints());
 -        return msgs;
 -    }
 -
 -    @Override
 -    public String getTitle() {
 -        return "Creating databases...";
 -    }
 -
 -    private List<Message> createDatabases() {
 -        try {
 -            // Set up couchdb internal databases
 -            Utils.getCouchDbInternalUsersClient();
 -            Utils.getCouchDbReplicatorClient();
 -            Utils.getCouchDbGlobalChangesClient();
 -
 -            // Set up streampipes internal databases
 -            Utils.getCouchDbUserClient();
 -            Utils.getCouchDbMonitoringClient();
 -            Utils.getCouchDbPipelineClient();
 -            Utils.getCouchDbConnectionClient();
 -            Utils.getCouchDbNotificationClient();
 -            Utils.getCouchDbPipelineCategoriesClient();
 -            Utils.getCouchDbVisualizationClient();
 -            Utils.getCouchDbRdfEndpointClient();
 -            Utils.getCouchDbDashboardClient();
 -            Utils.getCouchDbDashboardWidgetClient();
 -            Utils.getCouchDbLabelClient();
 -            Utils.getCouchDbCategoryClient();
 -
 -            return Collections.singletonList(Notifications.success(getTitle()));
 -        } catch (Exception e) {
 -            return Collections.singletonList(Notifications.error(getTitle()));
 -        }
 +public class CouchDbInstallationStep extends InstallationStep {
 +
 +  private static final String initRdfEndpointHost = "http://localhost:";
 +  private static final String PREPARING_NOTIFICATIONS_TEXT = "Preparing database " +
 +          "'notifications'...";
 +  private static final String PREPARING_USERS_TEXT = "Preparing database 'users'...";
-   private static List<String> initRdfEndpointPorts =
-           Collections.singletonList("8099/api/v1/master/sources/");
++  private static List<String> initRdfEndpointPorts = new ArrayList<>();
 +
 +  public CouchDbInstallationStep() {
 +
 +  }
 +
 +  @Override
 +  public void install() {
 +    createDatabases();
 +    createViews();
 +    addRdfEndpoints();
 +  }
 +
 +  @Override
 +  public String getTitle() {
 +    return "Creating databases...";
 +  }
 +
 +  private void createDatabases() {
 +    try {
 +      // Set up couchdb internal databases
 +      Utils.getCouchDbInternalUsersClient();
 +      Utils.getCouchDbReplicatorClient();
 +      Utils.getCouchDbGlobalChangesClient();
 +
 +      // Set up streampipes internal databases
 +      Utils.getCouchDbUserClient();
 +      Utils.getCouchDbMonitoringClient();
 +      Utils.getCouchDbPipelineClient();
 +      Utils.getCouchDbConnectionClient();
 +      Utils.getCouchDbNotificationClient();
 +      Utils.getCouchDbPipelineCategoriesClient();
 +      Utils.getCouchDbVisualizationClient();
 +      Utils.getCouchDbRdfEndpointClient();
 +      Utils.getCouchDbDashboardClient();
 +      Utils.getCouchDbDashboardWidgetClient();
 +      Utils.getCouchDbLabelClient();
 +      Utils.getCouchDbCategoryClient();
 +
 +      logSuccess(getTitle());
 +    } catch (Exception e) {
 +      logFailure(getTitle(), e);
      }
 -
 -    private List<Message> createViews() {
 -        List<Message> result = new ArrayList<>();
 -        result.add(addUserView());
 -        result.add(addConnectionView());
 -        result.add(addNotificationView());
 -        result.add(addLabelView());
 -        return result;
 +  }
 +
 +  private void createViews() {
 +    addUserView();
 +    addConnectionView();
 +    addNotificationView();
 +    addLabelView();
 +  }
 +
 +  private void addRdfEndpoints() {
 +    ExtensionsServiceEndpointStorageImpl rdfEndpointStorage = new ExtensionsServiceEndpointStorageImpl();
 +    initRdfEndpointPorts
 +            .forEach(p -> rdfEndpointStorage
 +                    .addExtensionsServiceEndpoint(new ExtensionsServiceEndpoint(initRdfEndpointHost + p)));
 +
 +    logSuccess("Discovering pipeline element endpoints...");
 +  }
 +
 +  private void addNotificationView() {
 +    try {
 +      DesignDocument userDocument = prepareDocument("_design/notificationtypes");
 +      DesignDocument notificationCountDocument = prepareDocument("_design/unread");
 +
 +      Map<String, MapReduce> notificationTypeViews = new HashMap<>();
 +      MapReduce notificationTypeFunction = new MapReduce();
 +      notificationTypeFunction.setMap("function (doc) { var vizName = doc.title.replace(/\\s/g, '-'); var indexName = doc.correspondingPipelineId + '-' + vizName; emit([indexName, doc.createdAtTimestamp], doc);}");
 +      notificationTypeViews.put("notificationtypes", notificationTypeFunction);
 +      userDocument.setViews(notificationTypeViews);
 +      Response resp = Utils.getCouchDbNotificationClient().design().synchronizeWithDb(userDocument);
 +
 +      Map<String, MapReduce> notificationCountTypeViews = new HashMap<>();
 +      MapReduce countFunction = new MapReduce();
 +      countFunction.setMap("function (doc) {\n" +
 +              "  var user = doc.targetedAt; \n" +
 +              "  if (!doc.read) {\n" +
 +              "    emit(user, 1);\n" +
 +              "  }\n" +
 +              "}");
 +      countFunction.setReduce("function (keys, values, rereduce) {\n" +
 +              "  if (rereduce) {\n" +
 +              "    return sum(values);\n" +
 +              "  } else {\n" +
 +              "    return values.length;\n" +
 +              "  }\n" +
 +              "}");
 +      notificationCountTypeViews.put("unread", countFunction);
 +      notificationCountDocument.setViews(notificationCountTypeViews);
 +      Response countResp =
 +              Utils.getCouchDbNotificationClient().design().synchronizeWithDb(notificationCountDocument);
 +
 +      if (resp.getError() != null && countResp != null) {
 +        logFailure(PREPARING_NOTIFICATIONS_TEXT);
 +      } else {
 +        logSuccess(PREPARING_NOTIFICATIONS_TEXT);
 +      }
 +    } catch (Exception e) {
 +      logFailure(PREPARING_NOTIFICATIONS_TEXT, e);
      }
 +  }
  
 -    private Message addRdfEndpoints() {
 -        ExtensionsServiceEndpointStorageImpl rdfEndpointStorage = new ExtensionsServiceEndpointStorageImpl();
 -        initRdfEndpointPorts
 -                .forEach(p -> rdfEndpointStorage
 -                        .addExtensionsServiceEndpoint(new ExtensionsServiceEndpoint(initRdfEndpointHost + p)));
 +  private void addUserView() {
 +    try {
 +      DesignDocument userDocument = prepareDocument("_design/users");
 +      Map<String, MapReduce> views = new HashMap<>();
  
 -        return Notifications.success("Discovering pipeline element endpoints...");
 -    }
 -
 -    private Message addNotificationView() {
 -        try {
 -            DesignDocument userDocument = prepareDocument("_design/notificationtypes");
 -            DesignDocument notificationCountDocument = prepareDocument("_design/unread");
 -
 -            Map<String, MapReduce> notificationTypeViews = new HashMap<>();
 -            MapReduce notificationTypeFunction = new MapReduce();
 -            notificationTypeFunction.setMap("function (doc) { var vizName = doc.title.replace(/\\s/g, '-'); var indexName = doc.correspondingPipelineId + '-' + vizName; emit([indexName, doc.createdAtTimestamp], doc);}");
 -            notificationTypeViews.put("notificationtypes", notificationTypeFunction);
 -            userDocument.setViews(notificationTypeViews);
 -            Response resp = Utils.getCouchDbNotificationClient().design().synchronizeWithDb(userDocument);
 -
 -            Map<String, MapReduce> notificationCountTypeViews = new HashMap<>();
 -            MapReduce countFunction = new MapReduce();
 -            countFunction.setMap("function (doc) {\n" +
 -                    "  var user = doc.targetedAt; \n" +
 -                    "  if (!doc.read) {\n" +
 -                    "    emit(user, 1);\n" +
 -                    "  }\n" +
 -                    "}");
 -            countFunction.setReduce("function (keys, values, rereduce) {\n" +
 -                    "  if (rereduce) {\n" +
 -                    "    return sum(values);\n" +
 -                    "  } else {\n" +
 -                    "    return values.length;\n" +
 -                    "  }\n" +
 -                    "}");
 -            notificationCountTypeViews.put("unread", countFunction);
 -            notificationCountDocument.setViews(notificationCountTypeViews);
 -            Response countResp =
 -                    Utils.getCouchDbNotificationClient().design().synchronizeWithDb(notificationCountDocument);
 -
 -            if (resp.getError() != null && countResp != null) return Notifications.error(PREPARING_NOTIFICATIONS_TEXT);
 -            else return Notifications.success(PREPARING_NOTIFICATIONS_TEXT);
 -        } catch (Exception e) {
 -            return Notifications.error(PREPARING_NOTIFICATIONS_TEXT);
 -        }
 -    }
 +      MapReduce passwordFunction = new MapReduce();
 +      passwordFunction.setMap("function(doc) { if(doc.username && doc.principalType === 'USER_ACCOUNT' && doc.password) { emit(doc.username, doc.password); } }");
  
 -    private Message addUserView() {
 -        try {
 -            DesignDocument userDocument = prepareDocument("_design/users");
 -            Map<String, MapReduce> views = new HashMap<>();
 +      MapReduce usernameFunction = new MapReduce();
 +      usernameFunction.setMap("function(doc) { if(doc.username) { emit(doc.username, doc); } }");
  
 -            MapReduce passwordFunction = new MapReduce();
 -            passwordFunction.setMap("function(doc) { if(doc.email&& doc.password) { emit(doc.email, doc.password); } }");
 +      MapReduce tokenFunction = new MapReduce();
 +      tokenFunction.setMap("function(doc) { if (doc.userApiTokens) { doc.userApiTokens.forEach(function(token) { emit(token.hashedToken, doc.email); });}}");
  
 -            MapReduce usernameFunction = new MapReduce();
 -            usernameFunction.setMap("function(doc) { if(doc.email) { emit(doc.email, doc); } }");
 +      views.put("password", passwordFunction);
 +      views.put("username", usernameFunction);
 +      views.put("token", tokenFunction);
  
 -            MapReduce tokenFunction = new MapReduce();
 -            tokenFunction.setMap("function(doc) { if (doc.userApiTokens) { doc.userApiTokens.forEach(function(token) { emit(token.hashedToken, doc.email); });}}");
 +      userDocument.setViews(views);
 +      Response resp = Utils.getCouchDbUserClient().design().synchronizeWithDb(userDocument);
  
 -            views.put("password", passwordFunction);
 -            views.put("username", usernameFunction);
 -            views.put("token", tokenFunction);
 -
 -            userDocument.setViews(views);
 -            Response resp = Utils.getCouchDbUserClient().design().synchronizeWithDb(userDocument);
 -
 -            if (resp.getError() != null) return Notifications.error(PREPARING_USERS_TEXT);
 -            else return Notifications.success(PREPARING_USERS_TEXT);
 -        } catch (Exception e) {
 -            return Notifications.error(PREPARING_USERS_TEXT);
 -        }
 +      if (resp.getError() != null) {
 +        logFailure(PREPARING_USERS_TEXT);
 +      } else {
 +        logSuccess(PREPARING_USERS_TEXT);
 +      }
 +    } catch (Exception e) {
 +      logFailure(PREPARING_USERS_TEXT, e);
      }
 +  }
  
 -    private Message addLabelView() {
 -        try {
 -            DesignDocument labelDocument = prepareDocument("_design/categoryId");
 -            Map<String, MapReduce> views = new HashMap<>();
 +  private void addLabelView() {
 +    try {
 +      DesignDocument labelDocument = prepareDocument("_design/categoryId");
 +      Map<String, MapReduce> views = new HashMap<>();
  
 -            MapReduce categoryIdFunction = new MapReduce();
 -            categoryIdFunction.setMap("function(doc) { if(doc.categoryId) { emit(doc.categoryId, doc); } }");
 +      MapReduce categoryIdFunction = new MapReduce();
 +      categoryIdFunction.setMap("function(doc) { if(doc.categoryId) { emit(doc.categoryId, doc); } }");
  
 -            views.put("categoryId", categoryIdFunction);
 +      views.put("categoryId", categoryIdFunction);
  
 -            labelDocument.setViews(views);
 -            Response resp = Utils.getCouchDbLabelClient().design().synchronizeWithDb(labelDocument);
 +      labelDocument.setViews(views);
 +      Response resp = Utils.getCouchDbLabelClient().design().synchronizeWithDb(labelDocument);
  
 -            if (resp.getError() != null) return Notifications.error(PREPARING_USERS_TEXT);
 -            else return Notifications.success(PREPARING_USERS_TEXT);
 -        } catch (Exception e) {
 -            return Notifications.error(PREPARING_USERS_TEXT);
 -        }
 +      if (resp.getError() != null) {
 +        logFailure(PREPARING_USERS_TEXT);
 +      } else {
 +        logSuccess(PREPARING_USERS_TEXT);
 +      }
 +    } catch (Exception e) {
 +      logFailure(PREPARING_USERS_TEXT, e);
      }
 +  }
  
 -    private Message addConnectionView() {
 -        try {
 -            DesignDocument connectionDocument = prepareDocument("_design/connection");
 -            Map<String, MapReduce> views = new HashMap<>();
 +  private void addConnectionView() {
 +    try {
 +      DesignDocument connectionDocument = prepareDocument("_design/connection");
 +      Map<String, MapReduce> views = new HashMap<>();
  
 -            MapReduce frequentFunction = new MapReduce();
 -            frequentFunction.setMap("function(doc) { if(doc.from && doc.to) { emit([doc.from, doc.to] , 1 ); } }");
 -            frequentFunction.setReduce("function (key, values) { return sum(values); }");
 +      MapReduce frequentFunction = new MapReduce();
 +      frequentFunction.setMap("function(doc) { if(doc.from && doc.to) { emit([doc.from, doc.to] , 1 ); } }");
 +      frequentFunction.setReduce("function (key, values) { return sum(values); }");
  
 -            views.put("frequent", frequentFunction);
 +      views.put("frequent", frequentFunction);
  
 -            connectionDocument.setViews(views);
 -            Response resp = Utils.getCouchDbConnectionClient().design().synchronizeWithDb(connectionDocument);
 -
 -            if (resp.getError() != null) return Notifications.error("Preparing database 'connection'...");
 -            else return Notifications.success("Preparing database 'connection'...");
 -        } catch (Exception e) {
 -            return Notifications.error("Preparing database 'connection'...");
 -        }
 -    }
 +      connectionDocument.setViews(views);
 +      Response resp = Utils.getCouchDbConnectionClient().design().synchronizeWithDb(connectionDocument);
  
 -    private DesignDocument prepareDocument(String id) {
 -        DesignDocument doc = new DesignDocument();
 -        doc.setLanguage("javascript");
 -        doc.setId(id);
 -        return doc;
 +      if (resp.getError() != null) {
 +        logFailure("Preparing database 'connection'...");
 +      } else {
 +        logSuccess("Preparing database 'connection'...");
 +      }
 +    } catch (Exception e) {
 +      logFailure("Preparing database 'connection'...", e);
      }
 +  }
 +
 +  private DesignDocument prepareDocument(String id) {
 +    DesignDocument doc = new DesignDocument();
 +    doc.setLanguage("javascript");
 +    doc.setId(id);
 +    return doc;
 +  }
  }
diff --cc ui/src/app/connect/services/data-marketplace.service.ts
index de185c0,afc9bda..588f91b
--- a/ui/src/app/connect/services/data-marketplace.service.ts
+++ b/ui/src/app/connect/services/data-marketplace.service.ts
@@@ -48,7 -44,7 +42,7 @@@ export class DataMarketplaceService 
    }
  
    get connectPath() {
-     return this.platformServicesCommons.apiBasePath + '/connect';
 -    return `${this.platformServicesCommons.apiBasePath()}/connect`;
++    return `${this.platformServicesCommons.apiBasePath}/connect`;
    }
  
    getAdapterDescriptions(): Observable<AdapterDescriptionUnion[]> {
diff --cc ui/src/app/connect/services/rest.service.ts
index b10b2d9,c2e12a8..d4d31a3
--- a/ui/src/app/connect/services/rest.service.ts
+++ b/ui/src/app/connect/services/rest.service.ts
@@@ -23,16 -23,9 +23,9 @@@ import { HttpClient } from '@angular/co
  import { from, Observable } from 'rxjs';
  import { map } from 'rxjs/operators';
  import { UnitDescription } from '../model/UnitDescription';
- import {
-   AdapterDescription,
-   FormatDescriptionList,
-   GuessSchema,
-   Message,
-   ProtocolDescriptionList,
-   SpDataStream
- } from '../../core-model/gen/streampipes-model';
+ import { AdapterDescription, FormatDescription, GuessSchema, Message, SpDataStream } from '../../core-model/gen/streampipes-model';
  import { PlatformServicesCommons } from '../../platform-services/apis/commons.service';
 -import { AuthStatusService } from '../../services/auth-status.service';
 +import { AuthService } from '../../services/auth.service';
  
  @Injectable()
  export class RestService {
@@@ -51,23 -44,19 +44,19 @@@
      return this.addAdapterDescription(adapter, '/master/adapters');
    }
  
-   addAdapterTemplate(adapter: AdapterDescription): Observable<Message> {
-     return this.addAdapterDescription(adapter, '/master/adapters/template');
-   }
- 
    addAdapterDescription(adapter: AdapterDescription, url: string): Observable<Message> {
 -    adapter.userName = this.authStatusService.email;
 +    adapter.userName = this.authService.getCurrentUser().email;
      const promise = new Promise<Message>((resolve, reject) => {
        this.http
-           .post(
-               this.connectPath + url,
-               adapter,
-           )
-           .pipe(map(response => {
-             const statusMessage = response as Message;
-             resolve(statusMessage);
-           }))
-           .subscribe();
+         .post(
+           this.connectPath + url,
+           adapter
+         )
+         .pipe(map(response => {
+           const statusMessage = response as Message;
+           resolve(statusMessage);
+         }))
+         .subscribe();
      });
      return from(promise);
    }
@@@ -83,14 -72,14 +72,14 @@@
  
    getSourceDetails(sourceElementId): Observable<SpDataStream> {
      return this.http
-         .get(this.platformServicesCommons.apiBasePath + '/streams/' + encodeURIComponent(sourceElementId)).pipe(map(response => {
-           return SpDataStream.fromData(response as SpDataStream);
-         }));
 -      .get(`${this.platformServicesCommons.apiBasePath()}/streams/${encodeURIComponent(sourceElementId)}`).pipe(map(response => {
++      .get(`${this.platformServicesCommons.apiBasePath}/streams/${encodeURIComponent(sourceElementId)}`).pipe(map(response => {
+         return SpDataStream.fromData(response as SpDataStream);
+       }));
    }
  
    getRuntimeInfo(sourceDescription): Observable<any> {
-     return this.http.post(this.platformServicesCommons.apiBasePath + '/pipeline-element/runtime', sourceDescription, {
-       headers: {ignoreLoadingBar: ''}
 -    return this.http.post(`${this.platformServicesCommons.apiBasePath()}/pipeline-element/runtime`, sourceDescription, {
++    return this.http.post(`${this.platformServicesCommons.apiBasePath}/pipeline-element/runtime`, sourceDescription, {
+       headers: { ignoreLoadingBar: '' }
      });
    }
  

[incubator-streampipes] 02/02: [STREAMPIPES-426] Add initial draft of permission management

Posted by ri...@apache.org.
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;
+  }
 }