refactor: Restructure source code folder

This way the location of certain classes should make more sense
This commit is contained in:
Joachim Van Herwegen
2021-10-08 10:58:35 +02:00
parent 012d9e0864
commit b3da9c9fcf
280 changed files with 684 additions and 673 deletions

View File

@@ -1,7 +1,7 @@
import type { CredentialGroup } from '../authentication/Credentials';
import type { Permission, PermissionSet } from '../ldp/permissions/Permissions';
import type { PermissionReaderInput } from './PermissionReader';
import { PermissionReader } from './PermissionReader';
import type { Permission, PermissionSet } from './permissions/Permissions';
/**
* PermissionReader which sets all permissions to true or false

View File

@@ -1,7 +1,7 @@
import type { CredentialSet } from '../authentication/Credentials';
import type { AccessMode, PermissionSet } from '../ldp/permissions/Permissions';
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import type { ResourceIdentifier } from '../http/representation/ResourceIdentifier';
import { AsyncHandler } from '../util/handlers/AsyncHandler';
import type { AccessMode, PermissionSet } from './permissions/Permissions';
export interface AuthorizerInput {
/**

View File

@@ -1,10 +1,9 @@
import type { AuxiliaryStrategy } from '../ldp/auxiliary/AuxiliaryStrategy';
import type { PermissionSet } from '../ldp/permissions/Permissions';
import type { AuxiliaryStrategy } from '../http/auxiliary/AuxiliaryStrategy';
import { getLoggerFor } from '../logging/LogUtil';
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
import type { PermissionReaderInput } from './PermissionReader';
import { PermissionReader } from './PermissionReader';
import type { PermissionSet } from './permissions/Permissions';
/**
* A PermissionReader for auxiliary resources such as acl or shape resources.

View File

@@ -1,13 +1,13 @@
import { CredentialGroup } from '../authentication/Credentials';
import type { AuxiliaryIdentifierStrategy } from '../http/auxiliary/AuxiliaryIdentifierStrategy';
import type { AccountSettings, AccountStore } from '../identity/interaction/email-password/storage/AccountStore';
import type { AuxiliaryIdentifierStrategy } from '../ldp/auxiliary/AuxiliaryIdentifierStrategy';
import type { AclPermission } from '../ldp/permissions/AclPermission';
import type { PermissionSet } from '../ldp/permissions/Permissions';
import { getLoggerFor } from '../logging/LogUtil';
import { createErrorMessage } from '../util/errors/ErrorUtil';
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
import type { PermissionReaderInput } from './PermissionReader';
import { PermissionReader } from './PermissionReader';
import type { AclPermission } from './permissions/AclPermission';
import type { PermissionSet } from './permissions/Permissions';
/**
* Allows control access if the request is being made by the owner of the pod containing the resource.

View File

@@ -1,9 +1,9 @@
import type { PermissionSet } from '../ldp/permissions/Permissions';
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
import { ensureTrailingSlash, trimTrailingSlashes } from '../util/PathUtil';
import type { PermissionReaderInput } from './PermissionReader';
import { PermissionReader } from './PermissionReader';
import type { PermissionSet } from './permissions/Permissions';
/**
* Redirects requests to specific PermissionReaders based on their identifier.

View File

@@ -1,10 +1,10 @@
import type { CredentialSet } from '../authentication/Credentials';
import type { AccessMode, PermissionSet } from '../ldp/permissions/Permissions';
import { getLoggerFor } from '../logging/LogUtil';
import { ForbiddenHttpError } from '../util/errors/ForbiddenHttpError';
import { UnauthorizedHttpError } from '../util/errors/UnauthorizedHttpError';
import type { AuthorizerInput } from './Authorizer';
import { Authorizer } from './Authorizer';
import type { AccessMode, PermissionSet } from './permissions/Permissions';
/**
* Authorizer that bases its decision on the output it gets from its PermissionReader.

View File

@@ -1,7 +1,7 @@
import type { CredentialSet } from '../authentication/Credentials';
import type { PermissionSet } from '../ldp/permissions/Permissions';
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import type { ResourceIdentifier } from '../http/representation/ResourceIdentifier';
import { AsyncHandler } from '../util/handlers/AsyncHandler';
import type { PermissionSet } from './permissions/Permissions';
export interface PermissionReaderInput {
/**

View File

@@ -1,7 +1,7 @@
import type { CredentialGroup } from '../authentication/Credentials';
import type { Permission, PermissionSet } from '../ldp/permissions/Permissions';
import { UnionHandler } from '../util/handlers/UnionHandler';
import type { PermissionReader } from './PermissionReader';
import type { Permission, PermissionSet } from './permissions/Permissions';
/**
* Combines the results of multiple PermissionReaders.

View File

@@ -2,13 +2,9 @@ import type { Quad, Term } from 'n3';
import { Store } from 'n3';
import { CredentialGroup } from '../authentication/Credentials';
import type { Credential, CredentialSet } from '../authentication/Credentials';
import type { AuxiliaryIdentifierStrategy } from '../ldp/auxiliary/AuxiliaryIdentifierStrategy';
import { AclMode } from '../ldp/permissions/AclPermission';
import type { AclPermission } from '../ldp/permissions/AclPermission';
import type { PermissionSet } from '../ldp/permissions/Permissions';
import { AccessMode } from '../ldp/permissions/Permissions';
import type { Representation } from '../ldp/representation/Representation';
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import type { AuxiliaryIdentifierStrategy } from '../http/auxiliary/AuxiliaryIdentifierStrategy';
import type { Representation } from '../http/representation/Representation';
import type { ResourceIdentifier } from '../http/representation/ResourceIdentifier';
import { getLoggerFor } from '../logging/LogUtil';
import type { ResourceStore } from '../storage/ResourceStore';
import { INTERNAL_QUADS } from '../util/ContentTypes';
@@ -19,9 +15,13 @@ import { NotFoundHttpError } from '../util/errors/NotFoundHttpError';
import type { IdentifierStrategy } from '../util/identifiers/IdentifierStrategy';
import { readableToQuads } from '../util/StreamUtil';
import { ACL, RDF } from '../util/Vocabularies';
import type { AccessChecker } from './access-checkers/AccessChecker';
import type { AccessChecker } from './access/AccessChecker';
import type { PermissionReaderInput } from './PermissionReader';
import { PermissionReader } from './PermissionReader';
import type { AclPermission } from './permissions/AclPermission';
import { AclMode } from './permissions/AclPermission';
import { AccessMode } from './permissions/Permissions';
import type { PermissionSet } from './permissions/Permissions';
const modesMap: Record<string, keyof AclPermission> = {
[ACL.Read]: AccessMode.read,

View File

@@ -1,6 +1,5 @@
import type { Store, Term } from 'n3';
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier';
import type { RepresentationConverter } from '../../storage/conversion/RepresentationConverter';
import type { ExpiringStorage } from '../../storage/keyvalue/ExpiringStorage';
import { fetchDataset } from '../../util/FetchUtil';

View File

@@ -0,0 +1,10 @@
import type { Permission } from './Permissions';
export enum AclMode {
control = 'control',
}
// Adds a control field to the permissions to specify this WAC-specific value
export type AclPermission = Permission & {
[mode in AclMode]?: boolean;
};

View File

@@ -0,0 +1,37 @@
import type { Operation } from '../../http/Operation';
import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError';
import { ModesExtractor } from './ModesExtractor';
import { AccessMode } from './Permissions';
const READ_METHODS = new Set([ 'GET', 'HEAD' ]);
const WRITE_METHODS = new Set([ 'PUT', 'DELETE' ]);
const APPEND_METHODS = new Set([ 'POST' ]);
const SUPPORTED_METHODS = new Set([ ...READ_METHODS, ...WRITE_METHODS, ...APPEND_METHODS ]);
/**
* Generates permissions for the base set of methods that always require the same permissions.
* Specifically: GET, HEAD, POST, PUT and DELETE.
*/
export class MethodModesExtractor extends ModesExtractor {
public async canHandle({ method }: Operation): Promise<void> {
if (!SUPPORTED_METHODS.has(method)) {
throw new NotImplementedHttpError(`Cannot determine permissions of ${method}`);
}
}
public async handle({ method }: Operation): Promise<Set<AccessMode>> {
const result = new Set<AccessMode>();
if (READ_METHODS.has(method)) {
result.add(AccessMode.read);
}
if (WRITE_METHODS.has(method)) {
result.add(AccessMode.write);
result.add(AccessMode.append);
result.add(AccessMode.create);
result.add(AccessMode.delete);
} else if (APPEND_METHODS.has(method)) {
result.add(AccessMode.append);
}
return result;
}
}

