mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
57 lines
2.2 KiB
TypeScript
57 lines
2.2 KiB
TypeScript
import type { Operation } from '../../http/Operation';
|
|
import type { ResourceSet } from '../../storage/ResourceSet';
|
|
import type { IdentifierStrategy } from '../../util/identifiers/IdentifierStrategy';
|
|
import { ModesExtractor } from './ModesExtractor';
|
|
import type { AccessMap } from './Permissions';
|
|
import { AccessMode } from './Permissions';
|
|
|
|
/**
|
|
* Returns the required access modes from the source {@link ModesExtractor}.
|
|
* In case create permissions are required,
|
|
* verifies if any of the containers permissions also need to be created
|
|
* and adds the corresponding identifier/mode combinations.
|
|
*/
|
|
export class IntermediateCreateExtractor extends ModesExtractor {
|
|
private readonly resourceSet: ResourceSet;
|
|
private readonly strategy: IdentifierStrategy;
|
|
private readonly source: ModesExtractor;
|
|
|
|
/**
|
|
* Certain permissions depend on the existence of the target resource.
|
|
* The provided {@link ResourceSet} will be used for that.
|
|
*
|
|
* @param resourceSet - {@link ResourceSet} that can verify the target resource existence.
|
|
* @param strategy - {@link IdentifierStrategy} that will be used to determine parent containers.
|
|
* @param source - The source {@link ModesExtractor}.
|
|
*/
|
|
public constructor(resourceSet: ResourceSet, strategy: IdentifierStrategy, source: ModesExtractor) {
|
|
super();
|
|
this.resourceSet = resourceSet;
|
|
this.strategy = strategy;
|
|
this.source = source;
|
|
}
|
|
|
|
public async canHandle(input: Operation): Promise<void> {
|
|
return this.source.canHandle(input);
|
|
}
|
|
|
|
public async handle(input: Operation): Promise<AccessMap> {
|
|
const requestedModes = await this.source.handle(input);
|
|
|
|
for (const key of requestedModes.distinctKeys()) {
|
|
if (requestedModes.hasEntry(key, AccessMode.create)) {
|
|
// Add the `create` mode if the parent does not exist yet
|
|
const parent = this.strategy.getParentContainer(key);
|
|
if (!await this.resourceSet.hasResource(parent)) {
|
|
// It is not completely clear at this point which permissions need to be available
|
|
// on intermediate containers to create them,
|
|
// so we stick with `create` for now.
|
|
requestedModes.add(parent, AccessMode.create);
|
|
}
|
|
}
|
|
}
|
|
|
|
return requestedModes;
|
|
}
|
|
}
|