Unverified Commit dd9b6656 authored by Markus V's avatar Markus V
Browse files

Attestation Validator

parent 99be7b05
Pipeline #103394319 passed with stage
in 6 minutes and 32 seconds
......@@ -107,7 +107,7 @@
<!-- Attribute table -->
<div class="card-body">
<div>
<h6 class="card-subtitle mb-2">Attributes:</h6>
<h6 class="card-subtitle mb-2">Self Attested Attributes:</h6>
<!-- Missing attributes -->
<table class="table pb-1" *ngIf="isAttributeMissing(identityInEdit)">
<thead>
......@@ -174,20 +174,20 @@
</ul>
</div>
<div>
<button class="btn btn-primary" (click)="toggleShowRef(identityInEdit)" [style.float]="'right'">
<button class="btn btn-primary" (click)="toggleShowRef(identityInEdit) || isReferenceMissing(identityInEdit)" [style.float]="'right'">
<span *ngIf="identityInEdit == showReferenceMan"> Hide</span>
<span *ngIf="identityInEdit != showReferenceMan"> Show</span>
reference management
</button>
</div>
<div style="margin-top: 1.5em;" *ngIf="identityInEdit == showReferenceMan">
<h6 class="card-subtitle mb-2">References:</h6>
<h6 class="card-subtitle mb-2">Third-Party Attested Attributes:</h6>
<!-- Missing references -->
<table class="table pb-1" *ngIf="isReferenceMissing(identityInEdit)">
<thead>
<tr>
<th>Reference Name</th>
<th>Referenced Value</th>
<th>Attribute Name</th>
<th>Attribute Value</th>
<th>Attestation ID</th>
</tr>
</thead>
......@@ -195,10 +195,21 @@
<tr [class.openid]="inOpenIdFlow()" [class.alert-danger]="newReference.name === missing.name" class="text-primary" *ngFor="let missing of missingReferences[identityInEdit.pubkey]">
<td><div style="min-width: 15em">{{missing.name}}</div></td>
<td>
<input placeholder="Claim in Attest" [(ngModel)]="missing.ref_value">
<select *ngIf="missing.ref_id !== ''" (change)="missing.ref_value=$event.target.value">
<option value="">Select a Claim</option>
<option *ngFor="let claim of objectKeys(attestation_val[identityInEdit.pubkey][missing.ref_id])" value={{claim}}>
{{claim}}
</option>
<option value="">{{attestation_val[identityInEdit.pubkey][missing.ref_id]['iss']}}</option>
</select>
</td>
<td>
<input placeholder="Attestation ID" [(ngModel)]="missing.ref_id">
<select (change)="missing.ref_id=$event.target.value; ">
<option value="">Select an Attestation</option>
<option *ngFor="let attest of attestation[identityInEdit.pubkey]" value={{attest.id}}>
{{attest.name}}
</option>
</select>
</td>
<td>
</td>
......@@ -209,18 +220,18 @@
<table class="table pb-1" style="">
<thead *ngIf="!isReferenceMissing(identityInEdit)">
<tr>
<th>Reference Name</th>
<th>Referenced Value</th>
<th>Attribute Name</th>
<th>Attribute Value</th>
<th>Attestation ID</th>
</tr>
</thead>
<tbody>
<tr [class.openid]="inOpenIdFlow()" [class.text-primary]="isRefRequested(identityInEdit, reference)" [class.text-secondary]="isoptRefRequested(identityInEdit, reference)" [class.alert-danger]="newReference.name === reference.name" *ngFor="let reference of references[identityInEdit.pubkey]">
<tr [class.openid]="inOpenIdFlow()" [class.text-primary]="isRefRequested(identityInEdit, reference)" [class.text-secondary]="isoptRefRequested(identityInEdit, reference)" [class.alert-danger]="newReference.name === reference.name" [class.alert-warning]="!isAttestationValid(reference.ref_id,identityInEdit)" *ngFor="let reference of references[identityInEdit.pubkey]">
<td><div style="min-width: 15em">{{reference.name}}</div></td>
<td>
<input placeholder="Claim Name Attest" [(ngModel)]="reference.ref_value">
</td>
<td>
<td>
<input placeholder="Attestation ID" [(ngModel)]="reference.ref_id">
</td>
<td>
......@@ -228,16 +239,31 @@
<span class="fa fa-trash"></span>
</button>
</td>
<td>
<div *ngIf= "isAttestationValid(reference.ref_id, identityInEdit)"> Valid Reference <span class="fa fa-check"></span> </div>
<div *ngIf= "!isAttestationValid(reference.ref_id, identityInEdit)"> <span style="color:#f00"> Expired Attestation </span><span class="fa fa-times"></span> </div>
</td>
</tr>
<tr [class.alert-danger]="isRefInConflict(identityInEdit,newReference)">
<td>
<input [class.text-danger]="!referenceNameValid(identityInEdit,newReference)" placeholder="Reference" [(ngModel)]="newReference.name">
</td>
<td>
<input placeholder="Claim Name Attest" [class.text-danger]="!referenceValueValid(newReference)" [(ngModel)]="newReference.ref_value">
<select *ngIf="newReference.ref_id !== ''" (change)="newReference.ref_value=$event.target.value">
<option value="">Select a Claim</option>
<option *ngFor="let claim of objectKeys(attestation_val[identityInEdit.pubkey][newReference.ref_id])" value={{claim}}>
{{claim}}
</option>
<option value="">{{attestation_val[identityInEdit.pubkey][newReference.ref_id]['iss']}}</option>
</select>
</td>
<td>
<input placeholder="Attestation ID" [class.text-danger]="!referenceIDValid(newReference)" [(ngModel)]="newReference.ref_id">
<select (change)="newReference.ref_id=$event.target.value; ">
<option value="">Select an Attestation</option>
<option *ngFor="let attest of attestation[identityInEdit.pubkey]" value={{attest.id}}>
{{attest.name}}
</option>
</select>
</td>
<td>
......@@ -280,12 +306,13 @@
<tr>
<th>Attestation Name</th>
<th>Attestation Type</th>
<th>Attestation Value</th>
<th>Attestation Value</th>
<th>Issuer</th>
<th>Attestation ID</th>
</tr>
</thead>
<tbody>
<tr [class.openid]="inOpenIdFlow()" [class.alert-danger]="newAttestation.name === attestation.name" *ngFor="let attestation of attestation[identityInEdit.pubkey]">
<tr [class.openid]="inOpenIdFlow()" [class.alert-danger]="newAttestation.name === attestation.name" [class.alert-warning]="!isAttestationValid(attestation.id, identityInEdit)" *ngFor="let attestation of attestation[identityInEdit.pubkey]">
<td><div style="min-width: 15em">{{attestation.name}}</div></td>
<td>
<div>{{attestation.type}}</div>
......@@ -293,12 +320,17 @@
<td>
<input placeholder="Attestation Value" [(ngModel)]="attestation.value">
</td>
<td><div style="min-width: 15em">{{attestation_val[identityInEdit.pubkey][attestation.id]['iss']}}</div></td>
<td><div style="min-width: 15em">{{attestation.id}}</div></td>
<td>
<button class="btn btn-primary" (click)="deleteAttestation(attestation)">
<span class="fa fa-trash"></span>
</button>
</td>
<td>
<div *ngIf= "isAttestationValid(attestation.id, identityInEdit)"> Valid <span class="fa fa-check"></span> </div>
<div *ngIf= "!isAttestationValid(attestation.id, identityInEdit)"> <span style="color:#f00"> Expired </span> <span class="fa fa-times"></span> </div>
</td>
</tr>
<tr [class.alert-danger]="isAttestInConflict(identityInEdit,newAttestation)">
<td>
......@@ -318,8 +350,7 @@
</tr>
</tbody>
</table>
<button style="background-color:#4267B2; margin:5px; border:none; color:white">Receive via Facebook</button>
<button style="background-color:#4285F4; margin:5px; border:none; color:white">Receive via Google</button>
<button style="background-color:#4267B2; margin:5px; border:none; color:white" (click)="addExampleAttestation()">Receive Example Attestation</button>
</div>
<!-- Attestation creation warning -->
<div *ngIf="!attestationNameValid(identityInEdit,newAttestation) || !attestationTypeValid(newAttestation) || !attestationValueValid(newAttestation)" class="alert alert-primary alert-dismissible fade show" role="alert">
......@@ -442,6 +473,12 @@
<span class="fa fa-plus"></span> Add
</button>
</div>
<div *ngIf="isReqReferenceInvalid(identity)" class="alert alert-danger alert-dismissible fade show" role="alert">
<span class="fa fa-openid"></span> This identity cannot be used because one or more references are invalid.
<button class="btn btn-primary" (click)="editIdentity(identity)">
<span class="fa fa-pencil-square-o"></span> Edit
</button>
</div>
<div *ngIf="(0 < requestedReferences[identity.pubkey]?.length) && inOpenIdFlow()" class="alert alert-danger alert-dismissible fade show" role="alert">
<span class="fa fa-openid"></span> Please mind, that sharing references might disclose additional information stored in the attestation.
</div>
......@@ -490,7 +527,7 @@
</div>
<div>
<div>
<button *ngIf="canAuthorize(identity)" [disabled]="!inOpenIdFlow() || isReferenceMissing(identity) || isAttributeMissing(identity) || !clientNameFound" (click)="loginIdentity(identity)" class="btn btn-primary mr-1 openid-login">
<button *ngIf="canAuthorize(identity)" [disabled]="!inOpenIdFlow() || isReferenceMissing(identity) || isAttributeMissing(identity) || !clientNameFound || isReqReferenceInvalid(identity)" (click)="loginIdentity(identity)" class="btn btn-primary mr-1 openid-login">
<span *ngIf="clientNameFound"><i class="fa fa-openid"></i> Share from this identity</span>
<span *ngIf="!clientNameFound"><i class="fa fa-exclamation-circle"></i> Sharing disabled</span>
</button>
......
......@@ -30,6 +30,7 @@ export class IdentityListComponent implements OnInit {
references: any;
newReference: Reference;
attestation: any;
attestation_val: any;
newAttestation: Attestation;
optionalReferences: any;
tickets: any;
......@@ -50,6 +51,7 @@ export class IdentityListComponent implements OnInit {
modalOpened: any;
clientNameFound: any;
errorInfos: any;
objectKeys : any;
constructor(private route: ActivatedRoute, private oidcService: OpenIdService,
private identityService: IdentityService,
......@@ -61,12 +63,14 @@ export class IdentityListComponent implements OnInit {
}
ngOnInit() {
this.objectKeys= Object.keys;
this.attributes = {};
this.references = {};
this.missingReferences = {};
this.requestedReferences = {};
this.newReference = new Reference('', '', '', '');
this.attestation = {};
this.attestation_val = {};
this.newAttestation = new Attestation('', '', '', '');
this.optionalReferences = {};
this.tickets = {};
......@@ -472,9 +476,11 @@ export class IdentityListComponent implements OnInit {
private updateAttestation(identity) {
this.reclaimService.getAttestation(identity).subscribe(attestation => {
this.attestation[identity.pubkey] = [];
this.attestation_val[identity.pubkey] = [];
let i;
for (i = 0; i < attestation.length; i++) {
this.attestation[identity.pubkey].push(attestation[i]);
this.setAttestationValue(attestation[i], identity);
}
this.updateTickets(identity);
},
......@@ -613,6 +619,42 @@ export class IdentityListComponent implements OnInit {
});
}
private setAttestationValue(attestation, identity) {
var value_string="";
return this.reclaimService.parseAttest(attestation).subscribe(json_string =>{
this.attestation_val[identity.pubkey][attestation.id]=json_string;
},
err => {
this.errorInfos.push("Error parsing attestation ``" + attestation.name + "''");
console.log(err);
});
}
isAttestationValid(attestation_id, identity) {
const now = Date.now().valueOf() / 1000;
if (this.attestation_val[identity.pubkey][attestation_id]['exp'] === 'undefined') {
return true;
}
return this.attestation_val[identity.pubkey][attestation_id]['exp'] > now;
}
addExampleAttestation() {
var exampleAttestation = new Attestation('exampleattest', '', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJFeGFtcGxlIENBIiwiaWF0IjoxNTcwMzc1ODIxLCJleHAiOjE2MDE5MTE4MjEsImF1ZCI6IioiLCJzdWIiOiJGb29AYmFyLmNvbSIsIkdpdmVuTmFtZSI6IkZvbyIsIlN1cm5hbWUiOiJCYXIiLCJFbWFpbCI6IkZvb0BiYXIuY29tIn0.PZwmUoJk7RXMJXYY5RoAUYeiIwNjEPEYTY9zT9o8vR4', 'JWT');
if (this.canAddAttestation(this.identityInEdit, exampleAttestation)){
this.reclaimService.addAttestation(this.identityInEdit, exampleAttestation)
.subscribe(res => {
//FIXME info dialog
this.updateAttestation(this.identityInEdit);
this.updateReferences(this.identityInEdit);
this.updateAttributes(this.identityInEdit);
},
err => {
this.errorInfos.push("Failed to add attestation ``" + exampleAttestation.name + "''");
console.log(err);
});
}
}
cancelAddIdentity() { this.newIdentity = null; }
saveIdentity() {
......@@ -996,6 +1038,21 @@ export class IdentityListComponent implements OnInit {
return false;
}
isReqReferenceInvalid(identity) {
if (!this.inOpenIdFlow()) {
return false;
}
if (undefined === this.requestedReferences[identity.pubkey]) {
return false;
}
for (var j =0; j< this.requestedReferences[identity.pubkey].length; j++) {
if (!this.isAttestationValid(this.requestedReferences[identity.pubkey][j].ref_id, identity)){
return true;
}
}
return false;
}
hasAttributes(identity) {
if (undefined === this.attributes[identity.pubkey]) {
return false;
......
......@@ -74,4 +74,11 @@ export class ReclaimService {
return this.http.post<Ticket>(this.config.get().apiUrl + '/reclaim/revoke',
ticket);
}
parseAttest(attestation: Attestation) {
var json = JSON.parse('{"value":"'+ attestation.value + '", "type":"'+ attestation.type + '"}')
return this.http.post(this.config.get().apiUrl +
'/reclaim/attestation/parse',json
);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment