javascriptsolid

How can I modify Solid Inrupt pod's permissions using javascript


I want to create a new container on a Solid Inrupt Pod but with reading permissions just for my pod's friends. Nobody else can read or write data in that directory.

I've been searching and I know that I have to modify a .acl file to add permissions of reading to a current friend of mine. I share some caps:

acl image

I added uo281997 manually but I want to know how can i add it with javascript and with a list of friends. Here I share a code that creates the container but never changes the .acl permissions: Notes: friends is an array of user webIds; and webId and session of the user

async function createFriendsFolder(friends, webId, session) {
    const folderUrl = webId.replace(
        "/profile/card#me",
        "/public/justforfriends/"
    );

    const folderDataset = await createContainerAt(
        folderUrl,
        {
            fetch: session.fetch,
        },
        {
            acl: {
                read: friends,
                append: [webId],
                write: [webId],
                control: [webId],
            },
        }
    );
    console.log("worked!");
}


Solution

  • Where did you get that acl parameter from? I don't see a third parameter listed in the createContainerAt API reference.

    Instead you'll indeed probably want to follow the docs on changing access. You'd have to create a Dataset with an Access Control List, adding something like this:

    import {
      getSolidDatasetWithAcl,
      hasResourceAcl,
      hasFallbackAcl,
      hasAccessibleAcl,
      createAcl,
      createAclFromFallbackAcl,
      getResourceAcl,
      setAgentResourceAccess,
      saveAclFor,
    } from "@inrupt/solid-client";
    
    // Note: `folderDataset` is from the code you posted, if you remove the third parameter to createContainerAt
    
    // Obtain the folders's own ACL, if available,
    // or initialise a new one, if possible:
    let folderAcl;
    if (!hasResourceAcl(folderDataset)) {
      if (!hasAccessibleAcl(folderDataset)) {
        throw new Error(
          "The current user does not have permission to change access rights to this folder."
        );
      }
      if (!hasFallbackAcl(folderDataset)) {
        // Initialise a new empty ACL
        folderAcl = createAcl(folderDataset);
      } else {
        folderAcl = createAclFromFallbackAcl(folderDataset);
      }
    } else {
      folderAcl = getResourceAcl(folderDataset);
    }
    
    // Give the user at `webId` full access to the folder.
    // DO NOT REMOVE THIS! You will lock yourself out if you do:
    const updatedAcl = setAgentResourceAccess(
      folderAcl,
      webId,
      { read: true, append: true, write: true, control: true }
    );
    friends.forEach(friend => {
      updatedAcl = setAgentResourceAccess(
        updatedAcl,
        friend,
        { read: true, append: false, write: false, control: true }
      )
    });
    
    // Now save the ACL:
    await saveAclFor(folderDataset, updatedAcl);
    

    One important caveat to this is that Inrupt's ESS server (i.e. the one at pod.inrupt.com) at the time of writing does not support this method ("WAC", Web Access Control) of access control, so it won't work there. It has its own proprietary access control protocol ("ACR", Access Control Resources), but that's not supported by other servers. There's also code that's supposed to work with both, but that doesn't due to a bug right now. So not a great situation, sorry.