Skip to content

Commit 175c36a

Browse files
committed
test: Add policy integration tests
1 parent 67f35ee commit 175c36a

6 files changed

Lines changed: 406 additions & 84 deletions

File tree

packages/ucp/src/util/Vocabularies.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export const ODRL = createVocabulary(
136136
'gt',
137137
'lt',
138138
'eq',
139+
'uid',
139140
);
140141

141142
export const ODRL_P = createVocabulary(

packages/uma/src/util/routeSpecific/middlewareUtil.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BadRequestHttpError } from "@solid/community-server";
1+
import { BadRequestHttpError, UnauthorizedHttpError } from '@solid/community-server';
22
import { HttpHandlerRequest } from "../http/models/HttpHandler";
33

44
/**
@@ -11,5 +11,5 @@ import { HttpHandlerRequest } from "../http/models/HttpHandler";
1111
export const verifyHttpCredentials = (request: HttpHandlerRequest): string => {
1212
if (typeof request.headers['authorization'] === 'string')
1313
return request.headers['authorization'];
14-
else throw new BadRequestHttpError('Missing Authorization header');
14+
else throw new UnauthorizedHttpError('Missing Authorization header');
1515
}

test/integration/Demo.test.ts

Lines changed: 1 addition & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { DialogOutput } from '@solidlab/uma';
33
import { Parser, Store } from 'n3';
44
import * as path from 'node:path';
55
import { getDefaultCssVariables, getPorts, instantiateFromConfig } from '../util/ServerUtil';
6+
import { findTokenEndpoint, getToken, noTokenFetch, tokenFetch, umaFetch } from '../util/UmaUtil';
67

78
const [ cssPort, umaPort ] = getPorts('Demo');
89

@@ -19,88 +20,6 @@ const terms = {
1920
}
2021
}
2122

22-
async function noTokenFetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<{ as_uri: string, ticket: string }> {
23-
const noTokenResponse = await fetch(input, init);
24-
25-
expect(noTokenResponse.status).toBe(401);
26-
27-
const wwwAuthenticateHeader = noTokenResponse.headers.get('WWW-Authenticate') as string;
28-
expect(typeof wwwAuthenticateHeader).toBe('string');
29-
30-
const parsedHeader = Object.fromEntries(
31-
wwwAuthenticateHeader
32-
.replace(/^UMA /,'')
33-
.split(', ')
34-
.map(param => param.split('=').map(s => s.replace(/"/g,'')))
35-
);
36-
expect(typeof parsedHeader.as_uri).toBe('string');
37-
expect(typeof parsedHeader.ticket).toBe('string');
38-
return parsedHeader;
39-
}
40-
41-
async function findTokenEndpoint(uri: string): Promise<string> {
42-
// TODO: cache this
43-
const configurationUrl = uri + '/.well-known/uma2-configuration';
44-
const configResponse = await fetch(configurationUrl);
45-
expect(configResponse.status).toBe(200);
46-
const configuration = await configResponse.json();
47-
expect(typeof configuration.token_endpoint).toBe('string');
48-
return configuration.token_endpoint;
49-
}
50-
51-
async function getToken(ticket: string, endpoint: string, webId?: string): Promise<DialogOutput> {
52-
const content: Record<string, string> = {
53-
grant_type: 'urn:ietf:params:oauth:grant-type:uma-ticket',
54-
ticket: ticket,
55-
};
56-
if (webId) {
57-
content.claim_token = encodeURIComponent(webId);
58-
content.claim_token_format = 'urn:solidlab:uma:claims:formats:webid';
59-
}
60-
61-
const response = await fetch(endpoint, {
62-
method: 'POST',
63-
headers: { 'content-type': 'application/json' },
64-
body: JSON.stringify(content),
65-
});
66-
67-
expect(response.status).toBe(200);
68-
expect(response.headers.get('content-type')).toBe('application/json');
69-
const jsonResponse: DialogOutput = await response.json();
70-
71-
expect(typeof jsonResponse.access_token).toBe('string');
72-
expect(jsonResponse.token_type).toBe('Bearer');
73-
const token = JSON.parse(Buffer.from(jsonResponse.access_token.split('.')[1], 'base64').toString());
74-
expect(Array.isArray(token.permissions)).toBe(true);
75-
76-
return jsonResponse;
77-
}
78-
79-
async function tokenFetch(token: any, input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response> {
80-
return fetch(input, {
81-
...init,
82-
headers: {
83-
...init?.headers,
84-
'Authorization': `${token.token_type} ${token.access_token}`
85-
},
86-
});
87-
}
88-
89-
// TODO: only call this function if you know there will be a 401
90-
async function umaFetch(input: string | URL | globalThis.Request, init?: RequestInit, webId?: string): Promise<Response> {
91-
// Parse ticket and UMA server URL from header
92-
const parsedHeader = await noTokenFetch(input, init);
93-
94-
// Find UMA server token endpoint
95-
const tokenEndpoint = await findTokenEndpoint(parsedHeader.as_uri);
96-
97-
// Send ticket request to UMA server and extract token from response
98-
const token = await getToken(parsedHeader.ticket, tokenEndpoint, webId);
99-
100-
// Perform new call with token
101-
return tokenFetch(token, input, init);
102-
}
103-
10423
describe('A demo server setup', (): void => {
10524
let umaApp: App;
10625
let cssApp: App;

0 commit comments

Comments
 (0)