Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Use PermissionReaders to determine available permissions
These readers will determine which permissions are available for the incoming credentials. Their results then get combined in a UnionReader and authorized in a PermissionBasedAuthorizer
- Loading branch information
Showing
50 changed files
with
708 additions
and
439 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions
10
...ig/ldp/authorization/authorizers/acl.json → config/ldp/authorization/readers/acl.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,31 @@ | ||
{ | ||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld", | ||
"import": [ | ||
"files-scs:config/ldp/authorization/authorizers/acl.json" | ||
"files-scs:config/ldp/authorization/readers/acl.json" | ||
], | ||
"@graph": [ | ||
{ | ||
"comment": "Uses Web Access Control for authorization.", | ||
"@id": "urn:solid-server:default:Authorizer", | ||
"@type": "WaterfallHandler", | ||
"handlers": [ | ||
{ | ||
"comment": "This authorizer will be used to prevent external access to containers used for internal storage.", | ||
"@id": "urn:solid-server:default:PathBasedAuthorizer", | ||
"@type": "PathBasedAuthorizer", | ||
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" } | ||
}, | ||
{ | ||
"comment": "This authorizer makes sure that for auxiliary resources, the main authorizer gets called with the associated identifier.", | ||
"@type": "AuxiliaryAuthorizer", | ||
"resourceAuthorizer": { "@id": "urn:solid-server:default:WebAclAuthorizer" }, | ||
"auxiliaryStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" } | ||
}, | ||
{ "@id": "urn:solid-server:default:WebAclAuthorizer" } | ||
] | ||
"@type": "PermissionBasedAuthorizer", | ||
"reader": { | ||
"@type": "UnionPermissionReader", | ||
"readers": [ | ||
{ | ||
"comment": "This PermissionReader will be used to prevent external access to containers used for internal storage.", | ||
"@id": "urn:solid-server:default:PathBasedReader", | ||
"@type": "PathBasedReader", | ||
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" } | ||
}, | ||
{ | ||
"comment": "This PermissionReader makes sure that for auxiliary resources, the main reader gets called with the associated identifier.", | ||
"@type": "AuxiliaryReader", | ||
"resourceReader": { "@id": "urn:solid-server:default:WebAclReader" }, | ||
"auxiliaryStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" } | ||
}, | ||
{ "@id": "urn:solid-server:default:WebAclReader" } | ||
] | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import type { CredentialGroup } from '../authentication/Credentials'; | ||
import type { Permission, PermissionSet } from '../ldp/permissions/Permissions'; | ||
import type { PermissionReaderInput } from './PermissionReader'; | ||
import { PermissionReader } from './PermissionReader'; | ||
|
||
/** | ||
* PermissionReader which sets all permissions to true or false | ||
* independently of the identifier and requested permissions. | ||
*/ | ||
export class AllStaticReader extends PermissionReader { | ||
private readonly permissions: Permission; | ||
|
||
public constructor(allow: boolean) { | ||
super(); | ||
this.permissions = Object.freeze({ | ||
read: allow, | ||
write: allow, | ||
append: allow, | ||
control: allow, | ||
}); | ||
} | ||
|
||
public async handle({ credentials }: PermissionReaderInput): Promise<PermissionSet> { | ||
const result: PermissionSet = {}; | ||
for (const [ key, value ] of Object.entries(credentials) as [CredentialGroup, Permission][]) { | ||
if (value) { | ||
result[key] = this.permissions; | ||
} | ||
} | ||
return result; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 16 additions & 15 deletions
31
src/authorization/AuxiliaryAuthorizer.ts → src/authorization/AuxiliaryReader.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
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'; | ||
|
||
/** | ||
* Redirects requests to specific PermissionReaders based on their identifier. | ||
* The keys in the input map will be converted to regular expressions. | ||
* The regular expressions should all start with a slash | ||
* and will be evaluated relative to the base URL. | ||
* | ||
* Will error if no match is found. | ||
*/ | ||
export class PathBasedReader extends PermissionReader { | ||
private readonly baseUrl: string; | ||
private readonly paths: Map<RegExp, PermissionReader>; | ||
|
||
public constructor(baseUrl: string, paths: Record<string, PermissionReader>) { | ||
super(); | ||
this.baseUrl = ensureTrailingSlash(baseUrl); | ||
const entries = Object.entries(paths) | ||
.map(([ key, val ]): [RegExp, PermissionReader] => [ new RegExp(key, 'u'), val ]); | ||
this.paths = new Map(entries); | ||
} | ||
|
||
public async canHandle(input: PermissionReaderInput): Promise<void> { | ||
const reader = this.findReader(input.identifier.path); | ||
await reader.canHandle(input); | ||
} | ||
|
||
public async handle(input: PermissionReaderInput): Promise<PermissionSet> { | ||
const reader = this.findReader(input.identifier.path); | ||
return reader.handle(input); | ||
} | ||
|
||
/** | ||
* Find the PermissionReader corresponding to the given path. | ||
* Errors if there is no match. | ||
*/ | ||
private findReader(path: string): PermissionReader { | ||
if (path.startsWith(this.baseUrl)) { | ||
// We want to keep the leading slash | ||
const relative = path.slice(trimTrailingSlashes(this.baseUrl).length); | ||
for (const [ regex, reader ] of this.paths) { | ||
if (regex.test(relative)) { | ||
return reader; | ||
} | ||
} | ||
} | ||
throw new NotImplementedHttpError('No regex matches the given path.'); | ||
} | ||
} |
Oops, something went wrong.