Skip to content

Commit a7f2e93

Browse files
committed
Merge branch 'feature/422756_adapt_policies' into 'develop'
feature/422756_adapt_policies See merge request upm-inesdata/connector-management-interface!3
2 parents 4bc2613 + ee904f2 commit a7f2e93

File tree

11 files changed

+162
-100
lines changed

11 files changed

+162
-100
lines changed

src/app/pages/assets/asset-editor-dialog/asset-editor-dialog.component.scss

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ mat-dialog-content {
22
width: 800px;
33
}
44

5-
.form-field {
5+
.form-field:nth-child(odd) {
66
margin-right: 10px;
7-
width: 350px;
7+
width: calc(50% - 10px)
8+
}
9+
10+
.form-field:nth-child(even) {
11+
width: 50%
812
}
913

1014
mat-card-actions {

src/app/pages/assets/asset-viewer/asset-viewer.component.html

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
<div *ngIf="filteredAssets$ | async as assets" id="wrapper">
22
<div class="container">
33
<mat-form-field appearance="fill" appearance="outline" class="search-form-field" color="accent">
4-
<!-- <mat-label>Search assets</mat-label> -->
4+
<mat-label>Search assets</mat-label>
55
<input (input)="onSearch()" [(ngModel)]="searchText" matInput>
66
<mat-icon matPrefix>search</mat-icon>
77
<button (click)="searchText=''; onSearch()" *ngIf="searchText" mat-icon-button matSuffix>
88
<mat-icon>close</mat-icon>
99
</button>
1010
</mat-form-field>
1111

12-
<mat-paginator [length]="assets.length" hidePageSize="true" pageSize="contractDefinitions.length">
13-
</mat-paginator>
14-
1512
<button (click)="onCreate()" color="accent" mat-stroked-button>
1613
<mat-icon>add_circle_outline</mat-icon>
1714
Create asset
@@ -21,7 +18,7 @@
2118
<div fxLayout="row wrap" fxLayoutAlign="start start">
2219
<mat-card *ngFor="let asset of assets" class="asset-card">
2320
<mat-card-header>
24-
<mat-icon mat-card-avatar>id</mat-icon>
21+
<mat-icon mat-card-avatar>upload</mat-icon>
2522
<mat-card-title>{{asset.id}}</mat-card-title>
2623
</mat-card-header>
2724
<mat-card-content>
@@ -44,7 +41,7 @@
4441
</mat-list>
4542
</mat-card-content>
4643

47-
<mat-divider inset></mat-divider>
44+
<mat-divider></mat-divider>
4845
<mat-card-actions class="card-actions">
4946
<button (click)="onDelete(asset)" [disabled]="isBusy()" color="warn" mat-stroked-button>
5047
<mat-icon>delete_sweep</mat-icon> Delete

src/app/pages/assets/asset-viewer/asset-viewer.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class AssetViewerComponent implements OnInit {
5252

5353
onDelete(asset: Asset) {
5454
const dialogData = ConfirmDialogModel.forDelete("asset", `"${asset.id}"`)
55-
const ref = this.dialog.open(ConfirmationDialogComponent, {maxWidth: "20%", data: dialogData});
55+
const ref = this.dialog.open(ConfirmationDialogComponent, {maxWidth: "30%", data: dialogData});
5656

5757
ref.afterClosed().subscribe({
5858
next: res => {

src/app/pages/policies/new-policy-dialog/new-policy-dialog.component.html

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,22 @@
66
<input [(ngModel)]="policyDefinition.id" matInput required>
77
</mat-form-field>
88

9-
<!-- Assigner / Assignee-->
10-
<div>
11-
<mat-form-field class="form-field form-field-half" id="form-field-asignee">
12-
<mat-label>Assignee</mat-label>
13-
<input [(ngModel)]="policy.assignee" matInput>
14-
</mat-form-field>
15-
16-
<mat-form-field class="form-field form-field-half" id="form-field-assigner">
17-
<mat-label>Assigner</mat-label>
18-
<input [(ngModel)]="policy.assigner" matInput>
19-
</mat-form-field>
20-
</div>
21-
229
<!-- Permissions -->
2310
<mat-form-field class="form-field-stretch" color="accent" id="form-field-permissions">
2411
<mat-label>Permissions (JSON)</mat-label>
25-
<input [(ngModel)]="permissionsJson" matInput>
12+
<textarea [(ngModel)]="permissionsJson" rows=4 matInput></textarea>
2613
</mat-form-field>
2714

2815
<!-- Prohibitions -->
2916
<mat-form-field class="form-field-stretch" color="accent" id="form-field-prohibitions">
3017
<mat-label>Prohibitions (JSON)</mat-label>
31-
<input [(ngModel)]="prohibitionsJson" matInput>
18+
<textarea [(ngModel)]="prohibitionsJson" rows=4 matInput></textarea>
3219
</mat-form-field>
3320

3421
<!-- Obligations -->
3522
<mat-form-field class="form-field-stretch" color="accent" id="form-field-obligations">
3623
<mat-label>Obligations (JSON)</mat-label>
37-
<input [(ngModel)]="obligationsJson" matInput>
24+
<textarea [(ngModel)]="obligationsJson" rows=4 matInput></textarea>
3825
</mat-form-field>
3926

4027
</mat-dialog-content>
@@ -50,7 +37,7 @@
5037
Create
5138
</button>
5239

53-
<button color="accent" mat-dialog-close="true" mat-stroked-button>
40+
<button color="accent" mat-dialog-close mat-stroked-button>
5441
<mat-icon>cancel</mat-icon>
5542
Cancel
5643
</button>
Lines changed: 87 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import {Component, Inject, OnInit} from '@angular/core';
2-
import {PolicyDefinitionInput, PolicyInput} from "../../../shared/models/edc-connector-entities";
3-
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
1+
import { Component, OnInit } from '@angular/core';
2+
import { PolicyDefinitionInput, PolicyInput } from "../../../shared/models/edc-connector-entities";
3+
import { MatDialogRef } from "@angular/material/dialog";
4+
import { NotificationService } from 'src/app/shared/services/notification.service';
45

56
@Component({
67
selector: 'app-new-policy-dialog',
@@ -20,33 +21,104 @@ export class NewPolicyDialogComponent implements OnInit {
2021
prohibitionsJson: string = '';
2122
obligationsJson: string = '';
2223

23-
constructor(private dialogRef: MatDialogRef<NewPolicyDialogComponent>) {
24+
constructor(private dialogRef: MatDialogRef<NewPolicyDialogComponent>,
25+
private notificationService: NotificationService) {
2426
}
2527

2628
ngOnInit(): void {
2729
this.editMode = true;
2830
}
2931

3032
onSave() {
31-
if (this.permissionsJson && this.permissionsJson !== '') {
32-
this.policy.permission = JSON.parse(this.permissionsJson);
33+
try {
34+
this.policy.permission = this.parseAndVerifyJson(this.permissionsJson, "Permissions");
35+
this.policy.prohibition = this.parseAndVerifyJson(this.prohibitionsJson, "Prohibitions");
36+
this.policy.obligation = this.parseAndVerifyJson(this.obligationsJson, "Obligations");
37+
38+
this.policy["@context"] = "http://www.w3.org/ns/odrl.jsonld";
39+
40+
this.dialogRef.close({
41+
policy: this.policyDefinition.policy,
42+
'@id': this.policyDefinition.id
43+
});
44+
45+
} catch (error) {
46+
if (error instanceof SyntaxError) {
47+
this.notificationService.showError("Error parsing JSON: " + error.message);
48+
console.error(error);
49+
}
50+
if (error instanceof VerifyJsonKeysError) {
51+
this.notificationService.showError(error.message);
52+
console.error(error);
53+
}
54+
}
55+
}
56+
57+
/**
58+
* Parse and verify a JSON from the policy
59+
*
60+
* @param json JSON to parse and verify
61+
* @param property property of the policy which containst the JSON to verify (permissions, prohibitons or obligations)
62+
* @returns the parsed JSON or null if it is empty
63+
*/
64+
private parseAndVerifyJson(json: string, property: string): any {
65+
if (json.trim() != '') {
66+
const parsedJson = JSON.parse(json);
67+
let requiredKeys = ["target", "action"];
68+
let allowedKeys = [...requiredKeys, "constraint", "duty"];
69+
70+
if (property === 'Obligations') {
71+
allowedKeys = [...requiredKeys, "constraint"];
72+
requiredKeys = [];
73+
}
74+
75+
if (!this.verifyKeys(parsedJson, requiredKeys, allowedKeys)) {
76+
throw new VerifyJsonKeysError(property + ' JSON is not valid');
77+
}
78+
79+
return parsedJson;
3380
}
3481

35-
if (this.prohibitionsJson && this.prohibitionsJson !== '') {
36-
this.policy.prohibition = JSON.parse(this.prohibitionsJson);
82+
return null;
83+
}
84+
85+
/**
86+
* Checks if a JSON has the required keys and if it has invalid keys
87+
*
88+
* @param json the JSON to verify
89+
* @param requiredKeys requiered keys that must be included in the JSON
90+
* @param allowedKeys allowed keys that may be included in the JSON
91+
* @returns true if keys are valid, false otherwise
92+
*/
93+
private verifyKeys(json: any, requiredKeys: string[], allowedKeys: string[]): boolean {
94+
const keysFromJson = Object.keys(json);
95+
96+
if (requiredKeys.length > 0) {
97+
for (const key of requiredKeys) {
98+
if (!keysFromJson.includes(key)) {
99+
return false;
100+
}
101+
}
37102
}
38103

39-
if (this.obligationsJson && this.obligationsJson !== '') {
40-
this.policy.obligation = JSON.parse(this.obligationsJson);
104+
for (const key of keysFromJson) {
105+
if (!allowedKeys.includes(key)) {
106+
return false;
107+
}
41108
}
42109

43-
this.policy["@context"]="http://www.w3.org/ns/odrl.jsonld"
110+
return true;
111+
}
44112

113+
}
45114

46-
this.dialogRef.close({
115+
/**
116+
* Error class to throw when JSON keys are wrong
117+
*/
118+
class VerifyJsonKeysError extends Error {
119+
constructor(msg: string) {
120+
super(msg);
47121

48-
policy : this.policyDefinition.policy,
49-
'@id': this.policyDefinition.id
50-
})
122+
Object.setPrototypeOf(this, VerifyJsonKeysError.prototype);
51123
}
52124
}
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
<mat-expansion-panel fxFill [disabled]="rules?.length === 0" hideToggle>
2-
<mat-expansion-panel-header>
3-
<mat-panel-title>{{title}}</mat-panel-title>
4-
</mat-expansion-panel-header>
1+
<h2 mat-dialog-title>{{data.title}}</h2>
2+
<mat-dialog-content>
53
<div class="rule-json-panel">
6-
<pre><p>{{rules | json}}</p></pre>
4+
<pre><p>{{data.rules | json}}</p></pre>
75
</div>
8-
</mat-expansion-panel>
6+
</mat-dialog-content>
7+
<mat-dialog-actions>
8+
<button color="accent" mat-dialog-close mat-stroked-button>
9+
<mat-icon>cancel</mat-icon>
10+
close
11+
</button>
12+
</mat-dialog-actions>
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
.rule-json-panel{
2-
margin-left: 20px
3-
}
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import {Component, Input} from '@angular/core';
1+
import {Component, Inject} from '@angular/core';
2+
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
3+
4+
export interface DialogData {
5+
title: string;
6+
rules: any;
7+
}
28

39
@Component({
410
selector: 'policy-rules',
@@ -7,9 +13,5 @@ import {Component, Input} from '@angular/core';
713
})
814
export class PolicyRuleViewerComponent {
915

10-
@Input() rules: any[] | undefined = [];
11-
@Input() title: string =''
12-
13-
constructor() {
14-
}
16+
constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}
1517
}

src/app/pages/policies/policy-view/policy-view.component.html

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div id="wrapper" *ngIf="filteredPolicies$ | async as policyDefinitions">
2-
<!-- entry fields for new policy-->
2+
<!-- entry fields for new policy-->
33
<div class="container">
44
<mat-form-field appearance="outline" class="search-form-field" color="accent">
55
<mat-label>Search policies</mat-label>
@@ -10,53 +10,41 @@
1010
</button>
1111
</mat-form-field>
1212

13-
<mat-paginator [length]="policyDefinitions?.length" hidePageSize="true" pageSize="10"></mat-paginator>
14-
1513
<button (click)="onCreate()" color="accent" mat-stroked-button>
1614
<mat-icon>add_circle_outline</mat-icon>
1715
Create policy
1816
</button>
1917

2018
</div>
2119

22-
<div fxLayout="column" fxLayoutAlign="space-around stretch">
23-
<mat-card *ngFor="let policyDef of policyDefinitions" class="policy-card">
20+
<div fxLayout="row wrap" fxLayoutGap="15px">
21+
<mat-card fxFlex="0 1 calc(33.3% - 15px)" *ngFor="let policyDef of policyDefinitions" class="policy-card">
2422
<mat-card-header>
2523
<mat-icon mat-card-avatar>policy</mat-icon>
2624
<mat-card-title><span class="code">{{policyDef.id}}</span></mat-card-title>
2725
</mat-card-header>
2826

2927
<mat-card-content>
30-
31-
<mat-list dense>
32-
<mat-list-item>
33-
<mat-icon matListItemIcon>trip_origin</mat-icon>
34-
<div matListItemTitle>{{policyDef.policy.assigner || 'n/a'}}</div>
35-
<div matListItemLine>Assigner</div>
36-
</mat-list-item>
37-
<mat-list-item>
38-
<mat-icon matListItemIcon>adjust</mat-icon>
39-
<div matListItemTitle>{{policyDef.policy.assignee || 'n/a'}}</div>
40-
<div matListItemLine>Assignee</div>
41-
</mat-list-item>
42-
</mat-list>
43-
44-
<!-- Permissions-->
45-
<policy-rules [rules]="policyDef.policy.permissions" [title]="'Permissions'"></policy-rules>
46-
47-
<!-- Obligations-->
48-
<policy-rules [rules]="policyDef.policy.obligations" [title]="'Obligations'"></policy-rules>
49-
50-
<!-- Prohibitions-->
51-
<policy-rules [rules]="policyDef.policy.prohibitions" [title]="'Prohibitions'"></policy-rules>
52-
28+
<div fxlayout="row wrap" fxLayoutGap="15px" fxLayoutAlign="center">
29+
<!-- Permissions-->
30+
<button fxFlex="0 1 calc(33.3% - 15px)" mat-raised-button (click)="viewRules('Permissions', policyDef.policy.permissions)"
31+
[disabled]="policyDef.policy.permissions.length === 0">Permissions</button>
32+
33+
<!-- Obligations-->
34+
<button fxFlex="0 1 calc(33.3% - 15px)" mat-raised-button (click)="viewRules('Obligations', policyDef.policy.obligations)"
35+
[disabled]="policyDef.policy.obligations.length === 0">Obligations</button>
36+
37+
<!-- Prohibitions-->
38+
<button fxFlex="0 1 calc(33.3% - 15px)" mat-raised-button (click)="viewRules('Prohibitions', policyDef.policy.prohibitions)"
39+
[disabled]="policyDef.policy.prohibitions.length === 0">Prohibitions</button>
40+
</div>
5341
</mat-card-content>
54-
<button (click)="delete(policyDef)" mat-stroked-button color="warn" matSuffix>
55-
<mat-icon>delete</mat-icon>
56-
Delete
57-
</button>
58-
<mat-card-actions>
5942

43+
<mat-divider></mat-divider>
44+
<mat-card-actions class="card-actions">
45+
<button (click)="delete(policyDef)" color="warn" mat-stroked-button>
46+
<mat-icon>delete_sweep</mat-icon> Delete
47+
</button>
6048
</mat-card-actions>
6149
</mat-card>
6250
</div>

0 commit comments

Comments
 (0)