mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Create WWW-Authenticate metadata writer
This commit is contained in:
parent
b604dd8331
commit
e3c5b39752
@ -41,6 +41,7 @@ module.exports = {
|
|||||||
'@typescript-eslint/no-invalid-void-type': 'off',
|
'@typescript-eslint/no-invalid-void-type': 'off',
|
||||||
// Problems with optional parameters
|
// Problems with optional parameters
|
||||||
'@typescript-eslint/no-unnecessary-condition': 'off',
|
'@typescript-eslint/no-unnecessary-condition': 'off',
|
||||||
|
'@typescript-eslint/prefer-optional-chain': 'error',
|
||||||
'@typescript-eslint/space-before-function-paren': [ 'error', 'never' ],
|
'@typescript-eslint/space-before-function-paren': [ 'error', 'never' ],
|
||||||
'@typescript-eslint/unbound-method': 'off',
|
'@typescript-eslint/unbound-method': 'off',
|
||||||
'@typescript-eslint/unified-signatures': 'off',
|
'@typescript-eslint/unified-signatures': 'off',
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
"files-scs:config/ldp/metadata-writer/writers/constant.json",
|
"files-scs:config/ldp/metadata-writer/writers/constant.json",
|
||||||
"files-scs:config/ldp/metadata-writer/writers/link-rel.json",
|
"files-scs:config/ldp/metadata-writer/writers/link-rel.json",
|
||||||
"files-scs:config/ldp/metadata-writer/writers/mapped.json",
|
"files-scs:config/ldp/metadata-writer/writers/mapped.json",
|
||||||
"files-scs:config/ldp/metadata-writer/writers/wac-allow.json"
|
"files-scs:config/ldp/metadata-writer/writers/wac-allow.json",
|
||||||
|
"files-scs:config/ldp/metadata-writer/writers/www-auth.json"
|
||||||
],
|
],
|
||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
@ -15,7 +16,8 @@
|
|||||||
{ "@id": "urn:solid-server:default:MetadataWriter_Constant" },
|
{ "@id": "urn:solid-server:default:MetadataWriter_Constant" },
|
||||||
{ "@id": "urn:solid-server:default:MetadataWriter_Mapped" },
|
{ "@id": "urn:solid-server:default:MetadataWriter_Mapped" },
|
||||||
{ "@id": "urn:solid-server:default:MetadataWriter_LinkRel" },
|
{ "@id": "urn:solid-server:default:MetadataWriter_LinkRel" },
|
||||||
{ "@id": "urn:solid-server:default:MetadataWriter_WacAllow" }
|
{ "@id": "urn:solid-server:default:MetadataWriter_WacAllow" },
|
||||||
|
{ "@id": "urn:solid-server:default:MetadataWriter_WwwAuth" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
11
config/ldp/metadata-writer/writers/www-auth.json
Normal file
11
config/ldp/metadata-writer/writers/www-auth.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^0.0.0/components/context.jsonld",
|
||||||
|
"@graph": [
|
||||||
|
{
|
||||||
|
"comment": "Adds the WWW-Authenticate header on 401 responses. The current auth value is required for the legacy solid-auth-client.",
|
||||||
|
"@id": "urn:solid-server:default:MetadataWriter_WwwAuth",
|
||||||
|
"@type": "WwwAuthMetadataWriter",
|
||||||
|
"auth": "Bearer scope=\"openid webid\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -97,6 +97,7 @@ export * from './ldp/http/metadata/MetadataParser';
|
|||||||
export * from './ldp/http/metadata/MetadataWriter';
|
export * from './ldp/http/metadata/MetadataWriter';
|
||||||
export * from './ldp/http/metadata/SlugParser';
|
export * from './ldp/http/metadata/SlugParser';
|
||||||
export * from './ldp/http/metadata/WacAllowMetadataWriter';
|
export * from './ldp/http/metadata/WacAllowMetadataWriter';
|
||||||
|
export * from './ldp/http/metadata/WwwAuthMetadataWriter';
|
||||||
|
|
||||||
// LDP/HTTP/Response
|
// LDP/HTTP/Response
|
||||||
export * from './ldp/http/response/CreatedResponseDescription';
|
export * from './ldp/http/response/CreatedResponseDescription';
|
||||||
|
24
src/ldp/http/metadata/WwwAuthMetadataWriter.ts
Normal file
24
src/ldp/http/metadata/WwwAuthMetadataWriter.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import type { HttpResponse } from '../../../server/HttpResponse';
|
||||||
|
import { addHeader } from '../../../util/HeaderUtil';
|
||||||
|
import { HTTP } from '../../../util/Vocabularies';
|
||||||
|
import type { RepresentationMetadata } from '../../representation/RepresentationMetadata';
|
||||||
|
import { MetadataWriter } from './MetadataWriter';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the `WWW-Authenticate` header with the injected value in case the response status code is 401.
|
||||||
|
*/
|
||||||
|
export class WwwAuthMetadataWriter extends MetadataWriter {
|
||||||
|
private readonly auth: string;
|
||||||
|
|
||||||
|
public constructor(auth: string) {
|
||||||
|
super();
|
||||||
|
this.auth = auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async handle(input: { response: HttpResponse; metadata: RepresentationMetadata }): Promise<void> {
|
||||||
|
const statusLiteral = input.metadata.get(HTTP.terms.statusCodeNumber);
|
||||||
|
if (statusLiteral?.value === '401') {
|
||||||
|
addHeader(input.response, 'WWW-Authenticate', this.auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -188,4 +188,16 @@ describe.each(stores)('An LDP handler with auth using %s', (name, { storeConfig,
|
|||||||
// Close response
|
// Close response
|
||||||
await response.text();
|
await response.text();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns the legacy WWW-Authenticate header on 401 requests.', async(): Promise<void> => {
|
||||||
|
await aclHelper.setSimpleAcl(baseUrl, {
|
||||||
|
permissions: {},
|
||||||
|
agentClass: 'agent',
|
||||||
|
accessTo: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await fetch(`${baseUrl}.acl`);
|
||||||
|
expect(response.status).toBe(401);
|
||||||
|
expect(response.headers.get('www-authenticate')).toBe('Bearer scope="openid webid"');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,7 @@ import { RepresentationMetadata } from '../../../../../src/ldp/representation/Re
|
|||||||
import type { HttpResponse } from '../../../../../src/server/HttpResponse';
|
import type { HttpResponse } from '../../../../../src/server/HttpResponse';
|
||||||
import { ACL, AUTH } from '../../../../../src/util/Vocabularies';
|
import { ACL, AUTH } from '../../../../../src/util/Vocabularies';
|
||||||
|
|
||||||
describe('WacAllowMetadataWriter', (): void => {
|
describe('A WacAllowMetadataWriter', (): void => {
|
||||||
const writer = new WacAllowMetadataWriter();
|
const writer = new WacAllowMetadataWriter();
|
||||||
let response: HttpResponse;
|
let response: HttpResponse;
|
||||||
|
|
||||||
|
36
test/unit/ldp/http/metadata/WwwAuthMetadataWriter.test.ts
Normal file
36
test/unit/ldp/http/metadata/WwwAuthMetadataWriter.test.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { createResponse } from 'node-mocks-http';
|
||||||
|
import { WwwAuthMetadataWriter } from '../../../../../src/ldp/http/metadata/WwwAuthMetadataWriter';
|
||||||
|
import { RepresentationMetadata } from '../../../../../src/ldp/representation/RepresentationMetadata';
|
||||||
|
import type { HttpResponse } from '../../../../../src/server/HttpResponse';
|
||||||
|
import { HTTP } from '../../../../../src/util/Vocabularies';
|
||||||
|
|
||||||
|
describe('A WwwAuthMetadataWriter', (): void => {
|
||||||
|
const auth = 'Bearer scope="openid webid"';
|
||||||
|
const writer = new WwwAuthMetadataWriter(auth);
|
||||||
|
let response: HttpResponse;
|
||||||
|
|
||||||
|
beforeEach(async(): Promise<void> => {
|
||||||
|
response = createResponse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds no header if there is no relevant metadata.', async(): Promise<void> => {
|
||||||
|
const metadata = new RepresentationMetadata();
|
||||||
|
await expect(writer.handle({ response, metadata })).resolves.toBeUndefined();
|
||||||
|
expect(response.getHeaders()).toEqual({ });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds no header if the status code is not 401.', async(): Promise<void> => {
|
||||||
|
const metadata = new RepresentationMetadata({ [HTTP.statusCodeNumber]: '403' });
|
||||||
|
await expect(writer.handle({ response, metadata })).resolves.toBeUndefined();
|
||||||
|
expect(response.getHeaders()).toEqual({ });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds a WWW-Authenticate header if the status code is 401.', async(): Promise<void> => {
|
||||||
|
const metadata = new RepresentationMetadata({ [HTTP.statusCodeNumber]: '401' });
|
||||||
|
await expect(writer.handle({ response, metadata })).resolves.toBeUndefined();
|
||||||
|
|
||||||
|
expect(response.getHeaders()).toEqual({
|
||||||
|
'www-authenticate': auth,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user