From 962b47469325e7effe1e1bfd47f71ca66ab1e04e Mon Sep 17 00:00:00 2001 From: jaxoncreed Date: Wed, 14 Feb 2024 13:50:29 -0500 Subject: [PATCH] Some coverage for getting access control --- packages/solid/src/resource/Resource.ts | 24 ++++++++++++--- packages/solid/src/resource/wac/getWacRule.ts | 14 ++++++++- .../src/resource/wac/results/WacRuleAbsent.ts | 5 ++++ packages/solid/src/util/rdfUtils.ts | 2 +- packages/solid/test/Integration.test.ts | 29 +++++++++++++++++++ 5 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 packages/solid/src/resource/wac/results/WacRuleAbsent.ts diff --git a/packages/solid/src/resource/Resource.ts b/packages/solid/src/resource/Resource.ts index 82b8915..2a5401a 100644 --- a/packages/solid/src/resource/Resource.ts +++ b/packages/solid/src/resource/Resource.ts @@ -29,6 +29,7 @@ import type { WacRule } from "./wac/WacRule"; import type { GetWacUriError, GetWacUriResult } from "./wac/getWacUri"; import { getWacUri } from "./wac/getWacUri"; import { getWacRuleWithAclUri, type GetWacRuleResult } from "./wac/getWacRule"; +import { NoncompliantPodError } from "../requester/results/error/NoncompliantPodError"; /** * Statuses shared between both Leaf and Container @@ -567,14 +568,29 @@ export abstract class Resource extends (EventEmitter as new () => TypedEmitter<{ // Get the wac uri const wacUriResult = await this.getWacUri(options); - if (wacUriResult.isError) { - return wacUriResult; - } + if (wacUriResult.isError) return wacUriResult; // Get the wac rule - return getWacRuleWithAclUri(wacUriResult.wacUri, { + const wacResult = await getWacRuleWithAclUri(wacUriResult.wacUri, { fetch: this.context.fetch, }); + if (wacResult.isError) return wacResult; + // If the wac rules was successfully found + if (wacResult.type === "getWacRuleSuccess") { + this.wacRule = wacResult.wacRule; + return wacResult; + } + + // If the WacRule is absent + const parentUri = getParentUri(this.uri); + if (!parentUri) { + return new NoncompliantPodError( + this.uri, + `Resource "${this.uri}" has no Effective ACL resource`, + ); + } + const parent = this.context.resourceStore.get(parentUri); + return parent.getWac(); } // async setWac(wacRule: WacRule): Promise<> { diff --git a/packages/solid/src/resource/wac/getWacRule.ts b/packages/solid/src/resource/wac/getWacRule.ts index 1f9405c..0171ef3 100644 --- a/packages/solid/src/resource/wac/getWacRule.ts +++ b/packages/solid/src/resource/wac/getWacRule.ts @@ -9,12 +9,16 @@ import { rawTurtleToDataset } from "../../util/rdfUtils"; import { AuthorizationShapeType } from "../../.ldo/wac.shapeTypes"; import type { AccessModeList, WacRule } from "./WacRule"; import type { Authorization } from "../../.ldo/wac.typings"; +import type { WacRuleAbsent } from "./results/WacRuleAbsent"; export type GetWacRuleError = | HttpErrorResultType | NoncompliantPodError | UnexpectedResourceError; -export type GetWacRuleResult = GetWacRuleSuccess | GetWacRuleError; +export type GetWacRuleResult = + | GetWacRuleSuccess + | GetWacRuleError + | WacRuleAbsent; export async function getWacRuleWithAclUri( aclUri: string, @@ -25,6 +29,14 @@ export async function getWacRuleWithAclUri( const errorResult = HttpErrorResult.checkResponse(aclUri, response); if (errorResult) return errorResult; + if (response.status === 404) { + return { + type: "wacRuleAbsent", + uri: aclUri, + isError: false, + }; + } + // Parse Turtle const rawTurtle = await response.text(); const rawTurtleResult = await rawTurtleToDataset(rawTurtle, aclUri); diff --git a/packages/solid/src/resource/wac/results/WacRuleAbsent.ts b/packages/solid/src/resource/wac/results/WacRuleAbsent.ts new file mode 100644 index 0000000..739ad2e --- /dev/null +++ b/packages/solid/src/resource/wac/results/WacRuleAbsent.ts @@ -0,0 +1,5 @@ +import type { ResourceSuccess } from "../../../requester/results/success/SuccessResult"; + +export interface WacRuleAbsent extends ResourceSuccess { + type: "wacRuleAbsent"; +} diff --git a/packages/solid/src/util/rdfUtils.ts b/packages/solid/src/util/rdfUtils.ts index a3a4268..d10a737 100644 --- a/packages/solid/src/util/rdfUtils.ts +++ b/packages/solid/src/util/rdfUtils.ts @@ -143,7 +143,7 @@ export async function rawTurtleToDataset( const error = UnexpectedResourceError.fromThrown(baseUri, err); return new NoncompliantPodError( baseUri, - `Request returned noncompliant turtle: ${error.message}`, + `Request returned noncompliant turtle: ${error.message}\n${rawTurtle}`, ); } } diff --git a/packages/solid/test/Integration.test.ts b/packages/solid/test/Integration.test.ts index 1ee33e5..1b30732 100644 --- a/packages/solid/test/Integration.test.ts +++ b/packages/solid/test/Integration.test.ts @@ -1655,5 +1655,34 @@ describe("Integration", () => { control: true, }); }); + + it("Gets wac rules for a resource that does not have a corresponding acl", async () => { + const container = solidLdoDataset.getResource(SAMPLE_DATA_URI); + const wacResult = await container.getWac(); + expect(wacResult.isError).toBe(false); + const wacSuccess = wacResult as GetWacRuleSuccess; + expect(wacSuccess.wacRule.public).toEqual({ + read: false, + write: false, + append: false, + control: false, + }); + expect(wacSuccess.wacRule.authenticated).toEqual({ + read: false, + write: false, + append: false, + control: false, + }); + expect(wacSuccess.wacRule.agent[WEB_ID]).toEqual({ + read: true, + write: true, + append: true, + control: true, + }); + }); + + it("returns an error when an error is encountered fetching the aclUri", async () => { + + }); }); });