View File

@@ -0,0 +1,5 @@
import type { Operation } from '../../http/Operation';
import { AsyncHandler } from '../../util/handlers/AsyncHandler';
import type { AccessMode } from './Permissions';
export abstract class ModesExtractor extends AsyncHandler<Operation, Set<AccessMode>> {}

View File

@@ -0,0 +1,19 @@
import type { CredentialGroup } from '../../authentication/Credentials';
/**
* Different modes that require permission.
*/
export enum AccessMode {
read = 'read',
append = 'append',
write = 'write',
create = 'create',
delete = 'delete',
}
/**
* A data interface indicating which permissions are required (based on the context).
*/
export type Permission = Partial<Record<AccessMode, boolean>>;
export type PermissionSet = Partial<Record<CredentialGroup, Permission>>;

View File

@@ -0,0 +1,85 @@
import { Algebra } from 'sparqlalgebrajs';
import type { Operation } from '../../http/Operation';
import type { Representation } from '../../http/representation/Representation';
import type { SparqlUpdatePatch } from '../../http/representation/SparqlUpdatePatch';
import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError';
import { ModesExtractor } from './ModesExtractor';
import { AccessMode } from './Permissions';
export class SparqlPatchModesExtractor extends ModesExtractor {
public async canHandle({ method, body }: Operation): Promise<void> {
if (method !== 'PATCH') {
throw new NotImplementedHttpError(`Cannot determine permissions of ${method}, only PATCH.`);
}
if (!body) {
throw new NotImplementedHttpError('Cannot determine permissions of PATCH operations without a body.');
}
if (!this.isSparql(body)) {
throw new NotImplementedHttpError('Cannot determine permissions of non-SPARQL patches.');
}
if (!this.isSupported(body.algebra)) {
throw new NotImplementedHttpError('Can only determine permissions of a PATCH with DELETE/INSERT operations.');
}
}
public async handle({ body }: Operation): Promise<Set<AccessMode>> {
// Verified in `canHandle` call
const update = (body as SparqlUpdatePatch).algebra as Algebra.DeleteInsert;
const result = new Set<AccessMode>();
// Since `append` is a specific type of write, it is true if `write` is true.
if (this.needsWrite(update)) {
result.add(AccessMode.write);
result.add(AccessMode.append);
result.add(AccessMode.create);
result.add(AccessMode.delete);
} else if (this.needsAppend(update)) {
result.add(AccessMode.append);
}
return result;
}
private isSparql(data: Representation): data is SparqlUpdatePatch {
return Boolean((data as SparqlUpdatePatch).algebra);
}
private isSupported(op: Algebra.Operation): boolean {
if (this.isDeleteInsert(op) || this.isNop(op)) {
return true;
}
if (op.type === Algebra.types.COMPOSITE_UPDATE) {
return (op as Algebra.CompositeUpdate).updates.every((update): boolean => this.isSupported(update));
}
return false;
}
private isDeleteInsert(op: Algebra.Operation): op is Algebra.DeleteInsert {
return op.type === Algebra.types.DELETE_INSERT;
}
private isNop(op: Algebra.Operation): op is Algebra.Nop {
return op.type === Algebra.types.NOP;
}
private needsAppend(update: Algebra.Operation): boolean {
if (this.isNop(update)) {
return false;
}
if (this.isDeleteInsert(update)) {
return Boolean(update.insert && update.insert.length > 0);
}
return (update as Algebra.CompositeUpdate).updates.some((op): boolean => this.needsAppend(op));
}
private needsWrite(update: Algebra.Operation): boolean {
if (this.isNop(update)) {
return false;
}
if (this.isDeleteInsert(update)) {
return Boolean(update.delete && update.delete.length > 0);
}
return (update as Algebra.CompositeUpdate).updates.some((op): boolean => this.needsWrite(op));
}
}