mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
test: Use Components.js in Authorization.
This commit is contained in:
parent
d1d29a3f52
commit
1cf1167261
@ -6,12 +6,14 @@
|
||||
"@type": "SequenceHandler",
|
||||
"SequenceHandler:_handlers": [
|
||||
{
|
||||
"@id": "urn:solid-server:default:LoggerInitializer",
|
||||
"@type": "LoggerInitializer",
|
||||
"LoggerInitializer:_loggerFactory": {
|
||||
"@id": "urn:solid-server:default:LoggerFactory"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@id": "urn:solid-server:default:RootContainerInitializer",
|
||||
"@type": "RootContainerInitializer",
|
||||
"RootContainerInitializer:_baseUrl": {
|
||||
"@id": "urn:solid-server:default:variable:baseUrl"
|
||||
@ -21,6 +23,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"@id": "urn:solid-server:default:AclInitializer",
|
||||
"@type": "AclInitializer",
|
||||
"AclInitializer:_baseUrl": {
|
||||
"@id": "urn:solid-server:default:variable:baseUrl"
|
||||
@ -33,6 +36,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"@id": "urn:solid-server:default:ServerInitializer",
|
||||
"@type": "ServerInitializer",
|
||||
"ServerInitializer:_serverFactory": {
|
||||
"@id": "urn:solid-server:default:ServerFactory"
|
||||
|
@ -131,7 +131,7 @@ export class WebAclAuthorizer extends Authorizer {
|
||||
if (error instanceof NotFoundHttpError) {
|
||||
this.logger.debug(`No direct ACL document found for ${id.path}`);
|
||||
} else {
|
||||
this.logger.error(`Error reading ACL for ${id.path}`, { error });
|
||||
this.logger.error(`Error reading ACL for ${id.path}: ${(error as Error).message}`, { error });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { ResourceStore } from '../storage/ResourceStore';
|
||||
import { TEXT_TURTLE } from '../util/ContentTypes';
|
||||
import { NotFoundHttpError } from '../util/errors/NotFoundHttpError';
|
||||
import { ensureTrailingSlash } from '../util/PathUtil';
|
||||
import { guardedStreamFrom } from '../util/StreamUtil';
|
||||
import { CONTENT_TYPE } from '../util/UriConstants';
|
||||
import { Initializer } from './Initializer';
|
||||
@ -24,7 +25,7 @@ export class AclInitializer extends Initializer {
|
||||
aclManager: AclManager,
|
||||
) {
|
||||
super();
|
||||
this.baseUrl = baseUrl;
|
||||
this.baseUrl = ensureTrailingSlash(baseUrl);
|
||||
this.store = store;
|
||||
this.aclManager = aclManager;
|
||||
}
|
||||
|
@ -8,6 +8,13 @@ import { isResourceIdentifier } from './ResourceIdentifier';
|
||||
export type MetadataIdentifier = ResourceIdentifier | NamedNode | BlankNode;
|
||||
export type MetadataOverrideValue = NamedNode | Literal | string | (NamedNode | Literal | string)[];
|
||||
|
||||
/**
|
||||
* Determines whether the object is a `RepresentationMetadata`.
|
||||
*/
|
||||
export const isRepresentationMetadata = function(object: any): object is RepresentationMetadata {
|
||||
return typeof object?.setMetadata === 'function';
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores the metadata triples and provides methods for easy access.
|
||||
* Most functions return the metadata object to allow for chaining.
|
||||
@ -49,7 +56,7 @@ export class RepresentationMetadata {
|
||||
this.id = DataFactory.namedNode(input.path);
|
||||
} else if (isTerm(input)) {
|
||||
this.id = input;
|
||||
} else if (input instanceof RepresentationMetadata) {
|
||||
} else if (isRepresentationMetadata(input)) {
|
||||
this.id = input.identifier;
|
||||
this.addQuads(input.quads());
|
||||
} else {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
|
||||
import { getLoggerFor } from '../../logging/LogUtil';
|
||||
import { InternalServerError } from '../errors/InternalServerError';
|
||||
import { ensureTrailingSlash } from '../PathUtil';
|
||||
import type { IdentifierStrategy } from './IdentifierStrategy';
|
||||
@ -8,13 +9,18 @@ import type { IdentifierStrategy } from './IdentifierStrategy';
|
||||
*/
|
||||
export class SingleRootIdentifierStrategy implements IdentifierStrategy {
|
||||
private readonly baseUrl: string;
|
||||
protected readonly logger = getLoggerFor(this);
|
||||
|
||||
public constructor(baseUrl: string) {
|
||||
this.baseUrl = ensureTrailingSlash(baseUrl);
|
||||
}
|
||||
|
||||
public supportsIdentifier(identifier: ResourceIdentifier): boolean {
|
||||
return identifier.path.startsWith(this.baseUrl);
|
||||
const supported = identifier.path.startsWith(this.baseUrl);
|
||||
this.logger.debug(supported ?
|
||||
`Identifier ${identifier.path} is part of ${this.baseUrl}` :
|
||||
`Identifier ${identifier.path} is not part of ${this.baseUrl}`);
|
||||
return supported;
|
||||
}
|
||||
|
||||
public getParentContainer(identifier: ResourceIdentifier): ResourceIdentifier {
|
||||
|
@ -1,65 +0,0 @@
|
||||
import type {
|
||||
HttpHandler,
|
||||
ResourceStore,
|
||||
} from '../../src/index';
|
||||
import {
|
||||
AuthenticatedLdpHandler,
|
||||
EmptyCredentialsExtractor,
|
||||
MethodPermissionsExtractor,
|
||||
RdfToQuadConverter,
|
||||
QuadToRdfConverter,
|
||||
WaterfallHandler,
|
||||
} from '../../src/index';
|
||||
import type { ServerConfig } from './ServerConfig';
|
||||
import {
|
||||
getInMemoryResourceStore,
|
||||
getConvertingStore,
|
||||
getBasicRequestParser,
|
||||
getOperationHandler,
|
||||
getWebAclAuthorizer,
|
||||
getResponseWriter,
|
||||
} from './Util';
|
||||
|
||||
/**
|
||||
* BasicHandlersWithAclConfig works with
|
||||
* - an WebAclAuthorizer
|
||||
* - an InMemoryResourceStore wrapped in a converting store & wrapped in a patching store
|
||||
* - GET, POST, PUT, PATCH & DELETE operation handlers
|
||||
*/
|
||||
|
||||
export class BasicHandlersWithAclConfig implements ServerConfig {
|
||||
public store: ResourceStore;
|
||||
|
||||
public constructor() {
|
||||
this.store = getConvertingStore(
|
||||
getInMemoryResourceStore(),
|
||||
[ new QuadToRdfConverter(),
|
||||
new RdfToQuadConverter() ],
|
||||
);
|
||||
}
|
||||
|
||||
public getHttpHandler(): HttpHandler {
|
||||
const requestParser = getBasicRequestParser();
|
||||
|
||||
const credentialsExtractor = new EmptyCredentialsExtractor();
|
||||
const permissionsExtractor = new WaterfallHandler([
|
||||
new MethodPermissionsExtractor(),
|
||||
]);
|
||||
|
||||
const operationHandler = getOperationHandler(this.store);
|
||||
|
||||
const responseWriter = getResponseWriter();
|
||||
const authorizer = getWebAclAuthorizer(this.store);
|
||||
|
||||
const handler = new AuthenticatedLdpHandler({
|
||||
requestParser,
|
||||
credentialsExtractor,
|
||||
permissionsExtractor,
|
||||
authorizer,
|
||||
operationHandler,
|
||||
responseWriter,
|
||||
});
|
||||
|
||||
return handler;
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ import {
|
||||
ErrorResponseWriter,
|
||||
GetOperationHandler,
|
||||
HeadOperationHandler,
|
||||
InMemoryDataAccessor,
|
||||
LinkRelMetadataWriter,
|
||||
LinkTypeParser,
|
||||
MappedMetadataWriter,
|
||||
@ -63,15 +62,6 @@ export const getRootFilePath = (subfolder: string): string => join(__dirname, '.
|
||||
export const getDataAccessorStore = (base: string, dataAccessor: DataAccessor): DataAccessorBasedStore =>
|
||||
new DataAccessorBasedStore(dataAccessor, new SingleRootIdentifierStrategy(base));
|
||||
|
||||
/**
|
||||
* Gives an in memory resource store based on (default) base url.
|
||||
* @param base - Optional base parameter for the run time config.
|
||||
*
|
||||
* @returns The in memory resource store.
|
||||
*/
|
||||
export const getInMemoryResourceStore = (base = BASE): DataAccessorBasedStore =>
|
||||
getDataAccessorStore(base, new InMemoryDataAccessor(BASE));
|
||||
|
||||
/**
|
||||
* Gives a converting store given some converters.
|
||||
* @param store - Initial store.
|
||||
|
45
test/configs/auth-ldp-handler.json
Normal file
45
test/configs/auth-ldp-handler.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
|
||||
"import": [
|
||||
"files-scs:config/presets/acl.json",
|
||||
"files-scs:config/presets/init.json",
|
||||
"files-scs:config/presets/ldp.json",
|
||||
"files-scs:config/presets/ldp/credentials-extractor.json",
|
||||
"files-scs:config/presets/ldp/metadata-handler.json",
|
||||
"files-scs:config/presets/ldp/operation-handler.json",
|
||||
"files-scs:config/presets/ldp/permissions-extractor.json",
|
||||
"files-scs:config/presets/ldp/response-writer.json",
|
||||
"files-scs:config/presets/ldp/request-parser.json",
|
||||
"files-scs:config/presets/representation-conversion.json",
|
||||
"files-scs:config/presets/storage/backend/storage-memory.json",
|
||||
"files-scs:config/presets/storage-wrapper.json",
|
||||
"files-scs:config/presets/cli-params.json"
|
||||
],
|
||||
"@graph": [
|
||||
{
|
||||
"@id": "urn:solid-server:test:Instances",
|
||||
"@type": "RecordObject",
|
||||
"RecordObject:_record": [
|
||||
{
|
||||
"RecordObject:_record_key": "initializer",
|
||||
"RecordObject:_record_value": { "@id": "urn:solid-server:default:AclInitializer" }
|
||||
},
|
||||
{
|
||||
"RecordObject:_record_key": "handler",
|
||||
"RecordObject:_record_value": { "@id": "urn:solid-server:default:LdpHandler" }
|
||||
},
|
||||
{
|
||||
"RecordObject:_record_key": "store",
|
||||
"RecordObject:_record_value": { "@id": "urn:solid-server:default:ResourceStore" }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"@id": "urn:solid-server:default:RoutingResourceStore",
|
||||
"@type": "PassthroughStore",
|
||||
"PassthroughStore:_source": {
|
||||
"@id": "urn:solid-server:default:MemoryResourceStore"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,20 +1,23 @@
|
||||
import type { MockResponse } from 'node-mocks-http';
|
||||
import { RootContainerInitializer } from '../../src/init/RootContainerInitializer';
|
||||
import { BasicHandlersWithAclConfig } from '../configs/BasicHandlersWithAclConfig';
|
||||
import { BASE } from '../configs/Util';
|
||||
import type { HttpHandler, Initializer, ResourceStore } from '../../src/';
|
||||
import { BASE, instantiateFromConfig } from '../configs/Util';
|
||||
import { AclTestHelper } from '../util/TestHelpers';
|
||||
import { call } from '../util/Util';
|
||||
|
||||
describe('A server with authorization', (): void => {
|
||||
const config = new BasicHandlersWithAclConfig();
|
||||
const handler = config.getHttpHandler();
|
||||
const { store } = config;
|
||||
const aclHelper = new AclTestHelper(store, 'http://test.com/');
|
||||
let handler: HttpHandler;
|
||||
let aclHelper: AclTestHelper;
|
||||
|
||||
beforeAll(async(): Promise<void> => {
|
||||
// Initialize store
|
||||
const initializer = new RootContainerInitializer(BASE, config.store);
|
||||
let initializer: Initializer,
|
||||
store: ResourceStore;
|
||||
const instances = await instantiateFromConfig('urn:solid-server:test:Instances', 'auth-ldp-handler.json', {
|
||||
'urn:solid-server:default:variable:baseUrl': BASE,
|
||||
}) as Record<string, any>;
|
||||
({ handler, store, initializer } = instances);
|
||||
|
||||
await initializer.handleSafe();
|
||||
aclHelper = new AclTestHelper(store, BASE);
|
||||
});
|
||||
|
||||
it('can create new entries.', async(): Promise<void> => {
|
||||
|
@ -6,8 +6,8 @@ import { Readable } from 'stream';
|
||||
import * as url from 'url';
|
||||
import type { MockResponse } from 'node-mocks-http';
|
||||
import { createResponse } from 'node-mocks-http';
|
||||
import type { ResourceStore, PermissionSet, HttpHandler, HttpRequest } from '../../src/index';
|
||||
import { guardedStreamFrom, RepresentationMetadata } from '../../src/index';
|
||||
import type { ResourceStore, PermissionSet, HttpHandler, HttpRequest } from '../../src/';
|
||||
import { guardedStreamFrom, RepresentationMetadata, ensureTrailingSlash } from '../../src/';
|
||||
import { CONTENT_TYPE } from '../../src/util/UriConstants';
|
||||
import { call } from './Util';
|
||||
|
||||
@ -18,7 +18,7 @@ export class AclTestHelper {
|
||||
|
||||
public constructor(store: ResourceStore, id: string) {
|
||||
this.store = store;
|
||||
this.id = id;
|
||||
this.id = ensureTrailingSlash(id);
|
||||
}
|
||||
|
||||
public async setSimpleAcl(
|
||||
|
Loading…
x
Reference in New Issue
Block a user