You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.8 KiB
80 lines
2.8 KiB
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,
|
|
);
|
|
}
|
|
|