mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Move MapperUtil functions to BaseFileIdentifierMapper
This commit is contained in:
parent
55fddf8e60
commit
e9502e55a7
@ -1,15 +1,18 @@
|
||||
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
|
||||
import { getLoggerFor } from '../../logging/LogUtil';
|
||||
import { APPLICATION_OCTET_STREAM } from '../../util/ContentTypes';
|
||||
import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError';
|
||||
import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError';
|
||||
import {
|
||||
decodeUriPathComponents,
|
||||
encodeUriPathComponents,
|
||||
ensureTrailingSlash,
|
||||
isContainerIdentifier,
|
||||
joinFilePath,
|
||||
normalizeFilePath,
|
||||
trimTrailingSlashes,
|
||||
} from '../../util/PathUtil';
|
||||
import type { FileIdentifierMapper, ResourceLink } from './FileIdentifierMapper';
|
||||
import { getAbsolutePath, getRelativePath, validateRelativePath } from './MapperUtil';
|
||||
|
||||
/**
|
||||
* Base class for {@link FileIdentifierMapper} implementations.
|
||||
@ -34,10 +37,10 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper {
|
||||
* @returns A ResourceLink with all the necessary metadata.
|
||||
*/
|
||||
public async mapUrlToFilePath(identifier: ResourceIdentifier, contentType?: string): Promise<ResourceLink> {
|
||||
const path = getRelativePath(this.baseRequestURI, identifier);
|
||||
validateRelativePath(path, identifier);
|
||||
const path = this.getRelativePath(identifier);
|
||||
this.validateRelativePath(path, identifier);
|
||||
|
||||
const filePath = getAbsolutePath(this.rootFilepath, path);
|
||||
const filePath = this.getAbsolutePath(path);
|
||||
return isContainerIdentifier(identifier) ?
|
||||
this.mapUrlToContainerPath(identifier, filePath) :
|
||||
this.mapUrlToDocumentPath(identifier, filePath, contentType);
|
||||
@ -142,4 +145,52 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper {
|
||||
protected async getContentTypeFromPath(filePath: string): Promise<string> {
|
||||
return APPLICATION_OCTET_STREAM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the absolute file path based on the rootFilepath.
|
||||
* @param path - The relative file path.
|
||||
*
|
||||
* @returns Absolute path of the file.
|
||||
*/
|
||||
protected getAbsolutePath(path: string): string {
|
||||
return joinFilePath(this.rootFilepath, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the baseRequestURI from the identifier.
|
||||
* @param identifier - Incoming identifier.
|
||||
*
|
||||
* @throws {@link NotFoundHttpError}
|
||||
* If the identifier does not match the baseRequestURI.
|
||||
*
|
||||
* @returns A string representing the relative path.
|
||||
*/
|
||||
protected getRelativePath(identifier: ResourceIdentifier): string {
|
||||
if (!identifier.path.startsWith(this.baseRequestURI)) {
|
||||
this.logger.warn(`The URL ${identifier.path} is outside of the scope ${this.baseRequestURI}`);
|
||||
throw new NotFoundHttpError();
|
||||
}
|
||||
return decodeUriPathComponents(identifier.path.slice(this.baseRequestURI.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given relative path is valid.
|
||||
*
|
||||
* @throws {@link BadRequestHttpError}
|
||||
* If the relative path is invalid.
|
||||
*
|
||||
* @param path - A relative path, as generated by {@link getRelativePath}.
|
||||
* @param identifier - A resource identifier.
|
||||
*/
|
||||
protected validateRelativePath(path: string, identifier: ResourceIdentifier): void {
|
||||
if (!path.startsWith('/')) {
|
||||
this.logger.warn(`URL ${identifier.path} needs a / after the base`);
|
||||
throw new BadRequestHttpError('URL needs a / after the base');
|
||||
}
|
||||
|
||||
if (path.includes('/..')) {
|
||||
this.logger.warn(`Disallowed /.. segment in URL ${identifier.path}.`);
|
||||
throw new BadRequestHttpError('Disallowed /.. segment in URL');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
|
||||
import { getLoggerFor } from '../../logging/LogUtil';
|
||||
import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError';
|
||||
import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError';
|
||||
import { joinFilePath, decodeUriPathComponents } from '../../util/PathUtil';
|
||||
|
||||
const logger = getLoggerFor('MapperUtil');
|
||||
|
||||
/**
|
||||
* Get the absolute file path based on the rootFilepath of the store.
|
||||
* @param rootFilepath - The root file path.
|
||||
* @param path - The relative file path.
|
||||
* @param identifier - Optional identifier to add to the path.
|
||||
*
|
||||
* @returns Absolute path of the file.
|
||||
*/
|
||||
export function getAbsolutePath(rootFilepath: string, path: string, identifier = ''): string {
|
||||
return joinFilePath(rootFilepath, path, identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the baseRequestURI from the identifier and checks if the stripped base URI matches the store's one.
|
||||
* @param baseRequestURI - Base URL for requests.
|
||||
* @param identifier - Incoming identifier.
|
||||
*
|
||||
* @throws {@link NotFoundHttpError}
|
||||
* If the identifier does not match the baseRequestURI path of the store.
|
||||
*
|
||||
* @returns A string representing the relative path.
|
||||
*/
|
||||
export function getRelativePath(baseRequestURI: string, identifier: ResourceIdentifier): string {
|
||||
if (!identifier.path.startsWith(baseRequestURI)) {
|
||||
logger.warn(`The URL ${identifier.path} is outside of the scope ${baseRequestURI}`);
|
||||
throw new NotFoundHttpError();
|
||||
}
|
||||
return decodeUriPathComponents(identifier.path.slice(baseRequestURI.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given relative path is valid.
|
||||
*
|
||||
* @throws {@link BadRequestHttpError}
|
||||
* If the relative path is invalid.
|
||||
*
|
||||
* @param path - A relative path, as generated by {@link getRelativePath}.
|
||||
* @param identifier - A resource identifier.
|
||||
*/
|
||||
export function validateRelativePath(path: string, identifier: ResourceIdentifier): void {
|
||||
if (!path.startsWith('/')) {
|
||||
logger.warn(`URL ${identifier.path} needs a / after the base`);
|
||||
throw new BadRequestHttpError('URL needs a / after the base');
|
||||
}
|
||||
|
||||
if (path.includes('/..')) {
|
||||
logger.warn(`Disallowed /.. segment in URL ${identifier.path}.`);
|
||||
throw new BadRequestHttpError('Disallowed /.. segment in URL');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user