parent
8632f0dfe3
commit
4d62c244dc
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,45 @@ |
|||||||
|
import { ContextDefinition } from "jsonld"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* wacContext: JSONLD Context for wac |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
export const wacContext: ContextDefinition = { |
||||||
|
type: { |
||||||
|
"@id": "@type", |
||||||
|
}, |
||||||
|
Authorization: "http://www.w3.org/ns/auth/acl#Authorization", |
||||||
|
accessTo: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#accessTo", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
default: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#default", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
agent: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#agent", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
agentGroup: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#agentGroup", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
agentClass: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#agentClass", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
AuthenticatedAgent: "http://www.w3.org/ns/auth/acl#AuthenticatedAgent", |
||||||
|
Agent: "http://xmlns.com/foaf/0.1/Agent", |
||||||
|
mode: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#mode", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
Read: "http://www.w3.org/ns/auth/acl#Read", |
||||||
|
Write: "http://www.w3.org/ns/auth/acl#Write", |
||||||
|
Append: "http://www.w3.org/ns/auth/acl#Append", |
||||||
|
Control: "http://www.w3.org/ns/auth/acl#Control", |
||||||
|
}; |
@ -0,0 +1,169 @@ |
|||||||
|
import { Schema } from "shexj"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* wacSchema: ShexJ Schema for wac |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
export const wacSchema: Schema = { |
||||||
|
type: "Schema", |
||||||
|
shapes: [ |
||||||
|
{ |
||||||
|
id: "http://www.w3.org/ns/auth/acls#Authorization", |
||||||
|
type: "ShapeDecl", |
||||||
|
shapeExpr: { |
||||||
|
type: "Shape", |
||||||
|
expression: { |
||||||
|
id: "http://www.w3.org/ns/auth/acls#AuthorizationShape", |
||||||
|
type: "EachOf", |
||||||
|
expressions: [ |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: ["http://www.w3.org/ns/auth/acl#Authorization"], |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "Denotes this as an acl:Authorization", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#accessTo", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The subject of this authorization", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#default", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The container subject of this authorization", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#agent", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"An agent is a person, social entity or software identified by a URI, e.g., a WebID denotes an agent", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#agentGroup", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"Denotes a group of agents being given the access permission", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#agentClass", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: [ |
||||||
|
"http://www.w3.org/ns/auth/acl#AuthenticatedAgent", |
||||||
|
"http://xmlns.com/foaf/0.1/Agent", |
||||||
|
], |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"An agent class is a class of persons or entities identified by a URI.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#mode", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: [ |
||||||
|
"http://www.w3.org/ns/auth/acl#Read", |
||||||
|
"http://www.w3.org/ns/auth/acl#Write", |
||||||
|
"http://www.w3.org/ns/auth/acl#Append", |
||||||
|
"http://www.w3.org/ns/auth/acl#Control", |
||||||
|
], |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"Denotes a class of operations that the agents can perform on a resource.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
@ -0,0 +1,19 @@ |
|||||||
|
import { ShapeType } from "@ldo/ldo"; |
||||||
|
import { wacSchema } from "./wac.schema"; |
||||||
|
import { wacContext } from "./wac.context"; |
||||||
|
import { Authorization } from "./wac.typings"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* LDO ShapeTypes wac |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Authorization ShapeType |
||||||
|
*/ |
||||||
|
export const AuthorizationShapeType: ShapeType<Authorization> = { |
||||||
|
schema: wacSchema, |
||||||
|
shape: "http://www.w3.org/ns/auth/acls#Authorization", |
||||||
|
context: wacContext, |
||||||
|
}; |
@ -0,0 +1,73 @@ |
|||||||
|
import { ContextDefinition } from "jsonld"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* Typescript Typings for wac |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Authorization Type |
||||||
|
*/ |
||||||
|
export interface Authorization { |
||||||
|
"@id"?: string; |
||||||
|
"@context"?: ContextDefinition; |
||||||
|
/** |
||||||
|
* Denotes this as an acl:Authorization |
||||||
|
*/ |
||||||
|
type: { |
||||||
|
"@id": "Authorization"; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* The subject of this authorization |
||||||
|
*/ |
||||||
|
accessTo?: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* The container subject of this authorization |
||||||
|
*/ |
||||||
|
default?: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* An agent is a person, social entity or software identified by a URI, e.g., a WebID denotes an agent |
||||||
|
*/ |
||||||
|
agent?: { |
||||||
|
"@id": string; |
||||||
|
}[]; |
||||||
|
/** |
||||||
|
* Denotes a group of agents being given the access permission |
||||||
|
*/ |
||||||
|
agentGroup?: { |
||||||
|
"@id": string; |
||||||
|
}[]; |
||||||
|
/** |
||||||
|
* An agent class is a class of persons or entities identified by a URI. |
||||||
|
*/ |
||||||
|
agentClass?: ( |
||||||
|
| { |
||||||
|
"@id": "AuthenticatedAgent"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Agent"; |
||||||
|
} |
||||||
|
)[]; |
||||||
|
/** |
||||||
|
* Denotes a class of operations that the agents can perform on a resource. |
||||||
|
*/ |
||||||
|
mode?: ( |
||||||
|
| { |
||||||
|
"@id": "Read"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Write"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Append"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Control"; |
||||||
|
} |
||||||
|
)[]; |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
PREFIX acl: <http://www.w3.org/ns/auth/acl#> |
||||||
|
PREFIX acls: <http://www.w3.org/ns/auth/acls#> |
||||||
|
PREFIX foaf: <http://xmlns.com/foaf/0.1/> |
||||||
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> |
||||||
|
|
||||||
|
acls:Authorization EXTRA a { |
||||||
|
$acls:AuthorizationShape ( |
||||||
|
a [ acl:Authorization ] |
||||||
|
// rdfs:comment "Denotes this as an acl:Authorization"; |
||||||
|
acl:accessTo IRI? |
||||||
|
// rdfs:comment "The subject of this authorization"; |
||||||
|
acl:default IRI? |
||||||
|
// rdfs:comment "The container subject of this authorization"; |
||||||
|
acl:agent IRI* |
||||||
|
// rdfs:comment "An agent is a person, social entity or software identified by a URI, e.g., a WebID denotes an agent"; |
||||||
|
acl:agentGroup IRI* |
||||||
|
// rdfs:comment "Denotes a group of agents being given the access permission"; |
||||||
|
acl:agentClass [ acl:AuthenticatedAgent foaf:Agent ]* |
||||||
|
// rdfs:comment "An agent class is a class of persons or entities identified by a URI."; |
||||||
|
acl:mode [ acl:Read acl:Write acl:Append acl:Control ]* |
||||||
|
// rdfs:comment "Denotes a class of operations that the agents can perform on a resource."; |
||||||
|
) |
||||||
|
} |
@ -1,13 +0,0 @@ |
|||||||
/* istanbul ignore file */ |
|
||||||
|
|
||||||
export async function getAccessRules(): Promise<undefined> { |
|
||||||
throw new Error("Not Implemented"); |
|
||||||
// const [publicAccess, agentAccess] = await Promise.all([
|
|
||||||
// universalAccess.getPublicAccess(uri, { fetch }),
|
|
||||||
// universalAccess.getAgentAccessAll(uri, { fetch }),
|
|
||||||
// ]);
|
|
||||||
// if (agentAccess === null || publicAccess === null) {
|
|
||||||
// return new AccessRuleFetchError(uri);
|
|
||||||
// }
|
|
||||||
// return new AccessRuleResult(uri, publicAccess, agentAccess);
|
|
||||||
} |
|
@ -1,88 +0,0 @@ |
|||||||
/* istanbul ignore file */ |
|
||||||
|
|
||||||
import type { AclDataset, WithChangeLog } from "@inrupt/solid-client"; |
|
||||||
import { |
|
||||||
getSolidDatasetWithAcl, |
|
||||||
hasResourceAcl, |
|
||||||
hasFallbackAcl, |
|
||||||
hasAccessibleAcl, |
|
||||||
createAclFromFallbackAcl, |
|
||||||
getResourceAcl, |
|
||||||
setAgentResourceAccess, |
|
||||||
saveAclFor, |
|
||||||
setPublicDefaultAccess, |
|
||||||
setPublicResourceAccess, |
|
||||||
setAgentDefaultAccess, |
|
||||||
} from "@inrupt/solid-client"; |
|
||||||
import { guaranteeFetch } from "../../util/guaranteeFetch"; |
|
||||||
import { isContainerUri } from "../../util/uriTypes"; |
|
||||||
import type { AccessRule } from "../results/success/AccessRule"; |
|
||||||
import type { SetAccessRuleSuccess } from "../results/success/AccessRule"; |
|
||||||
import { AccessRuleFetchError } from "../results/error/AccessControlError"; |
|
||||||
import type { BasicRequestOptions } from "./requestOptions"; |
|
||||||
|
|
||||||
export type SetAccessRulesResult = |
|
||||||
| SetAccessRuleSuccess |
|
||||||
| SetAccessRulesResultError; |
|
||||||
export type SetAccessRulesResultError = AccessRuleFetchError; |
|
||||||
|
|
||||||
export async function setAccessRules( |
|
||||||
uri: string, |
|
||||||
newAccessRules: AccessRule, |
|
||||||
options?: BasicRequestOptions, |
|
||||||
): Promise<SetAccessRulesResult> { |
|
||||||
console.warn("Access Control is stil underdeveloped. Use with caution."); |
|
||||||
const fetch = guaranteeFetch(options?.fetch); |
|
||||||
const isContainer = isContainerUri(uri); |
|
||||||
|
|
||||||
// Code Copied from https://docs.inrupt.com/developer-tools/javascript/client-libraries/tutorial/manage-wac/
|
|
||||||
// Fetch the SolidDataset and its associated ACLs, if available:
|
|
||||||
const myDatasetWithAcl = await getSolidDatasetWithAcl(uri, { fetch }); |
|
||||||
|
|
||||||
// Obtain the SolidDataset's own ACL, if available,
|
|
||||||
// or initialise a new one, if possible:
|
|
||||||
let resourceAcl; |
|
||||||
if (!hasResourceAcl(myDatasetWithAcl)) { |
|
||||||
if (!hasAccessibleAcl(myDatasetWithAcl)) { |
|
||||||
return new AccessRuleFetchError( |
|
||||||
uri, |
|
||||||
"The current user does not have permission to change access rights to this Resource.", |
|
||||||
); |
|
||||||
} |
|
||||||
if (!hasFallbackAcl(myDatasetWithAcl)) { |
|
||||||
return new AccessRuleFetchError( |
|
||||||
"The current user does not have permission to see who currently has access to this Resource.", |
|
||||||
); |
|
||||||
} |
|
||||||
resourceAcl = createAclFromFallbackAcl(myDatasetWithAcl); |
|
||||||
} else { |
|
||||||
resourceAcl = getResourceAcl(myDatasetWithAcl); |
|
||||||
} |
|
||||||
|
|
||||||
// Give someone Control access to the given Resource:
|
|
||||||
|
|
||||||
let updatedAcl: AclDataset & WithChangeLog = resourceAcl; |
|
||||||
if (newAccessRules.public) { |
|
||||||
if (isContainer) { |
|
||||||
updatedAcl = setPublicDefaultAccess(updatedAcl, newAccessRules.public); |
|
||||||
} else { |
|
||||||
updatedAcl = setPublicResourceAccess(updatedAcl, newAccessRules.public); |
|
||||||
} |
|
||||||
} |
|
||||||
if (newAccessRules.agent) { |
|
||||||
const setAgentAccess = isContainer |
|
||||||
? setAgentDefaultAccess |
|
||||||
: setAgentResourceAccess; |
|
||||||
Object.entries(newAccessRules.agent).forEach(([webId, rules]) => { |
|
||||||
updatedAcl = setAgentAccess(updatedAcl, webId, rules); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
// Now save the ACL:
|
|
||||||
await saveAclFor(myDatasetWithAcl, updatedAcl, { fetch }); |
|
||||||
return { |
|
||||||
isError: false, |
|
||||||
uri, |
|
||||||
type: "setAccessRuleSuccess", |
|
||||||
}; |
|
||||||
} |
|
@ -1,11 +0,0 @@ |
|||||||
import type { Access } from "@inrupt/solid-client"; |
|
||||||
import type { ResourceSuccess } from "./SuccessResult"; |
|
||||||
|
|
||||||
export interface AccessRule { |
|
||||||
public?: Access; |
|
||||||
agent?: Record<string, Access>; |
|
||||||
} |
|
||||||
|
|
||||||
export interface SetAccessRuleSuccess extends ResourceSuccess { |
|
||||||
type: "setAccessRuleSuccess"; |
|
||||||
} |
|
@ -0,0 +1,19 @@ |
|||||||
|
export interface AccessModeList { |
||||||
|
read: boolean; |
||||||
|
append: boolean; |
||||||
|
write: boolean; |
||||||
|
control: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export interface WacRule { |
||||||
|
public: AccessModeList; |
||||||
|
authenticated: AccessModeList; |
||||||
|
agent: Record<string, AccessModeList>; |
||||||
|
} |
||||||
|
|
||||||
|
// export interface SetWacRule {
|
||||||
|
// ruleFor: Resource;
|
||||||
|
// public?: AccessModeList;
|
||||||
|
// authenticated?: AccessModeList;
|
||||||
|
// agent?: Record<string, AccessModeList>;
|
||||||
|
// }
|
@ -0,0 +1,100 @@ |
|||||||
|
import type { GetWacRuleSuccess } from "./results/GetWacRuleSuccess"; |
||||||
|
import { guaranteeFetch } from "../../util/guaranteeFetch"; |
||||||
|
import type { BasicRequestOptions } from "../../requester/requests/requestOptions"; |
||||||
|
import type { HttpErrorResultType } from "../../requester/results/error/HttpErrorResult"; |
||||||
|
import { HttpErrorResult } from "../../requester/results/error/HttpErrorResult"; |
||||||
|
import type { NoncompliantPodError } from "../../requester/results/error/NoncompliantPodError"; |
||||||
|
import type { UnexpectedResourceError } from "../../requester/results/error/ErrorResult"; |
||||||
|
import { rawTurtleToDataset } from "../../util/rdfUtils"; |
||||||
|
import { AuthorizationShapeType } from "../../.ldo/wac.shapeTypes"; |
||||||
|
import type { AccessModeList, WacRule } from "./WacRule"; |
||||||
|
import type { Authorization } from "../../.ldo/wac.typings"; |
||||||
|
|
||||||
|
export type GetWacRuleError = |
||||||
|
| HttpErrorResultType |
||||||
|
| NoncompliantPodError |
||||||
|
| UnexpectedResourceError; |
||||||
|
export type GetWacRuleResult = GetWacRuleSuccess | GetWacRuleError; |
||||||
|
|
||||||
|
export async function getWacRuleWithAclUri( |
||||||
|
aclUri: string, |
||||||
|
options?: BasicRequestOptions, |
||||||
|
): Promise<GetWacRuleResult> { |
||||||
|
const fetch = guaranteeFetch(options?.fetch); |
||||||
|
const response = await fetch(aclUri); |
||||||
|
const errorResult = HttpErrorResult.checkResponse(aclUri, response); |
||||||
|
if (errorResult) return errorResult; |
||||||
|
|
||||||
|
// Parse Turtle
|
||||||
|
const rawTurtle = await response.text(); |
||||||
|
const rawTurtleResult = await rawTurtleToDataset(rawTurtle, aclUri); |
||||||
|
if (rawTurtleResult.isError) return rawTurtleResult; |
||||||
|
const dataset = rawTurtleResult.dataset; |
||||||
|
const authorizations = dataset |
||||||
|
.usingType(AuthorizationShapeType) |
||||||
|
.matchSubject( |
||||||
|
"http://www.w3.org/1999/02/22-rdf-syntax-ns#type", |
||||||
|
"http://www.w3.org/ns/auth/acl#Authorization", |
||||||
|
); |
||||||
|
|
||||||
|
const wacRule: WacRule = { |
||||||
|
public: { |
||||||
|
read: false, |
||||||
|
write: false, |
||||||
|
append: false, |
||||||
|
control: false, |
||||||
|
}, |
||||||
|
authenticated: { |
||||||
|
read: false, |
||||||
|
write: false, |
||||||
|
append: false, |
||||||
|
control: false, |
||||||
|
}, |
||||||
|
agent: {}, |
||||||
|
}; |
||||||
|
|
||||||
|
function applyAccessModesToList( |
||||||
|
accessModeList: AccessModeList, |
||||||
|
authorization: Authorization, |
||||||
|
): void { |
||||||
|
authorization.mode?.forEach((mode) => { |
||||||
|
accessModeList[mode["@id"].toLowerCase()] = true; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
authorizations.forEach((authorization) => { |
||||||
|
if ( |
||||||
|
authorization.agentClass?.some( |
||||||
|
(agentClass) => agentClass["@id"] === "Agent", |
||||||
|
) |
||||||
|
) { |
||||||
|
applyAccessModesToList(wacRule.public, authorization); |
||||||
|
applyAccessModesToList(wacRule.authenticated, authorization); |
||||||
|
} |
||||||
|
if ( |
||||||
|
authorization.agentClass?.some( |
||||||
|
(agentClass) => agentClass["@id"] === "AuthenticatedAgent", |
||||||
|
) |
||||||
|
) { |
||||||
|
applyAccessModesToList(wacRule.authenticated, authorization); |
||||||
|
} |
||||||
|
authorization.agent?.forEach((agent) => { |
||||||
|
if (!wacRule.agent[agent["@id"]]) { |
||||||
|
wacRule.agent[agent["@id"]] = { |
||||||
|
read: false, |
||||||
|
write: false, |
||||||
|
append: false, |
||||||
|
control: false, |
||||||
|
}; |
||||||
|
} |
||||||
|
applyAccessModesToList(wacRule.agent[agent["@id"]], authorization); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
return { |
||||||
|
type: "getWacRuleSuccess", |
||||||
|
uri: aclUri, |
||||||
|
isError: false, |
||||||
|
wacRule, |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
import type { GetWacUriSuccess } from "./results/GetWacUriSuccess"; |
||||||
|
import type { HttpErrorResultType } from "../../requester/results/error/HttpErrorResult"; |
||||||
|
import { |
||||||
|
HttpErrorResult, |
||||||
|
NotFoundHttpError, |
||||||
|
} from "../../requester/results/error/HttpErrorResult"; |
||||||
|
import { UnexpectedResourceError } from "../../requester/results/error/ErrorResult"; |
||||||
|
import { guaranteeFetch } from "../../util/guaranteeFetch"; |
||||||
|
import type { BasicRequestOptions } from "../../requester/requests/requestOptions"; |
||||||
|
import { NoncompliantPodError } from "../../requester/results/error/NoncompliantPodError"; |
||||||
|
import { parse as parseLinkHeader } from "http-link-header"; |
||||||
|
|
||||||
|
export type GetWacUriError = |
||||||
|
| HttpErrorResultType |
||||||
|
| NotFoundHttpError |
||||||
|
| NoncompliantPodError |
||||||
|
| UnexpectedResourceError; |
||||||
|
export type GetWacUriResult = GetWacUriSuccess | GetWacUriError; |
||||||
|
|
||||||
|
export async function getWacUri( |
||||||
|
resourceUri: string, |
||||||
|
options?: BasicRequestOptions, |
||||||
|
): Promise<GetWacUriResult> { |
||||||
|
try { |
||||||
|
const fetch = guaranteeFetch(options?.fetch); |
||||||
|
const response = await fetch(resourceUri, { |
||||||
|
method: "head", |
||||||
|
}); |
||||||
|
const errorResult = HttpErrorResult.checkResponse(resourceUri, response); |
||||||
|
if (errorResult) return errorResult; |
||||||
|
if (NotFoundHttpError.is(response)) { |
||||||
|
return new NotFoundHttpError( |
||||||
|
resourceUri, |
||||||
|
response, |
||||||
|
"Could not get access control rules because the resource does not exist.", |
||||||
|
); |
||||||
|
} |
||||||
|
// Get the URI from the link header
|
||||||
|
const linkHeader = response.headers.get("link"); |
||||||
|
if (!linkHeader) { |
||||||
|
return new NoncompliantPodError( |
||||||
|
resourceUri, |
||||||
|
"No link header present in request.", |
||||||
|
); |
||||||
|
} |
||||||
|
const parsedLinkHeader = parseLinkHeader(linkHeader); |
||||||
|
const aclUris = parsedLinkHeader.get("rel", "acl"); |
||||||
|
if (aclUris.length !== 1) { |
||||||
|
return new NoncompliantPodError( |
||||||
|
resourceUri, |
||||||
|
`There must be one link with a rel="acl"`, |
||||||
|
); |
||||||
|
} |
||||||
|
return { |
||||||
|
type: "getWacUriSuccess", |
||||||
|
isError: false, |
||||||
|
uri: resourceUri, |
||||||
|
wacUri: aclUris[0].uri, |
||||||
|
}; |
||||||
|
} catch (err: unknown) { |
||||||
|
return UnexpectedResourceError.fromThrown(resourceUri, err); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
import type { ResourceSuccess } from "../../../requester/results/success/SuccessResult"; |
||||||
|
import type { WacRule } from "../WacRule"; |
||||||
|
|
||||||
|
export interface GetWacRuleSuccess extends ResourceSuccess { |
||||||
|
type: "getWacRuleSuccess"; |
||||||
|
wacRule: WacRule; |
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
import type { ResourceSuccess } from "../../../requester/results/success/SuccessResult"; |
||||||
|
|
||||||
|
export interface GetWacUriSuccess extends ResourceSuccess { |
||||||
|
type: "getWacUriSuccess"; |
||||||
|
wacUri: string; |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
import type { ResourceSuccess } from "../../../requester/results/success/SuccessResult"; |
||||||
|
import type { WacRule } from "../WacRule"; |
||||||
|
|
||||||
|
export interface SetWacRuleSuccess extends ResourceSuccess { |
||||||
|
type: "setWacRuleSuccess"; |
||||||
|
wacRule: WacRule; |
||||||
|
} |
Loading…
Reference in new issue