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/05 08:15:05 UTC
[incubator-streampipes] branch STREAMPIPES-426 updated:
[STREAMPIPES-43] Add group management
This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch STREAMPIPES-426
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
The following commit(s) were added to refs/heads/STREAMPIPES-426 by this push:
new 8b4e495 [STREAMPIPES-43] Add group management
8b4e495 is described below
commit 8b4e4952d6d00c76068e253d4360a65f98f46cb5
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Tue Oct 5 10:14:52 2021 +0200
[STREAMPIPES-43] Add group management
---
.../streampipes/model/client/user/Group.java | 11 ++-
.../streampipes/model/client/user/Principal.java | 10 +++
.../streampipes/rest/impl/UserGroupResource.java | 2 +-
ui/src/app/configuration/configuration.module.ts | 6 +-
.../edit-group-dialog.component.html | 55 +++++++++++++
.../edit-group-dialog.component.scss | 29 +++++++
.../edit-group-dialog.component.ts | 87 ++++++++++++++++++++
.../edit-user-dialog.component.html | 26 +++++-
.../edit-user-dialog/edit-user-dialog.component.ts | 40 ++++++++--
.../security-configuration.component.html | 8 ++
.../user-group-configuration.component.html | 77 ++++++++++++++++++
.../user-group-configuration.component.scss | 17 ++++
.../user-group-configuration.component.ts | 92 ++++++++++++++++++++++
.../app/core-model/gen/streampipes-model-client.ts | 29 ++++++-
.../platform-services/apis/user-group.service.ts | 60 ++++++++++++++
ui/src/app/platform-services/platform.module.ts | 4 +-
16 files changed, 534 insertions(+), 19 deletions(-)
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 2a2db99..8ee6e90 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
@@ -18,9 +18,13 @@
package org.apache.streampipes.model.client.user;
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
public class Group {
protected @SerializedName("_id") String groupId;
@@ -28,9 +32,10 @@ public class Group {
private String groupName;
- private List<Role> roles;
+ private Set<Role> roles;
public Group() {
+ this.roles = new HashSet<>();
}
public String getGroupId() {
@@ -57,11 +62,11 @@ public class Group {
this.groupName = groupName;
}
- public List<Role> getRoles() {
+ public Set<Role> getRoles() {
return roles;
}
- public void setRoles(List<Role> roles) {
+ public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
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 a9b9b04..7154e49 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
@@ -42,6 +42,7 @@ public abstract class Principal implements UserDetails {
protected List<Element> ownActions;
protected Set<Role> roles;
+ protected Set<String> groups;
private PrincipalType principalType;
@@ -51,6 +52,7 @@ public abstract class Principal implements UserDetails {
this.ownSepas = new ArrayList<>();
this.ownSources = new ArrayList<>();
this.roles = new HashSet<>();
+ this.groups = new HashSet<>();
}
public List<Element> getOwnSources() {
@@ -167,6 +169,14 @@ public abstract class Principal implements UserDetails {
this.principalType = principalType;
}
+ public Set<String> getGroups() {
+ return groups;
+ }
+
+ public void setGroups(Set<String> groups) {
+ this.groups = groups;
+ }
+
@Override
public boolean isAccountNonExpired() {
return !this.isAccountExpired();
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/UserGroupResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/UserGroupResource.java
index f02627c..4331fb2 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/UserGroupResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/UserGroupResource.java
@@ -24,7 +24,7 @@ import org.apache.streampipes.storage.api.IUserGroupStorage;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
-@Path("/v2/users/groups")
+@Path("/v2/usergroups")
public class UserGroupResource extends AbstractAuthGuardedRestResource {
@GET
diff --git a/ui/src/app/configuration/configuration.module.ts b/ui/src/app/configuration/configuration.module.ts
index a9cbc59..f88de28 100644
--- a/ui/src/app/configuration/configuration.module.ts
+++ b/ui/src/app/configuration/configuration.module.ts
@@ -50,6 +50,8 @@ import { SecurityUserConfigComponent } from './security-configuration/security-u
import { SecurityServiceConfigComponent } from './security-configuration/security-service-configuration/security-service-config.component';
import { EditUserDialogComponent } from './security-configuration/edit-user-dialog/edit-user-dialog.component';
import { PlatformServicesModule } from '../platform-services/platform.module';
+import { SecurityUserGroupConfigComponent } from './security-configuration/user-group-configuration/user-group-configuration.component';
+import { EditGroupDialogComponent } from './security-configuration/edit-group-dialog/edit-group-dialog.component';
@NgModule({
imports: [
@@ -80,12 +82,14 @@ import { PlatformServicesModule } from '../platform-services/platform.module';
ConsulConfigsNumberComponent,
DeleteDatalakeIndexComponent,
EditUserDialogComponent,
+ EditGroupDialogComponent,
PipelineElementConfigurationComponent,
SecurityConfigurationComponent,
SecurityUserConfigComponent,
+ SecurityUserGroupConfigComponent,
SecurityServiceConfigComponent,
MessagingConfigurationComponent,
- DatalakeConfigurationComponent
+ DatalakeConfigurationComponent,
],
providers: [
ConfigurationService,
diff --git a/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.html b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.html
new file mode 100644
index 0000000..f16b0fe
--- /dev/null
+++ b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.html
@@ -0,0 +1,55 @@
+<!--
+ ~ 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.
+ ~
+ -->
+
+<div class="sp-dialog-container">
+ <div class="sp-dialog-content">
+ <div fxFlex="100" fxLayout="column" class="p-15">
+ <form [formGroup]="parentForm" fxFlex="100" fxLayout="column">
+ <div class="general-options-panel" fxLayout="column">
+ <span class="general-options-header">Basics</span>
+ <mat-form-field color="accent">
+ <mat-label>Group Name</mat-label>
+ <input formControlName="groupName" fxFlex
+ matInput
+ required>
+ </mat-form-field>
+ </div>
+ <div fxLayout="column" class="general-options-panel">
+ <span class="general-options-header">Roles</span>
+ <mat-checkbox *ngFor="let role of availableRoles" [value]="role"
+ [checked]="group.roles.indexOf(role) > -1" (change)="changeRoleAssignment($event)">
+ {{role}}
+ </mat-checkbox>
+ </div>
+ </form>
+ </div>
+ </div>
+ <mat-divider></mat-divider>
+ <div class="sp-dialog-actions">
+ <div fxLayout="row">
+ <button mat-button mat-raised-button color="accent" (click)="save()" style="margin-right:10px;"
+ [disabled]="!parentForm.valid || clonedGroup.roles.length == 0"
+ data-cy="sp-element-edit-user-save">
+ <i class="material-icons">save</i><span> Save</span>
+ </button>
+ <button mat-button mat-raised-button class="mat-basic" (click)="close(false)">
+ Cancel
+ </button>
+ </div>
+ </div>
+</div>
diff --git a/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.scss b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.scss
new file mode 100644
index 0000000..8dace49
--- /dev/null
+++ b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.scss
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+@import '../../../../scss/sp/sp-dialog.scss';
+
+.form-field .mat-form-field-wrapper {
+ margin-bottom: -1.25em;
+}
+
+
+.form-field .mat-form-field-infix {
+ border-top: 0;
+}
+
diff --git a/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.ts b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.ts
new file mode 100644
index 0000000..f58a2da
--- /dev/null
+++ b/ui/src/app/configuration/security-configuration/edit-group-dialog/edit-group-dialog.component.ts
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
+import { Group, Role } from '../../../core-model/gen/streampipes-model-client';
+import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
+import { UserRole } from '../../../_enums/user-role.enum';
+import { DialogRef } from '../../../core-ui/dialog/base-dialog/dialog-ref';
+import { UserGroupService } from '../../../platform-services/apis/user-group.service';
+import { MatCheckboxChange } from '@angular/material/checkbox';
+
+@Component({
+ selector: 'sp-edit-group-dialog',
+ templateUrl: './edit-group-dialog.component.html',
+ styleUrls: ['./edit-group-dialog.component.scss'],
+ encapsulation: ViewEncapsulation.None
+})
+export class EditGroupDialogComponent implements OnInit {
+
+ @Input()
+ group: Group;
+
+ @Input()
+ editMode: boolean;
+
+ parentForm: FormGroup;
+ availableRoles: string[];
+ clonedGroup: Group;
+
+ constructor(private fb: FormBuilder,
+ private dialogRef: DialogRef<EditGroupDialogComponent>,
+ private userGroupService: UserGroupService) {}
+
+ ngOnInit(): void {
+ this.availableRoles = Object.values(UserRole).filter(value => typeof value === 'string') as string[];
+ this.clonedGroup = Group.fromData(this.group, new Group());
+ this.parentForm = this.fb.group({});
+ this.parentForm.addControl('groupName', new FormControl(this.clonedGroup.groupName, Validators.required));
+
+ this.parentForm.valueChanges.subscribe(v => this.clonedGroup.groupName = v.groupName);
+ }
+
+ close(refresh: boolean) {
+ this.dialogRef.close(refresh);
+ }
+
+ save() {
+ if (this.editMode) {
+ this.userGroupService.updateGroup(this.clonedGroup).subscribe(() => this.close(true));
+ } else {
+ this.userGroupService.createGroup(this.clonedGroup).subscribe(() => this.close(true));
+ }
+ }
+
+ changeRoleAssignment(event: MatCheckboxChange) {
+ if (this.clonedGroup.roles.indexOf(event.source.value as Role) > -1) {
+ this.removeRole(event.source.value);
+ } else {
+ this.addRole(event.source.value);
+ }
+ }
+
+ removeRole(role: string) {
+ this.clonedGroup.roles.splice(this.clonedGroup.roles.indexOf(role as Role), 1);
+ }
+
+ addRole(role: string) {
+ this.clonedGroup.roles.push(role as Role);
+ }
+
+
+}
diff --git a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
index 4bdc2a3..e9d5e53 100644
--- a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
+++ b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
@@ -1,3 +1,21 @@
+<!--
+ ~ 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.
+ ~
+ -->
+
<div class="sp-dialog-container">
<div class="sp-dialog-content">
<div fxFlex="100" fxLayout="column" class="p-15">
@@ -49,10 +67,10 @@
</div>
<div fxLayout="column" class="general-options-panel">
<span class="general-options-header">Groups</span>
-<!-- <mat-checkbox *ngFor="let role of availableRoles" [value]="role"-->
-<!-- [checked]="user.roles.indexOf(role) > -1" (change)="changeRoleAssignment($event)">-->
-<!-- {{role}}-->
-<!-- </mat-checkbox>-->
+ <mat-checkbox *ngFor="let group of availableGroups" [value]="group.groupId"
+ [checked]="user.groups.indexOf(group.groupId) > -1" (change)="changeGroupAssignment($event)">
+ {{group.groupName}}
+ </mat-checkbox>
</div>
<div fxLayout="column" class="general-options-panel">
<span class="general-options-header">Roles</span>
diff --git a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.ts b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.ts
index c9cb3f9..60b5a0e 100644
--- a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.ts
+++ b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.ts
@@ -1,6 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
import { AfterViewInit, Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { DialogRef } from '../../../core-ui/dialog/base-dialog/dialog-ref';
import {
+ Group,
Role,
ServiceAccount,
UserAccount
@@ -17,6 +36,7 @@ import {
import { UserRole } from '../../../_enums/user-role.enum';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { UserService } from '../../../platform-services/apis/user.service';
+import { UserGroupService } from '../../../platform-services/apis/user-group.service';
@Component({
selector: 'sp-edit-user-dialog',
@@ -24,7 +44,7 @@ import { UserService } from '../../../platform-services/apis/user.service';
styleUrls: ['./edit-user-dialog.component.scss'],
encapsulation: ViewEncapsulation.None
})
-export class EditUserDialogComponent implements OnInit, AfterViewInit {
+export class EditUserDialogComponent implements OnInit {
@Input()
user: any;
@@ -37,17 +57,19 @@ export class EditUserDialogComponent implements OnInit, AfterViewInit {
clonedUser: UserAccount | ServiceAccount;
availableRoles: string[];
+ availableGroups: Group[] = [];
constructor(private dialogRef: DialogRef<EditUserDialogComponent>,
private fb: FormBuilder,
- private userService: UserService) {
- }
-
- ngAfterViewInit(): void {
+ private userService: UserService,
+ private userGroupService: UserGroupService) {
}
ngOnInit(): void {
this.availableRoles = Object.values(UserRole).filter(value => typeof value === 'string') as string[];
+ this.userGroupService.getAllUserGroups().subscribe(response => {
+ this.availableGroups = response;
+ });
this.clonedUser = this.user instanceof UserAccount ? UserAccount.fromData(this.user, new UserAccount()) : ServiceAccount.fromData(this.user, new ServiceAccount());
this.isUserAccount = this.user instanceof UserAccount;
this.parentForm = this.fb.group({});
@@ -122,6 +144,14 @@ export class EditUserDialogComponent implements OnInit, AfterViewInit {
this.dialogRef.close(refresh);
}
+ changeGroupAssignment(event: MatCheckboxChange) {
+ if (this.clonedUser.groups.indexOf(event.source.value) > -1) {
+ this.clonedUser.groups.splice(this.clonedUser.groups.indexOf(event.source.value), 1);
+ } else {
+ this.clonedUser.groups.push(event.source.value);
+ }
+ }
+
changeRoleAssignment(event: MatCheckboxChange) {
if (this.clonedUser.roles.indexOf(event.source.value as Role) > -1) {
this.removeRole(event.source.value);
diff --git a/ui/src/app/configuration/security-configuration/security-configuration.component.html b/ui/src/app/configuration/security-configuration/security-configuration.component.html
index a1c9218..5db6583 100644
--- a/ui/src/app/configuration/security-configuration/security-configuration.component.html
+++ b/ui/src/app/configuration/security-configuration/security-configuration.component.html
@@ -33,4 +33,12 @@
</sp-split-section>
</div>
<mat-divider></mat-divider>
+ <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+ <sp-split-section title="Groups"
+ subtitle="Manage user groups">
+ <div class="subsection-title">Existing groups</div>
+ <sp-security-user-group-config></sp-security-user-group-config>
+ </sp-split-section>
+ </div>
+ <mat-divider></mat-divider>
</div>
diff --git a/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.html b/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.html
new file mode 100644
index 0000000..2d1473d
--- /dev/null
+++ b/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.html
@@ -0,0 +1,77 @@
+<!--
+ ~ 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.
+ ~
+ -->
+
+<div fxLayout="column">
+ <div>
+ <button mat-button mat-raised-button color="accent" (click)="createGroup()"><i
+ class="material-icons">add</i><span> New User Group</span></button>
+ </div>
+ <div fxFlex="100" fxLayout="column">
+ <table
+ fxFlex="100"
+ mat-table
+ data-cy="security-service-config"
+ [dataSource]="dataSource"
+ style="width: 100%;"
+ matSort>
+
+ <ng-container matColumnDef="groupName">
+ <th mat-header-cell mat-sort-header *matHeaderCellDef>Group name</th>
+ <td mat-cell *matCellDef="let group">
+ <h4 style="margin-bottom:0px;">{{group.groupName}}</h4>
+ </td>
+ </ng-container>
+
+ <ng-container matColumnDef="edit">
+ <th mat-header-cell *matHeaderCellDef class="text-right">Actions</th>
+ <td mat-cell *matCellDef="let group">
+ <div fxLayout="row">
+ <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="end center">
+ <div class="mr-15">
+ <button color="accent"
+ mat-button
+ mat-raised-button
+ matTooltip="Edit user"
+ matTooltipPosition="above"
+ data-cy="service-edit-btn"
+ (click)="editGroup(group)">
+ <i class="material-icons">edit</i>
+ <span> Edit</span>
+ </button>
+ </div>
+ <button color="warn"
+ mat-button
+ mat-raised-button
+ matTooltip="Delete service"
+ matTooltipPosition="above"
+ data-cy="service-delete-btn"
+ (click)="deleteGroup(group)">
+ <i class="material-icons">delete</i>
+ <span> Delete</span>
+ </button>
+ </span>
+ </div>
+ </td>
+ </ng-container>
+
+ <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+ <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+
+ </table>
+ </div>
+</div>
diff --git a/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.scss b/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.scss
new file mode 100644
index 0000000..13cbc4a
--- /dev/null
+++ b/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.scss
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ *
+ */
diff --git a/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.ts b/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.ts
new file mode 100644
index 0000000..630e48b
--- /dev/null
+++ b/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.ts
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { Group } from '../../../core-model/gen/streampipes-model-client';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import { MatTableDataSource } from '@angular/material/table';
+import { UserGroupService } from '../../../platform-services/apis/user-group.service';
+import { PanelType } from '../../../core-ui/dialog/base-dialog/base-dialog.model';
+import { DialogService } from '../../../core-ui/dialog/base-dialog/base-dialog.service';
+import { EditGroupDialogComponent } from '../edit-group-dialog/edit-group-dialog.component';
+
+@Component({
+ selector: 'sp-security-user-group-config',
+ templateUrl: './user-group-configuration.component.html',
+ styleUrls: ['./user-group-configuration.component.scss']
+})
+export class SecurityUserGroupConfigComponent implements OnInit {
+
+
+ @ViewChild(MatPaginator) paginator: MatPaginator;
+ pageSize = 1;
+ @ViewChild(MatSort) sort: MatSort;
+
+ dataSource: MatTableDataSource<Group>;
+
+ displayedColumns: string[] = ['groupName', 'edit'];
+
+ constructor(private userGroupService: UserGroupService,
+ private dialogService: DialogService) {}
+
+ ngOnInit(): void {
+ this.loadAllGroups();
+ }
+
+ createGroup() {
+ const group = new Group();
+ group.roles = [];
+ this.openGroupEditDialog(group, false);
+ }
+
+ loadAllGroups() {
+ this.userGroupService.getAllUserGroups().subscribe(response => {
+ this.dataSource = new MatTableDataSource(response);
+ });
+ }
+
+ deleteGroup(group: Group) {
+ this.userGroupService.deleteGroup(group).subscribe(response => {
+ this.loadAllGroups();
+ });
+ }
+
+ editGroup(group: Group) {
+ this.openGroupEditDialog(group, true);
+ }
+
+ openGroupEditDialog(group: Group, editMode: boolean) {
+ const dialogRef = this.dialogService.open(EditGroupDialogComponent, {
+ panelType: PanelType.SLIDE_IN_PANEL,
+ title: editMode ? 'Edit group ' + group.groupName : 'Add group',
+ width: '50vw',
+ data: {
+ 'group': group,
+ 'editMode': editMode
+ }
+ });
+
+ dialogRef.afterClosed().subscribe(refresh => {
+ if (refresh) {
+ this.loadAllGroups();
+ }
+ });
+ }
+
+}
diff --git a/ui/src/app/core-model/gen/streampipes-model-client.ts b/ui/src/app/core-model/gen/streampipes-model-client.ts
index 1564e3a..b99c706 100644
--- a/ui/src/app/core-model/gen/streampipes-model-client.ts
+++ b/ui/src/app/core-model/gen/streampipes-model-client.ts
@@ -19,7 +19,7 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
-// Generated using typescript-generator version 2.27.744 on 2021-10-04 22:00:31.
+// Generated using typescript-generator version 2.27.744 on 2021-10-05 10:08:33.
export class Element {
elementId: string;
@@ -102,6 +102,25 @@ export interface GrantedAuthority {
authority: string;
}
+export class Group {
+ groupId: string;
+ groupName: string;
+ rev: string;
+ roles: Role[];
+
+ static fromData(data: Group, target?: Group): Group {
+ if (!data) {
+ return data;
+ }
+ const instance = target || new Group();
+ instance.groupId = data.groupId;
+ instance.rev = data.rev;
+ instance.groupName = data.groupName;
+ instance.roles = __getCopyArrayFn(__identity<Role>())(data.roles);
+ return instance;
+ }
+}
+
export class MatchingResultMessage {
description: string;
matchingSuccessful: boolean;
@@ -134,6 +153,7 @@ export class Principal implements UserDetails {
authorities: GrantedAuthority[];
credentialsNonExpired: boolean;
enabled: boolean;
+ groups: string[];
ownActions: Element[];
ownSepas: Element[];
ownSources: Element[];
@@ -150,12 +170,12 @@ export class Principal implements UserDetails {
}
const instance = target || new Principal();
instance.enabled = data.enabled;
- instance.password = data.password;
instance.username = data.username;
- instance.authorities = __getCopyArrayFn(__identity<GrantedAuthority>())(data.authorities);
- instance.accountNonLocked = data.accountNonLocked;
+ instance.password = data.password;
instance.accountNonExpired = data.accountNonExpired;
+ instance.accountNonLocked = data.accountNonLocked;
instance.credentialsNonExpired = data.credentialsNonExpired;
+ instance.authorities = __getCopyArrayFn(__identity<GrantedAuthority>())(data.authorities);
instance.principalId = data.principalId;
instance.rev = data.rev;
instance.accountEnabled = data.accountEnabled;
@@ -165,6 +185,7 @@ export class Principal implements UserDetails {
instance.ownSepas = __getCopyArrayFn(Element.fromData)(data.ownSepas);
instance.ownActions = __getCopyArrayFn(Element.fromData)(data.ownActions);
instance.roles = __getCopyArrayFn(__identity<Role>())(data.roles);
+ instance.groups = __getCopyArrayFn(__identity<string>())(data.groups);
instance.principalType = data.principalType;
return instance;
}
diff --git a/ui/src/app/platform-services/apis/user-group.service.ts b/ui/src/app/platform-services/apis/user-group.service.ts
new file mode 100644
index 0000000..d39f788
--- /dev/null
+++ b/ui/src/app/platform-services/apis/user-group.service.ts
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { map } from 'rxjs/operators';
+import { Observable } from 'rxjs';
+import { PlatformServicesCommons } from './commons.service';
+import { Group } from '../../core-model/gen/streampipes-model-client';
+
+@Injectable()
+export class UserGroupService {
+
+ constructor(private http: HttpClient,
+ private platformServicesCommons: PlatformServicesCommons) {
+ }
+
+ public getAllUserGroups(): Observable<Group[]> {
+ return this.http.get(`${this.userGroupPath}`)
+ .pipe(map(response => {
+ return (response as any[]).map(p => Group.fromData(p));
+ }));
+ }
+
+ public createGroup(group: Group) {
+ return this.http.post(this.userGroupPath, group);
+ }
+
+ public updateGroup(group: Group) {
+ return this.http.put(`${this.userGroupPath}/${group.groupId}`, group);
+ }
+
+ public deleteGroup(group: Group) {
+ return this.http.delete(`${this.userGroupPath}/${group.groupId}`);
+ }
+
+ public getGroup(groupId: string) {
+ return this.http.get(`${this.userGroupPath}/${groupId}`);
+ }
+
+ private get userGroupPath() {
+ return this.platformServicesCommons.apiBasePath + '/usergroups';
+ }
+
+}
diff --git a/ui/src/app/platform-services/platform.module.ts b/ui/src/app/platform-services/platform.module.ts
index 8a3ed07..e2a8eae 100644
--- a/ui/src/app/platform-services/platform.module.ts
+++ b/ui/src/app/platform-services/platform.module.ts
@@ -29,6 +29,7 @@ import { SemanticTypesService } from './apis/semantic-types.service';
import { PipelineCanvasMetadataService } from './apis/pipeline-canvas-metadata.service';
import { PipelineTemplateService } from './apis/pipeline-template.service';
import { UserService } from './apis/user.service';
+import { UserGroupService } from './apis/user-group.service';
@NgModule({
imports: [],
@@ -45,7 +46,8 @@ import { UserService } from './apis/user.service';
PipelineService,
SemanticTypesService,
PipelineTemplateService,
- UserService
+ UserService,
+ UserGroupService
],
entryComponents: []
})