mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Replace getParentContainer util function with ContainerManager
This commit is contained in:
@@ -8,9 +8,10 @@ import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { ResourceStore } from '../storage/ResourceStore';
|
||||
import { INTERNAL_QUADS } from '../util/ContentTypes';
|
||||
import { ForbiddenHttpError } from '../util/errors/ForbiddenHttpError';
|
||||
import { InternalServerError } from '../util/errors/InternalServerError';
|
||||
import { NotFoundHttpError } from '../util/errors/NotFoundHttpError';
|
||||
import { UnauthorizedHttpError } from '../util/errors/UnauthorizedHttpError';
|
||||
import { getParentContainer } from '../util/PathUtil';
|
||||
import type { IdentifierStrategy } from '../util/identifiers/IdentifierStrategy';
|
||||
import { ACL, FOAF } from '../util/UriConstants';
|
||||
import type { AclManager } from './AclManager';
|
||||
import type { AuthorizerArgs } from './Authorizer';
|
||||
@@ -26,11 +27,13 @@ export class WebAclAuthorizer extends Authorizer {
|
||||
|
||||
private readonly aclManager: AclManager;
|
||||
private readonly resourceStore: ResourceStore;
|
||||
private readonly identifierStrategy: IdentifierStrategy;
|
||||
|
||||
public constructor(aclManager: AclManager, resourceStore: ResourceStore) {
|
||||
public constructor(aclManager: AclManager, resourceStore: ResourceStore, identifierStrategy: IdentifierStrategy) {
|
||||
super();
|
||||
this.aclManager = aclManager;
|
||||
this.resourceStore = resourceStore;
|
||||
this.identifierStrategy = identifierStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,7 +137,11 @@ export class WebAclAuthorizer extends Authorizer {
|
||||
}
|
||||
|
||||
this.logger.debug(`Traversing to the parent of ${id.path}`);
|
||||
const parent = getParentContainer(id);
|
||||
if (this.identifierStrategy.isRootContainer(id)) {
|
||||
this.logger.error(`No ACL document found for root container ${id.path}`);
|
||||
throw new InternalServerError('No ACL document found for root container');
|
||||
}
|
||||
const parent = this.identifierStrategy.getParentContainer(id);
|
||||
return this.getAclRecursive(parent, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ import { ConflictHttpError } from '../util/errors/ConflictHttpError';
|
||||
import { MethodNotAllowedHttpError } from '../util/errors/MethodNotAllowedHttpError';
|
||||
import { NotFoundHttpError } from '../util/errors/NotFoundHttpError';
|
||||
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
|
||||
import type { IdentifierStrategy } from '../util/identifiers/IdentifierStrategy';
|
||||
import {
|
||||
ensureTrailingSlash,
|
||||
getParentContainer,
|
||||
isContainerIdentifier,
|
||||
isContainerPath,
|
||||
trimTrailingSlashes,
|
||||
@@ -51,10 +51,12 @@ import type { ResourceStore } from './ResourceStore';
|
||||
export class DataAccessorBasedStore implements ResourceStore {
|
||||
private readonly accessor: DataAccessor;
|
||||
private readonly base: string;
|
||||
private readonly identifierStrategy: IdentifierStrategy;
|
||||
|
||||
public constructor(accessor: DataAccessor, base: string) {
|
||||
public constructor(accessor: DataAccessor, base: string, identifierStrategy: IdentifierStrategy) {
|
||||
this.accessor = accessor;
|
||||
this.base = ensureTrailingSlash(base);
|
||||
this.identifierStrategy = identifierStrategy;
|
||||
}
|
||||
|
||||
public async getRepresentation(identifier: ResourceIdentifier): Promise<Representation> {
|
||||
@@ -219,7 +221,7 @@ export class DataAccessorBasedStore implements ResourceStore {
|
||||
}
|
||||
|
||||
if (createContainers) {
|
||||
await this.createRecursiveContainers(getParentContainer(identifier));
|
||||
await this.createRecursiveContainers(this.identifierStrategy.getParentContainer(identifier));
|
||||
}
|
||||
|
||||
// Make sure the metadata has the correct identifier and correct type quads
|
||||
@@ -354,7 +356,7 @@ export class DataAccessorBasedStore implements ResourceStore {
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof NotFoundHttpError) {
|
||||
// Make sure the parent exists first
|
||||
await this.createRecursiveContainers(getParentContainer(container));
|
||||
await this.createRecursiveContainers(this.identifierStrategy.getParentContainer(container));
|
||||
await this.writeData(container, this.getEmptyContainerRepresentation(container), true);
|
||||
} else {
|
||||
throw error;
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Patch } from '../ldp/http/Patch';
|
||||
import type { Representation } from '../ldp/representation/Representation';
|
||||
import type { RepresentationPreferences } from '../ldp/representation/RepresentationPreferences';
|
||||
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { getParentContainer } from '../util/PathUtil';
|
||||
import type { IdentifierStrategy } from '../util/identifiers/IdentifierStrategy';
|
||||
import type { Conditions } from './Conditions';
|
||||
import type { ResourceStore } from './ResourceStore';
|
||||
|
||||
@@ -14,10 +14,12 @@ import type { ResourceStore } from './ResourceStore';
|
||||
export class MonitoringStore<T extends ResourceStore = ResourceStore>
|
||||
extends EventEmitter implements ResourceStore {
|
||||
private readonly source: T;
|
||||
private readonly identifierStrategy: IdentifierStrategy;
|
||||
|
||||
public constructor(source: T) {
|
||||
public constructor(source: T, identifierStrategy: IdentifierStrategy) {
|
||||
super();
|
||||
this.source = source;
|
||||
this.identifierStrategy = identifierStrategy;
|
||||
}
|
||||
|
||||
public async addResource(container: ResourceIdentifier, representation: Representation,
|
||||
@@ -35,11 +37,9 @@ export class MonitoringStore<T extends ResourceStore = ResourceStore>
|
||||
await this.source.deleteResource(identifier, conditions);
|
||||
|
||||
// Both the container contents and the resource itself have changed
|
||||
try {
|
||||
const container = getParentContainer(identifier);
|
||||
if (!this.identifierStrategy.isRootContainer(identifier)) {
|
||||
const container = this.identifierStrategy.getParentContainer(identifier);
|
||||
this.emit('changed', container);
|
||||
} catch {
|
||||
// Parent container not found
|
||||
}
|
||||
this.emit('changed', identifier);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpErr
|
||||
import { UnsupportedMediaTypeHttpError } from '../../util/errors/UnsupportedMediaTypeHttpError';
|
||||
import { guardStream } from '../../util/GuardedStream';
|
||||
import type { Guarded } from '../../util/GuardedStream';
|
||||
import { ensureTrailingSlash, getParentContainer, isContainerIdentifier } from '../../util/PathUtil';
|
||||
import type { IdentifierStrategy } from '../../util/identifiers/IdentifierStrategy';
|
||||
import { ensureTrailingSlash, isContainerIdentifier } from '../../util/PathUtil';
|
||||
import { generateResourceQuads } from '../../util/ResourceUtil';
|
||||
import { CONTENT_TYPE, LDP } from '../../util/UriConstants';
|
||||
import { toNamedNode } from '../../util/UriUtil';
|
||||
@@ -49,12 +50,14 @@ export class SparqlDataAccessor implements DataAccessor {
|
||||
protected readonly logger = getLoggerFor(this);
|
||||
private readonly endpoint: string;
|
||||
private readonly base: string;
|
||||
private readonly identifierStrategy: IdentifierStrategy;
|
||||
private readonly fetcher: SparqlEndpointFetcher;
|
||||
private readonly generator: SparqlGenerator;
|
||||
|
||||
public constructor(endpoint: string, base: string) {
|
||||
public constructor(endpoint: string, base: string, identifierStrategy: IdentifierStrategy) {
|
||||
this.endpoint = endpoint;
|
||||
this.base = ensureTrailingSlash(base);
|
||||
this.identifierStrategy = identifierStrategy;
|
||||
this.fetcher = new SparqlEndpointFetcher();
|
||||
this.generator = new Generator();
|
||||
}
|
||||
@@ -149,7 +152,7 @@ export class SparqlDataAccessor implements DataAccessor {
|
||||
* Helper function to get named nodes corresponding to the identifier and its parent container.
|
||||
*/
|
||||
private getRelatedNames(identifier: ResourceIdentifier): { name: NamedNode; parent: NamedNode } {
|
||||
const parentIdentifier = getParentContainer(identifier);
|
||||
const parentIdentifier = this.identifierStrategy.getParentContainer(identifier);
|
||||
const name = namedNode(identifier.path);
|
||||
const parent = namedNode(parentIdentifier.path);
|
||||
return { name, parent };
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { InternalServerError } from './errors/InternalServerError';
|
||||
|
||||
/**
|
||||
* Makes sure the input path has exactly 1 slash at the end.
|
||||
@@ -39,26 +38,6 @@ export const decodeUriPathComponents = (path: string): string => path.split('/')
|
||||
*/
|
||||
export const encodeUriPathComponents = (path: string): string => path.split('/').map(encodeURIComponent).join('/');
|
||||
|
||||
/**
|
||||
* Finds the container containing the given resource.
|
||||
* This does not ensure either the container or resource actually exist.
|
||||
*
|
||||
* @param id - Identifier to find container of.
|
||||
*
|
||||
* @returns The identifier of the container this resource is in.
|
||||
*/
|
||||
export const getParentContainer = (id: ResourceIdentifier): ResourceIdentifier => {
|
||||
// Trailing slash is necessary for URL library
|
||||
const parentPath = new URL('..', ensureTrailingSlash(id.path)).toString();
|
||||
|
||||
// This probably means there is an issue with the root
|
||||
if (parentPath === id.path) {
|
||||
throw new InternalServerError(`Resource ${id.path} does not have a parent container`);
|
||||
}
|
||||
|
||||
return { path: parentPath };
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the path corresponds to a container path (ending in a /).
|
||||
* @param path - Path to check.
|
||||
|
||||
Reference in New Issue
Block a user