parent
265b3e1c64
commit
6d8ff2515f
@ -0,0 +1,59 @@ |
|||||||
|
import React, { useState, useEffect } from "react"; |
||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import type { Container, LeafUri } from "@ldo/solid"; |
||||||
|
import { useSolidAuth, useLdo } from "@ldo/solid-react"; |
||||||
|
|
||||||
|
export interface BuildMainContainerChildProps { |
||||||
|
mainContainer: Container; |
||||||
|
} |
||||||
|
|
||||||
|
export const BuildMainContainer: FunctionComponent<{ |
||||||
|
child: FunctionComponent<BuildMainContainerChildProps>; |
||||||
|
}> = ({ child }) => { |
||||||
|
const Child = child; |
||||||
|
const [mainContainer, setMainContainer] = useState<Container | undefined>(); |
||||||
|
const { session } = useSolidAuth(); |
||||||
|
const { getResource } = useLdo(); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (session.webId) { |
||||||
|
const webIdResource = getResource(session.webId as LeafUri); |
||||||
|
webIdResource.getRootContainer().then(async (rootContainer) => { |
||||||
|
if (rootContainer.type === "error") { |
||||||
|
alert(rootContainer.message); |
||||||
|
return; |
||||||
|
} |
||||||
|
const mainContainer = |
||||||
|
await rootContainer.createChildIfAbsent("demo-react/"); |
||||||
|
if (mainContainer.type === "error") { |
||||||
|
alert(mainContainer.message); |
||||||
|
return; |
||||||
|
} |
||||||
|
setMainContainer(mainContainer); |
||||||
|
mainContainer.setAccessRules({ |
||||||
|
public: { |
||||||
|
read: true, |
||||||
|
write: false, |
||||||
|
append: false, |
||||||
|
control: false, |
||||||
|
}, |
||||||
|
agent: { |
||||||
|
[session.webId!]: { |
||||||
|
read: true, |
||||||
|
write: true, |
||||||
|
append: true, |
||||||
|
control: true, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
}, [session.webId]); |
||||||
|
|
||||||
|
if (!session.webId || !mainContainer) { |
||||||
|
// Return blank screen
|
||||||
|
return <p>Loading</p>; |
||||||
|
} |
||||||
|
|
||||||
|
return <Child mainContainer={mainContainer} />; |
||||||
|
}; |
@ -1,37 +0,0 @@ |
|||||||
import React, { useState, useEffect } from "react"; |
|
||||||
import type { FunctionComponent } from "react"; |
|
||||||
import type { Container, LeafUri } from "@ldo/solid"; |
|
||||||
import { useSolidAuth, useLdo } from "@ldo/solid-react"; |
|
||||||
|
|
||||||
export interface BuildRootContainerChildProps { |
|
||||||
rootContainer: Container; |
|
||||||
} |
|
||||||
|
|
||||||
export const BuildRootContainer: FunctionComponent<{ |
|
||||||
child: FunctionComponent<BuildRootContainerChildProps>; |
|
||||||
}> = ({ child }) => { |
|
||||||
const Child = child; |
|
||||||
const [rootContainer, setRootContainer] = useState<Container | undefined>(); |
|
||||||
const { session } = useSolidAuth(); |
|
||||||
const { getResource } = useLdo(); |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
if (session.webId) { |
|
||||||
const webIdResource = getResource(session.webId as LeafUri); |
|
||||||
webIdResource.getRootContainer().then((rootContainer) => { |
|
||||||
if (rootContainer.type !== "error") { |
|
||||||
setRootContainer(rootContainer); |
|
||||||
} else { |
|
||||||
alert(rootContainer.message); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
}, [session.webId]); |
|
||||||
|
|
||||||
if (!session.webId || !rootContainer) { |
|
||||||
// Return blank screen
|
|
||||||
return <p>Loading</p>; |
|
||||||
} |
|
||||||
|
|
||||||
return <Child rootContainer={rootContainer} />; |
|
||||||
}; |
|
@ -0,0 +1,51 @@ |
|||||||
|
import type { Access } from "@inrupt/solid-client"; |
||||||
|
import { ErrorResult } from "./ErrorResult"; |
||||||
|
import { RequesterResult } from "./RequesterResult"; |
||||||
|
|
||||||
|
export interface AccessRule { |
||||||
|
public?: Access; |
||||||
|
agent?: Record<string, Access>; |
||||||
|
} |
||||||
|
|
||||||
|
export class AccessRuleChangeResult |
||||||
|
extends RequesterResult |
||||||
|
implements AccessRule |
||||||
|
{ |
||||||
|
type = "accessRuleChange" as const; |
||||||
|
readonly public?: Access; |
||||||
|
readonly agent?: Record<string, Access>; |
||||||
|
|
||||||
|
constructor( |
||||||
|
uri: string, |
||||||
|
publicRules?: Access, |
||||||
|
agentRules?: Record<string, Access>, |
||||||
|
) { |
||||||
|
super(uri); |
||||||
|
this.public = publicRules; |
||||||
|
this.agent = agentRules; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export class AccessRuleResult extends RequesterResult implements AccessRule { |
||||||
|
type = "accessRule" as const; |
||||||
|
readonly public: Access; |
||||||
|
readonly agent: Record<string, Access>; |
||||||
|
|
||||||
|
constructor( |
||||||
|
uri: string, |
||||||
|
publicRules: Access, |
||||||
|
agentRules: Record<string, Access>, |
||||||
|
) { |
||||||
|
super(uri); |
||||||
|
this.public = publicRules; |
||||||
|
this.agent = agentRules; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export class AccessRuleFetchError extends ErrorResult { |
||||||
|
readonly errorType = "accessRuleFetch" as const; |
||||||
|
|
||||||
|
constructor(uri: string, message?: string) { |
||||||
|
super(uri, message || `Cannot get access rules for ${uri}.`); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
import { universalAccess } from "@inrupt/solid-client"; |
||||||
|
import type { |
||||||
|
AccessRuleFetchError, |
||||||
|
AccessRuleResult, |
||||||
|
} from "../requestResults/AccessRule"; |
||||||
|
import type { SimpleRequestParams } from "./requestParams"; |
||||||
|
|
||||||
|
export async function getAccessRules({ |
||||||
|
uri, |
||||||
|
fetch, |
||||||
|
}: SimpleRequestParams): Promise<AccessRuleResult | AccessRuleFetchError> { |
||||||
|
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);
|
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
import type { AclDataset, WithChangeLog } from "@inrupt/solid-client"; |
||||||
|
import { getAgentAccessAll } from "@inrupt/solid-client"; |
||||||
|
import { getPublicAccess } from "@inrupt/solid-client"; |
||||||
|
import { |
||||||
|
getSolidDatasetWithAcl, |
||||||
|
hasResourceAcl, |
||||||
|
hasFallbackAcl, |
||||||
|
hasAccessibleAcl, |
||||||
|
createAclFromFallbackAcl, |
||||||
|
getResourceAcl, |
||||||
|
setAgentResourceAccess, |
||||||
|
saveAclFor, |
||||||
|
setPublicDefaultAccess, |
||||||
|
setPublicResourceAccess, |
||||||
|
setAgentDefaultAccess, |
||||||
|
} from "@inrupt/solid-client"; |
||||||
|
import { isContainerUri } from "../../util/uriTypes"; |
||||||
|
import type { AccessRule } from "../requestResults/AccessRule"; |
||||||
|
import { AccessRuleChangeResult } from "../requestResults/AccessRule"; |
||||||
|
import { AccessRuleFetchError } from "../requestResults/AccessRule"; |
||||||
|
import type { SimpleRequestParams } from "./requestParams"; |
||||||
|
|
||||||
|
export async function setAccessRules( |
||||||
|
{ uri, fetch }: SimpleRequestParams, |
||||||
|
newAccessRules: AccessRule, |
||||||
|
): Promise<AccessRuleChangeResult | AccessRuleFetchError> { |
||||||
|
console.warn("Access Control is stil underdeveloped. Use with caution."); |
||||||
|
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 new AccessRuleChangeResult( |
||||||
|
uri, |
||||||
|
getPublicAccess(myDatasetWithAcl) || undefined, |
||||||
|
getAgentAccessAll(myDatasetWithAcl) || undefined, |
||||||
|
); |
||||||
|
} |
Loading…
Reference in new issue