Skip to content

Commit

Permalink
Basic Implementation of Policy Constraints
Browse files Browse the repository at this point in the history
Signed-off-by: Felix Hoops <9974641+jfelixh@users.noreply.github.com>
  • Loading branch information
jfelixh authored and actions-user committed Mar 15, 2024
1 parent 989d8ef commit 286af54
Show file tree
Hide file tree
Showing 15 changed files with 356 additions and 129 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# vscode settings
.vscode
.vscode

.DS_Store
Empty file modified test_client.sh
100644 → 100755
Empty file.
50 changes: 20 additions & 30 deletions vclogin/__tests__/evaluateLoginPolicy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
* SPDX-License-Identifier: MIT
*/

import {
isTrustedPresentation,
exportedForTesting,
} from "@/lib/evaluateLoginPolicy";
import { isTrustedPresentation } from "@/lib/extractClaims";
import vpEmployee from "@/testdata/presentations/VP_EmployeeCredential.json";
import vpEmail from "@/testdata/presentations/VP_EmailPass.json";
import vpTezos from "@/testdata/presentations/VP_TezosAssociatedAddress.json";
import policyAcceptAnything from "@/testdata/policies/acceptAnything.json";
import policyEmployeeFromAnyone from "@/testdata/policies/acceptEmployeeFromAnyone.json";
import policyEmailFromAltme from "@/testdata/policies/acceptEmailFromAltme.json";
import policyFromAltme from "@/testdata/policies/acceptFromAltme.json";
import policyEmailFromAltmeConstr from "@/testdata/policies/acceptEmailFromAltmeConstr.json";
import policyEmployeeFromAnyoneConstr from "@/testdata/policies/acceptEmployeeFromAnyoneConstr.json";

describe("evaluateLoginPolicy", () => {
it("defaults to false if no policy is available", () => {
Expand Down Expand Up @@ -54,34 +53,25 @@ describe("evaluateLoginPolicy", () => {
trusted = isTrustedPresentation(vpEmployee, policyFromAltme);
expect(trusted).toBe(false);
});
});

describe("utility function for VP policy validation", () => {
let hasUniquePath = exportedForTesting.hasUniquePath;

it("should return true when there is a unique path", () => {
const patternFits = [
["A", "B"],
["C", "D"],
["E", "F"],
];
const usedCreds = ["A", "C", "E"];
expect(hasUniquePath(patternFits, usedCreds)).toBe(true);
});

it("should return false when there is no unique path", () => {
const patternFits = [
["A", "B"],
["C", "D"],
["E", "F"],
];
const usedCreds = ["A", "C", "E", "B"];
expect(hasUniquePath(patternFits, usedCreds)).toBe(false);
it("accepts only VP with credential(s) with simple constraint", () => {
var trusted = isTrustedPresentation(vpEmail, policyEmailFromAltmeConstr);
expect(trusted).toBe(true);
trusted = isTrustedPresentation(vpEmployee, policyEmailFromAltmeConstr);
expect(trusted).toBe(false);
trusted = isTrustedPresentation(vpTezos, policyEmailFromAltmeConstr);
expect(trusted).toBe(false);
});

it("should return false when the patternFits array has only one subarray with no elements", () => {
const patternFits = [[]];
const usedCreds = [];
expect(hasUniquePath(patternFits, usedCreds)).toBe(false);
it("accepts only VP with credential(s) with complicated constraint", () => {
var trusted = isTrustedPresentation(
vpEmployee,
policyEmployeeFromAnyoneConstr,
);
expect(trusted).toBe(true);
trusted = isTrustedPresentation(vpEmail, policyEmployeeFromAnyoneConstr);
expect(trusted).toBe(false);
trusted = isTrustedPresentation(vpTezos, policyEmployeeFromAnyoneConstr);
expect(trusted).toBe(false);
});
});
12 changes: 12 additions & 0 deletions vclogin/__tests__/extractClaims.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import vpEmployee from "@/testdata/presentations/VP_EmployeeCredential.json";
import vpEmail from "@/testdata/presentations/VP_EmailPass.json";
import policyAcceptAnything from "@/testdata/policies/acceptAnything.json";
import policyEmailFromAltme from "@/testdata/policies/acceptEmailFromAltme.json";
import policyEmailFromAltmeConstr from "@/testdata/policies/acceptEmailFromAltmeConstr.json";
import policyEmployeeFromAnyone from "@/testdata/policies/acceptEmployeeFromAnyone.json";

describe("extractClaims", () => {
Expand Down Expand Up @@ -47,6 +48,17 @@ describe("extractClaims", () => {
expect(claims).toStrictEqual(expected);
});

it("all designated claims from an EmailPass Credential are mapped (constrained)", () => {
var claims = extractClaims(vpEmail, policyEmailFromAltmeConstr);
var expected = {
tokenId: {
email: "felix.hoops@tum.de",
},
tokenAccess: {},
};
expect(claims).toStrictEqual(expected);
});

it("all designated claims from an EmployeeCredential are extracted", () => {
var claims = extractClaims(vpEmployee, policyEmployeeFromAnyone);
var expected = {
Expand Down
2 changes: 1 addition & 1 deletion vclogin/__tests__/testdata/policies/acceptAnything.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"credentialID": "credential1",
"credentialId": "credential1",
"patterns": [
{
"issuer": "*",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"credentialID": "one",
"credentialId": "one",
"patterns": [
{
"issuer": "did:web:app.altme.io:issuer",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[
{
"credentialId": "one",
"patterns": [
{
"issuer": "did:web:app.altme.io:issuer",
"claims": [
{
"claimPath": "$.credentialSubject.email",
"token": "id_token"
}
],
"constraint": {
"op": "equalsDID",
"a": "$VP.proof.verificationMethod",
"b": "$.credentialSubject.id"
}
}
]
}
]
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"credentialID": "one",
"credentialId": "one",
"patterns": [
{
"issuer": "*",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
[
{
"credentialId": "one",
"patterns": [
{
"issuer": "*",
"claims": [
{
"claimPath": "$.credentialSubject.hasLegallyBindingName",
"newPath": "$.companyName"
},
{
"claimPath": "$.credentialSubject.name",
"token": "id_token"
},
{
"claimPath": "$.credentialSubject.email",
"token": "id_token"
}
],
"constraint": {
"op": "and",
"a": {
"op": "equalsDID",
"a": "$VP.proof.verificationMethod",
"b": "$.credentialSubject.id"
},
"b": {
"op": "and",
"a": {
"op": "endsWith",
"a": "$.credentialSubject.email",
"b": "@test.com"
},
"b": {
"op": "or",
"a": {
"op": "matches",
"a": "$.credentialSubject.title",
"b": "C[EOT]O"
},
"b": {
"op": "equals",
"a": "$.credentialSubject.hasJurisdiction",
"b": "GER"
}
}
}
}
}
]
}
]
2 changes: 1 addition & 1 deletion vclogin/__tests__/testdata/policies/acceptFromAltme.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"credentialID": "one",
"credentialId": "one",
"patterns": [
{
"issuer": "did:web:app.altme.io:issuer",
Expand Down
89 changes: 0 additions & 89 deletions vclogin/lib/evaluateLoginPolicy.ts

This file was deleted.

Loading

0 comments on commit 286af54

Please sign in to comment.