mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Let Authorizers output an Authorization
This commit is contained in:
parent
8ccc68d29c
commit
f2f265c586
@ -1,10 +1,19 @@
|
|||||||
|
import type { PermissionSet } from '../ldp/permissions/PermissionSet';
|
||||||
import { Authorizer } from './Authorizer';
|
import { Authorizer } from './Authorizer';
|
||||||
|
import { WebAclAuthorization } from './WebAclAuthorization';
|
||||||
|
|
||||||
|
const allowEverything: PermissionSet = {
|
||||||
|
read: true,
|
||||||
|
write: true,
|
||||||
|
append: true,
|
||||||
|
control: true,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorizer which allows all access independent of the identifier and requested permissions.
|
* Authorizer which allows all access independent of the identifier and requested permissions.
|
||||||
*/
|
*/
|
||||||
export class AllowEverythingAuthorizer extends Authorizer {
|
export class AllowEverythingAuthorizer extends Authorizer {
|
||||||
public async handle(): Promise<void> {
|
public async handle(): Promise<WebAclAuthorization> {
|
||||||
// Allows all actions
|
return new WebAclAuthorization(allowEverything, allowEverything);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
src/authorization/Authorization.ts
Normal file
12
src/authorization/Authorization.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { RepresentationMetadata } from '../ldp/representation/RepresentationMetadata';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The output of an Authorizer
|
||||||
|
*/
|
||||||
|
export interface Authorization {
|
||||||
|
/**
|
||||||
|
* Add metadata relevant for this Authorization.
|
||||||
|
* @param metadata - Metadata to update.
|
||||||
|
*/
|
||||||
|
addMetadata: (metadata: RepresentationMetadata) => void;
|
||||||
|
}
|
@ -2,12 +2,13 @@ import type { Credentials } from '../authentication/Credentials';
|
|||||||
import type { PermissionSet } from '../ldp/permissions/PermissionSet';
|
import type { PermissionSet } from '../ldp/permissions/PermissionSet';
|
||||||
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||||
import { AsyncHandler } from '../util/handlers/AsyncHandler';
|
import { AsyncHandler } from '../util/handlers/AsyncHandler';
|
||||||
|
import type { Authorization } from './Authorization';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies if the given credentials have access to the given permissions on the given resource.
|
* Verifies if the given credentials have access to the given permissions on the given resource.
|
||||||
* An {@link Error} with the necessary explanation will be thrown when permissions are not granted.
|
* An {@link Error} with the necessary explanation will be thrown when permissions are not granted.
|
||||||
*/
|
*/
|
||||||
export abstract class Authorizer extends AsyncHandler<AuthorizerArgs> {}
|
export abstract class Authorizer extends AsyncHandler<AuthorizerArgs, Authorization> {}
|
||||||
|
|
||||||
export interface AuthorizerArgs {
|
export interface AuthorizerArgs {
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import type { AuxiliaryIdentifierStrategy } from '../ldp/auxiliary/AuxiliaryIdentifierStrategy';
|
import type { AuxiliaryIdentifierStrategy } from '../ldp/auxiliary/AuxiliaryIdentifierStrategy';
|
||||||
import { getLoggerFor } from '../logging/LogUtil';
|
import { getLoggerFor } from '../logging/LogUtil';
|
||||||
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
|
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
|
||||||
|
import type { Authorization } from './Authorization';
|
||||||
import type { AuthorizerArgs } from './Authorizer';
|
import type { AuthorizerArgs } from './Authorizer';
|
||||||
import { Authorizer } from './Authorizer';
|
import { Authorizer } from './Authorizer';
|
||||||
|
|
||||||
@ -26,13 +27,13 @@ export class AuxiliaryAuthorizer extends Authorizer {
|
|||||||
return this.resourceAuthorizer.canHandle(resourceAuth);
|
return this.resourceAuthorizer.canHandle(resourceAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handle(auxiliaryAuth: AuthorizerArgs): Promise<void> {
|
public async handle(auxiliaryAuth: AuthorizerArgs): Promise<Authorization> {
|
||||||
const resourceAuth = this.getRequiredAuthorization(auxiliaryAuth);
|
const resourceAuth = this.getRequiredAuthorization(auxiliaryAuth);
|
||||||
this.logger.debug(`Checking auth request for ${auxiliaryAuth.identifier.path} on ${resourceAuth.identifier.path}`);
|
this.logger.debug(`Checking auth request for ${auxiliaryAuth.identifier.path} on ${resourceAuth.identifier.path}`);
|
||||||
return this.resourceAuthorizer.handle(resourceAuth);
|
return this.resourceAuthorizer.handle(resourceAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handleSafe(auxiliaryAuth: AuthorizerArgs): Promise<void> {
|
public async handleSafe(auxiliaryAuth: AuthorizerArgs): Promise<Authorization> {
|
||||||
const resourceAuth = this.getRequiredAuthorization(auxiliaryAuth);
|
const resourceAuth = this.getRequiredAuthorization(auxiliaryAuth);
|
||||||
this.logger.debug(`Checking auth request for ${auxiliaryAuth.identifier.path} to ${resourceAuth.identifier.path}`);
|
this.logger.debug(`Checking auth request for ${auxiliaryAuth.identifier.path} to ${resourceAuth.identifier.path}`);
|
||||||
return this.resourceAuthorizer.handleSafe(resourceAuth);
|
return this.resourceAuthorizer.handleSafe(resourceAuth);
|
||||||
|
35
src/authorization/WebAclAuthorization.ts
Normal file
35
src/authorization/WebAclAuthorization.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import type { PermissionSet } from '../ldp/permissions/PermissionSet';
|
||||||
|
import type { RepresentationMetadata } from '../ldp/representation/RepresentationMetadata';
|
||||||
|
import { ACL, AUTH } from '../util/Vocabularies';
|
||||||
|
import type { Authorization } from './Authorization';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates which permissions are available on the requested resource.
|
||||||
|
*/
|
||||||
|
export class WebAclAuthorization implements Authorization {
|
||||||
|
/**
|
||||||
|
* Permissions granted to the agent requesting the resource.
|
||||||
|
*/
|
||||||
|
public user: PermissionSet;
|
||||||
|
/**
|
||||||
|
* Permissions granted to the public.
|
||||||
|
*/
|
||||||
|
public everyone: PermissionSet;
|
||||||
|
|
||||||
|
public constructor(user: PermissionSet, everyone: PermissionSet) {
|
||||||
|
this.user = user;
|
||||||
|
this.everyone = everyone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addMetadata(metadata: RepresentationMetadata): void {
|
||||||
|
for (const mode of (Object.keys(this.user) as (keyof PermissionSet)[])) {
|
||||||
|
const capitalizedMode = mode.charAt(0).toUpperCase() + mode.slice(1) as 'Read' | 'Write' | 'Append' | 'Control';
|
||||||
|
if (this.user[mode]) {
|
||||||
|
metadata.add(AUTH.terms.userMode, ACL.terms[capitalizedMode]);
|
||||||
|
}
|
||||||
|
if (this.everyone[mode]) {
|
||||||
|
metadata.add(AUTH.terms.publicMode, ACL.terms[capitalizedMode]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ import type { IdentifierStrategy } from '../util/identifiers/IdentifierStrategy'
|
|||||||
import { ACL, FOAF } from '../util/Vocabularies';
|
import { ACL, FOAF } from '../util/Vocabularies';
|
||||||
import type { AuthorizerArgs } from './Authorizer';
|
import type { AuthorizerArgs } from './Authorizer';
|
||||||
import { Authorizer } from './Authorizer';
|
import { Authorizer } from './Authorizer';
|
||||||
|
import { WebAclAuthorization } from './WebAclAuthorization';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles most web access control predicates such as
|
* Handles most web access control predicates such as
|
||||||
@ -48,36 +49,60 @@ export class WebAclAuthorizer extends Authorizer {
|
|||||||
* Will throw an error if this is not the case.
|
* Will throw an error if this is not the case.
|
||||||
* @param input - Relevant data needed to check if access can be granted.
|
* @param input - Relevant data needed to check if access can be granted.
|
||||||
*/
|
*/
|
||||||
public async handle({ identifier, permissions, credentials }: AuthorizerArgs): Promise<void> {
|
public async handle({ identifier, permissions, credentials }: AuthorizerArgs): Promise<WebAclAuthorization> {
|
||||||
const modes = (Object.keys(permissions) as (keyof PermissionSet)[]).filter((key): boolean => permissions[key]);
|
const modes = (Object.keys(permissions) as (keyof PermissionSet)[]).filter((key): boolean => permissions[key]);
|
||||||
|
|
||||||
// Verify that all required modes are set for the given agent
|
// Verify that all required modes are set for the given agent
|
||||||
this.logger.debug(`Checking if ${credentials.webId} has ${modes.join()} permissions for ${identifier.path}`);
|
this.logger.debug(`Checking if ${credentials.webId} has ${modes.join()} permissions for ${identifier.path}`);
|
||||||
const store = await this.getAclRecursive(identifier);
|
const store = await this.getAclRecursive(identifier);
|
||||||
|
const authorization = this.createAuthorization(credentials, store);
|
||||||
for (const mode of modes) {
|
for (const mode of modes) {
|
||||||
this.checkPermission(credentials, store, mode);
|
this.checkPermission(credentials, authorization, mode);
|
||||||
}
|
}
|
||||||
this.logger.debug(`${credentials.webId} has ${modes.join()} permissions for ${identifier.path}`);
|
this.logger.debug(`${credentials.webId} has ${modes.join()} permissions for ${identifier.path}`);
|
||||||
|
return authorization;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if any of the triples in the store grant the agent permission to use the given mode.
|
* Creates an Authorization object based on the quads found in the store.
|
||||||
|
* @param agent - Agent who's credentials will be used for the `user` field.
|
||||||
|
* @param store - Store containing all relevant authorization triples.
|
||||||
|
*/
|
||||||
|
private createAuthorization(agent: Credentials, store: Store): WebAclAuthorization {
|
||||||
|
const publicPermissions = this.createPermissions({}, store);
|
||||||
|
const userPermissions = this.createPermissions(agent, store);
|
||||||
|
|
||||||
|
return new WebAclAuthorization(userPermissions, publicPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the authorization permissions for the given credentials.
|
||||||
|
* @param credentials - Credentials to find the permissions for.
|
||||||
|
* @param store - Store containing all relevant authorization triples.
|
||||||
|
*/
|
||||||
|
private createPermissions(credentials: Credentials, store: Store): PermissionSet {
|
||||||
|
const permissions: PermissionSet = {
|
||||||
|
read: false,
|
||||||
|
write: false,
|
||||||
|
append: false,
|
||||||
|
control: false,
|
||||||
|
};
|
||||||
|
for (const mode of (Object.keys(permissions) as (keyof PermissionSet)[])) {
|
||||||
|
permissions[mode] = this.hasPermission(credentials, store, mode);
|
||||||
|
}
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the authorization grants the agent permission to use the given mode.
|
||||||
* Throws a {@link ForbiddenHttpError} or {@link UnauthorizedHttpError} depending on the credentials
|
* Throws a {@link ForbiddenHttpError} or {@link UnauthorizedHttpError} depending on the credentials
|
||||||
* if access is not allowed.
|
* if access is not allowed.
|
||||||
* @param agent - Agent that wants access.
|
* @param agent - Agent that wants access.
|
||||||
* @param store - A store containing the relevant triples for authorization.
|
* @param authorization - An Authorization containing the permissions the agent has on the resource.
|
||||||
* @param mode - Which mode is requested. Probable one of ('write' | 'read' | 'append' | 'control').
|
* @param mode - Which mode is requested.
|
||||||
*/
|
*/
|
||||||
private checkPermission(agent: Credentials, store: Store, mode: string): void {
|
private checkPermission(agent: Credentials, authorization: WebAclAuthorization, mode: keyof PermissionSet): void {
|
||||||
const modeString = ACL[this.capitalize(mode) as 'Write' | 'Read' | 'Append' | 'Control'];
|
if (!authorization.user[mode]) {
|
||||||
const auths = this.getModePermissions(store, modeString);
|
|
||||||
|
|
||||||
// Having write permissions implies having append permissions
|
|
||||||
if (modeString === ACL.Append) {
|
|
||||||
auths.push(...this.getModePermissions(store, ACL.Write));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!auths.some((term): boolean => this.hasAccess(agent, term, store))) {
|
|
||||||
const isLoggedIn = typeof agent.webId === 'string';
|
const isLoggedIn = typeof agent.webId === 'string';
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
this.logger.warn(`Agent ${agent.webId} has no ${mode} permissions`);
|
this.logger.warn(`Agent ${agent.webId} has no ${mode} permissions`);
|
||||||
@ -92,6 +117,24 @@ export class WebAclAuthorizer extends Authorizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given agent has permission to execute the given mode based on the triples in the store.
|
||||||
|
* @param agent - Agent that wants access.
|
||||||
|
* @param store - A store containing the relevant triples for authorization.
|
||||||
|
* @param mode - Which mode is requested.
|
||||||
|
*/
|
||||||
|
private hasPermission(agent: Credentials, store: Store, mode: keyof PermissionSet): boolean {
|
||||||
|
const modeString = ACL[this.capitalize(mode) as 'Write' | 'Read' | 'Append' | 'Control'];
|
||||||
|
const auths = this.getModePermissions(store, modeString);
|
||||||
|
|
||||||
|
// Having write permissions implies having append permissions
|
||||||
|
if (modeString === ACL.Append) {
|
||||||
|
auths.push(...this.getModePermissions(store, ACL.Write));
|
||||||
|
}
|
||||||
|
|
||||||
|
return auths.some((term): boolean => this.hasAccess(agent, term, store));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capitalizes the input string.
|
* Capitalizes the input string.
|
||||||
* @param mode - String to transform.
|
* @param mode - String to transform.
|
||||||
|
@ -9,8 +9,10 @@ export * from './authentication/UnsecureWebIdExtractor';
|
|||||||
|
|
||||||
// Authorization
|
// Authorization
|
||||||
export * from './authorization/AllowEverythingAuthorizer';
|
export * from './authorization/AllowEverythingAuthorizer';
|
||||||
|
export * from './authorization/Authorization';
|
||||||
export * from './authorization/Authorizer';
|
export * from './authorization/Authorizer';
|
||||||
export * from './authorization/AuxiliaryAuthorizer';
|
export * from './authorization/AuxiliaryAuthorizer';
|
||||||
|
export * from './authorization/WebAclAuthorization';
|
||||||
export * from './authorization/WebAclAuthorizer';
|
export * from './authorization/WebAclAuthorizer';
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
|
@ -68,6 +68,11 @@ export const ACL = createUriAndTermNamespace('http://www.w3.org/ns/auth/acl#',
|
|||||||
'Control',
|
'Control',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const AUTH = createUriAndTermNamespace('urn:solid:auth:',
|
||||||
|
'userMode',
|
||||||
|
'publicMode',
|
||||||
|
);
|
||||||
|
|
||||||
export const DC = createUriAndTermNamespace('http://purl.org/dc/terms/',
|
export const DC = createUriAndTermNamespace('http://purl.org/dc/terms/',
|
||||||
'modified',
|
'modified',
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,23 @@
|
|||||||
import { AllowEverythingAuthorizer } from '../../../src/authorization/AllowEverythingAuthorizer';
|
import { AllowEverythingAuthorizer } from '../../../src/authorization/AllowEverythingAuthorizer';
|
||||||
|
import type { PermissionSet } from '../../../src/ldp/permissions/PermissionSet';
|
||||||
|
|
||||||
describe('An AllowEverythingAuthorizer', (): void => {
|
describe('An AllowEverythingAuthorizer', (): void => {
|
||||||
const authorizer = new AllowEverythingAuthorizer();
|
const authorizer = new AllowEverythingAuthorizer();
|
||||||
|
const allowEverything: PermissionSet = {
|
||||||
|
read: true,
|
||||||
|
write: true,
|
||||||
|
append: true,
|
||||||
|
control: true,
|
||||||
|
};
|
||||||
|
|
||||||
it('can handle everything.', async(): Promise<void> => {
|
it('can handle everything.', async(): Promise<void> => {
|
||||||
await expect(authorizer.canHandle({} as any)).resolves.toBeUndefined();
|
await expect(authorizer.canHandle({} as any)).resolves.toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('always returns undefined.', async(): Promise<void> => {
|
it('always returns an empty Authorization.', async(): Promise<void> => {
|
||||||
await expect(authorizer.handle()).resolves.toBeUndefined();
|
await expect(authorizer.handle()).resolves.toEqual({
|
||||||
|
user: allowEverything,
|
||||||
|
everyone: allowEverything,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
43
test/unit/authorization/WebAclAuthorization.test.ts
Normal file
43
test/unit/authorization/WebAclAuthorization.test.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { WebAclAuthorization } from '../../../src/authorization/WebAclAuthorization';
|
||||||
|
import { RepresentationMetadata } from '../../../src/ldp/representation/RepresentationMetadata';
|
||||||
|
import { ACL, AUTH } from '../../../src/util/Vocabularies';
|
||||||
|
import 'jest-rdf';
|
||||||
|
|
||||||
|
describe('A WebAclAuthorization', (): void => {
|
||||||
|
let authorization: WebAclAuthorization;
|
||||||
|
let metadata: RepresentationMetadata;
|
||||||
|
|
||||||
|
beforeEach(async(): Promise<void> => {
|
||||||
|
authorization = new WebAclAuthorization(
|
||||||
|
{
|
||||||
|
read: false,
|
||||||
|
append: false,
|
||||||
|
write: false,
|
||||||
|
control: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
read: false,
|
||||||
|
append: false,
|
||||||
|
write: false,
|
||||||
|
control: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
metadata = new RepresentationMetadata();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds no metadata if there are no permissions.', async(): Promise<void> => {
|
||||||
|
expect(authorization.addMetadata(metadata)).toBeUndefined();
|
||||||
|
expect(metadata.quads()).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds corresponding acl metadata for all permissions present.', async(): Promise<void> => {
|
||||||
|
authorization.user.read = true;
|
||||||
|
authorization.user.write = true;
|
||||||
|
authorization.everyone.read = true;
|
||||||
|
expect(authorization.addMetadata(metadata)).toBeUndefined();
|
||||||
|
expect(metadata.quads()).toHaveLength(3);
|
||||||
|
expect(metadata.getAll(AUTH.terms.userMode)).toEqualRdfTermArray([ ACL.terms.Read, ACL.terms.Write ]);
|
||||||
|
expect(metadata.get(AUTH.terms.publicMode)).toEqualRdfTerm(ACL.terms.Read);
|
||||||
|
});
|
||||||
|
});
|
@ -1,5 +1,6 @@
|
|||||||
import { namedNode, quad } from '@rdfjs/data-model';
|
import { namedNode, quad } from '@rdfjs/data-model';
|
||||||
import type { Credentials } from '../../../src/authentication/Credentials';
|
import type { Credentials } from '../../../src/authentication/Credentials';
|
||||||
|
import { WebAclAuthorization } from '../../../src/authorization/WebAclAuthorization';
|
||||||
import { WebAclAuthorizer } from '../../../src/authorization/WebAclAuthorizer';
|
import { WebAclAuthorizer } from '../../../src/authorization/WebAclAuthorizer';
|
||||||
import type { AuxiliaryIdentifierStrategy } from '../../../src/ldp/auxiliary/AuxiliaryIdentifierStrategy';
|
import type { AuxiliaryIdentifierStrategy } from '../../../src/ldp/auxiliary/AuxiliaryIdentifierStrategy';
|
||||||
import type { PermissionSet } from '../../../src/ldp/permissions/PermissionSet';
|
import type { PermissionSet } from '../../../src/ldp/permissions/PermissionSet';
|
||||||
@ -29,6 +30,7 @@ describe('A WebAclAuthorizer', (): void => {
|
|||||||
let permissions: PermissionSet;
|
let permissions: PermissionSet;
|
||||||
let credentials: Credentials;
|
let credentials: Credentials;
|
||||||
let identifier: ResourceIdentifier;
|
let identifier: ResourceIdentifier;
|
||||||
|
let authorization: WebAclAuthorization;
|
||||||
|
|
||||||
beforeEach(async(): Promise<void> => {
|
beforeEach(async(): Promise<void> => {
|
||||||
permissions = {
|
permissions = {
|
||||||
@ -39,6 +41,20 @@ describe('A WebAclAuthorizer', (): void => {
|
|||||||
};
|
};
|
||||||
credentials = {};
|
credentials = {};
|
||||||
identifier = { path: 'http://test.com/foo' };
|
identifier = { path: 'http://test.com/foo' };
|
||||||
|
authorization = new WebAclAuthorization(
|
||||||
|
{
|
||||||
|
read: false,
|
||||||
|
append: false,
|
||||||
|
write: false,
|
||||||
|
control: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
read: false,
|
||||||
|
append: false,
|
||||||
|
write: false,
|
||||||
|
control: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
store = {
|
store = {
|
||||||
getRepresentation: jest.fn(),
|
getRepresentation: jest.fn(),
|
||||||
@ -60,7 +76,9 @@ describe('A WebAclAuthorizer', (): void => {
|
|||||||
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Read`)),
|
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Read`)),
|
||||||
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Write`)),
|
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Write`)),
|
||||||
]) } as Representation);
|
]) } as Representation);
|
||||||
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toBeUndefined();
|
Object.assign(authorization.everyone, { read: true, write: true, append: true });
|
||||||
|
Object.assign(authorization.user, { read: true, write: true, append: true });
|
||||||
|
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toEqual(authorization);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows access if there is a parent acl file allowing all agents.', async(): Promise<void> => {
|
it('allows access if there is a parent acl file allowing all agents.', async(): Promise<void> => {
|
||||||
@ -77,7 +95,9 @@ describe('A WebAclAuthorizer', (): void => {
|
|||||||
]),
|
]),
|
||||||
} as Representation;
|
} as Representation;
|
||||||
};
|
};
|
||||||
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toBeUndefined();
|
Object.assign(authorization.everyone, { read: true, write: true, append: true });
|
||||||
|
Object.assign(authorization.user, { read: true, write: true, append: true });
|
||||||
|
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toEqual(authorization);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows access to authorized agents if the acl files allows all authorized users.', async(): Promise<void> => {
|
it('allows access to authorized agents if the acl files allows all authorized users.', async(): Promise<void> => {
|
||||||
@ -88,7 +108,8 @@ describe('A WebAclAuthorizer', (): void => {
|
|||||||
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Write`)),
|
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Write`)),
|
||||||
]) } as Representation);
|
]) } as Representation);
|
||||||
credentials.webId = 'http://test.com/user';
|
credentials.webId = 'http://test.com/user';
|
||||||
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toBeUndefined();
|
Object.assign(authorization.user, { read: true, write: true, append: true });
|
||||||
|
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toEqual(authorization);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('errors if authorization is required but the agent is not authorized.', async(): Promise<void> => {
|
it('errors if authorization is required but the agent is not authorized.', async(): Promise<void> => {
|
||||||
@ -109,7 +130,8 @@ describe('A WebAclAuthorizer', (): void => {
|
|||||||
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Read`)),
|
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Read`)),
|
||||||
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Write`)),
|
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Write`)),
|
||||||
]) } as Representation);
|
]) } as Representation);
|
||||||
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toBeUndefined();
|
Object.assign(authorization.user, { read: true, write: true, append: true });
|
||||||
|
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toEqual(authorization);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('errors if a specific agents wants to access files not assigned to them.', async(): Promise<void> => {
|
it('errors if a specific agents wants to access files not assigned to them.', async(): Promise<void> => {
|
||||||
@ -153,6 +175,7 @@ describe('A WebAclAuthorizer', (): void => {
|
|||||||
quad(nn('auth'), nn(`${acl}accessTo`), nn(identifier.path)),
|
quad(nn('auth'), nn(`${acl}accessTo`), nn(identifier.path)),
|
||||||
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Write`)),
|
quad(nn('auth'), nn(`${acl}mode`), nn(`${acl}Write`)),
|
||||||
]) } as Representation);
|
]) } as Representation);
|
||||||
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toBeUndefined();
|
Object.assign(authorization.user, { write: true, append: true });
|
||||||
|
await expect(authorizer.handle({ identifier, permissions, credentials })).resolves.toEqual(authorization);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -70,7 +70,7 @@ describe('An AuthenticatedLdpHandler', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('errors an invalid object was thrown by a handler.', async(): Promise< void> => {
|
it('errors an invalid object was thrown by a handler.', async(): Promise< void> => {
|
||||||
args.authorizer.handle = async(): Promise<void> => {
|
args.authorizer.handle = async(): Promise<any> => {
|
||||||
throw 'apple';
|
throw 'apple';
|
||||||
};
|
};
|
||||||
const handler = new AuthenticatedLdpHandler(args);
|
const handler = new AuthenticatedLdpHandler(args);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user