diff --git a/kouncil-backend/src/main/java/com/consdata/kouncil/datamasking/PolicyController.java b/kouncil-backend/src/main/java/com/consdata/kouncil/datamasking/PolicyController.java new file mode 100644 index 00000000..60ddd349 --- /dev/null +++ b/kouncil-backend/src/main/java/com/consdata/kouncil/datamasking/PolicyController.java @@ -0,0 +1,24 @@ +package com.consdata.kouncil.datamasking; + +import com.consdata.kouncil.model.admin.SystemFunctionName.Fields; +import javax.annotation.security.RolesAllowed; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +@AllArgsConstructor +@RequestMapping("/api/policy") +public class PolicyController { + + private final PolicyService policyService; + + @RolesAllowed(Fields.POLICY_DELETE) + @DeleteMapping(path = "/{id}") + public void deletePolicy(@PathVariable("id") Long id) { + policyService.deletePolicy(id); + } +} diff --git a/kouncil-backend/src/main/java/com/consdata/kouncil/datamasking/PolicyService.java b/kouncil-backend/src/main/java/com/consdata/kouncil/datamasking/PolicyService.java new file mode 100644 index 00000000..f827eef6 --- /dev/null +++ b/kouncil-backend/src/main/java/com/consdata/kouncil/datamasking/PolicyService.java @@ -0,0 +1,15 @@ +package com.consdata.kouncil.datamasking; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class PolicyService { + + private final PolicyRepository policyRepository; + + public void deletePolicy(Long id) { + policyRepository.deleteById(id); + } +} diff --git a/kouncil-backend/src/main/resources/kouncil.yaml b/kouncil-backend/src/main/resources/kouncil.yaml index b445de20..1c1ae465 100644 --- a/kouncil-backend/src/main/resources/kouncil.yaml +++ b/kouncil-backend/src/main/resources/kouncil.yaml @@ -29,7 +29,7 @@ kouncil: search-filter: "(&(objectClass=user)(userPrincipalName={0})(memberOf=CN=KOUNCIL,CN=Users,DC=kouncil,DC=io))" sso: supported: - providers: github + providers: github,okta topics: exclude-regex-patterns: __.* authorization: diff --git a/kouncil-frontend/apps/kouncil/src/app/app-factories.ts b/kouncil-frontend/apps/kouncil/src/app/app-factories.ts index cb9f6858..ef18be24 100644 --- a/kouncil-frontend/apps/kouncil/src/app/app-factories.ts +++ b/kouncil-frontend/apps/kouncil/src/app/app-factories.ts @@ -32,7 +32,14 @@ import { UserGroupService, UserGroupsService } from '@app/feat-user-groups'; -import {PoliciesBackendService, PoliciesDemoService, PoliciesService} from '@app/feat-data-masking'; +import { + PoliciesBackendService, + PoliciesDemoService, + PoliciesService, + PolicyBackendService, + PolicyDemoService, + PolicyService +} from '@app/feat-data-masking'; export function topicsServiceFactory(http: HttpClient): TopicsService { switch (environment.backend) { @@ -165,3 +172,14 @@ export function policiesServiceFactory(http: HttpClient): PoliciesService { return new PoliciesDemoService(); } } + +export function policyServiceFactory(http: HttpClient): PolicyService { + switch (environment.backend) { + case Backend.SERVER: { + return new PolicyBackendService(http); + } + case Backend.DEMO: + default: + return new PolicyDemoService(); + } +} diff --git a/kouncil-frontend/apps/kouncil/src/app/app.module.ts b/kouncil-frontend/apps/kouncil/src/app/app.module.ts index 1f7d23a6..77f1df2e 100644 --- a/kouncil-frontend/apps/kouncil/src/app/app.module.ts +++ b/kouncil-frontend/apps/kouncil/src/app/app.module.ts @@ -64,6 +64,7 @@ import { clustersServiceFactory, functionsServiceFactory, policiesServiceFactory, + policyServiceFactory, resendServiceFactory, schemaRegistryServiceFactory, sendServiceFactory, @@ -115,7 +116,7 @@ import { } from '@app/feat-user-groups'; import {RX_STOMP_CONFIG} from './rx-stomp.config'; import {FeatNotificationsModule, RxStompService} from '@app/feat-notifications'; -import {FeatDataMaskingModule, PoliciesService} from '@app/feat-data-masking'; +import {FeatDataMaskingModule, PoliciesService, PolicyService} from '@app/feat-data-masking'; import {FeatBreadcrumbModule} from '@app/feat-breadcrumb'; export const BASE_URL = new InjectionToken('BASE_URL'); @@ -347,7 +348,13 @@ export function authServiceFactory(http: HttpClient, baseUrl: string): AuthServi provide: PoliciesService, useFactory: policiesServiceFactory, deps: [HttpClient] + }, + { + provide: PolicyService, + useFactory: policyServiceFactory, + deps: [HttpClient] } + ], bootstrap: [AppComponent] }) diff --git a/kouncil-frontend/libs/feat-data-masking/src/index.ts b/kouncil-frontend/libs/feat-data-masking/src/index.ts index 72bd5784..d39794e4 100644 --- a/kouncil-frontend/libs/feat-data-masking/src/index.ts +++ b/kouncil-frontend/libs/feat-data-masking/src/index.ts @@ -3,3 +3,6 @@ export {PoliciesComponent} from './lib/policies/policies.component'; export {PoliciesService} from './lib/policies/policies.service'; export {PoliciesBackendService} from './lib/policies/policies.backend.service'; export {PoliciesDemoService} from './lib/policies/policies.demo.service'; +export {PolicyService} from './lib/policy/policy.service'; +export {PolicyBackendService} from './lib/policy/policy-backend.service'; +export {PolicyDemoService} from './lib/policy/policy-demo.service'; diff --git a/kouncil-frontend/libs/feat-data-masking/src/lib/policies/policies.component.ts b/kouncil-frontend/libs/feat-data-masking/src/lib/policies/policies.component.ts index 46891e68..1c2f01e8 100644 --- a/kouncil-frontend/libs/feat-data-masking/src/lib/policies/policies.component.ts +++ b/kouncil-frontend/libs/feat-data-masking/src/lib/policies/policies.component.ts @@ -1,11 +1,19 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; import {PoliciesService} from './policies.service'; -import {SystemFunctionName} from '@app/common-auth'; +import {AuthService, SystemFunctionName} from '@app/common-auth'; import {AbstractTableComponent, TableColumn} from '@app/common-components'; import {first} from 'rxjs/operators'; import {Subscription} from 'rxjs'; -import {ProgressBarService, SearchService} from '@app/common-utils'; +import { + ProgressBarService, + SearchService, + SnackBarComponent, + SnackBarData +} from '@app/common-utils'; import {MaskingType, Policy} from "../policy.model"; +import {ConfirmService} from "@app/feat-confirm"; +import {MatSnackBar} from "@angular/material/snack-bar"; +import {PolicyService} from "../policy/policy.service"; @Component({ selector: 'app-data-masking-policies', @@ -40,6 +48,12 @@ import {MaskingType, Policy} from "../policy.model"; [template]="cellTemplate">
+
@@ -104,7 +118,11 @@ export class PoliciesComponent extends AbstractTableComponent implements OnInit, constructor(private dataMaskingPoliciesService: PoliciesService, private progressBarService: ProgressBarService, - private searchService: SearchService) { + private searchService: SearchService, + private confirmService: ConfirmService, + private snackbar: MatSnackBar, + private policyService: PolicyService, + protected authService: AuthService) { super(); } @@ -138,4 +156,42 @@ export class PoliciesComponent extends AbstractTableComponent implements OnInit, }); } + confirmDeletePolicy(id: number, name: string): void { + this.subscription.add(this.confirmService.openConfirmDialog$({ + title: 'Delete policy', + subtitle: 'Are you sure you want to delete:', + sectionLine1: `Policy ${name}` + }) + .pipe(first()) + .subscribe((confirmed) => { + if (confirmed) { + this.progressBarService.setProgress(true); + this.deletePolicy(id, name); + } + })); + } + + private deletePolicy(id: number, name: string): void { + this.subscription.add(this.policyService.deletePolicy$(id) + .pipe(first()) + .subscribe({ + next: () => { + this.loadPolicies(); + + this.snackbar.openFromComponent(SnackBarComponent, { + data: new SnackBarData(`Policy ${name} deleted`, 'snackbar-success', ''), + panelClass: ['snackbar'], + duration: 3000 + }); + }, + error: () => { + this.snackbar.openFromComponent(SnackBarComponent, { + data: new SnackBarData(`Policy ${name} couldn't be deleted`, 'snackbar-error', ''), + panelClass: ['snackbar'], + duration: 3000 + }); + this.progressBarService.setProgress(false); + } + })); + } } diff --git a/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy-backend.service.ts b/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy-backend.service.ts new file mode 100644 index 00000000..2f753904 --- /dev/null +++ b/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy-backend.service.ts @@ -0,0 +1,18 @@ +import {Injectable} from '@angular/core'; +import {PolicyService} from './policy.service'; +import {Observable} from "rxjs"; +import {HttpClient} from "@angular/common/http"; + +@Injectable({ + providedIn: 'root' +}) +export class PolicyBackendService implements PolicyService { + + constructor(private http: HttpClient) { + } + + deletePolicy$(id: number): Observable { + return this.http.delete(`/api/policy/${id}`); + } + +} diff --git a/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy-demo.service.ts b/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy-demo.service.ts new file mode 100644 index 00000000..cace1ab7 --- /dev/null +++ b/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy-demo.service.ts @@ -0,0 +1,14 @@ +import {Injectable} from '@angular/core'; +import {Observable, of} from 'rxjs'; +import {PolicyService} from './policy.service'; + +@Injectable({ + providedIn: 'root' +}) +export class PolicyDemoService implements PolicyService { + + deletePolicy$(id: number): Observable { + return of(); + } + +} diff --git a/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy.service.ts b/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy.service.ts new file mode 100644 index 00000000..897517fc --- /dev/null +++ b/kouncil-frontend/libs/feat-data-masking/src/lib/policy/policy.service.ts @@ -0,0 +1,8 @@ +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs'; + +@Injectable() +export abstract class PolicyService { + + abstract deletePolicy$(id: number): Observable; +}