How to update ACL of binary file

Hi Community!

We are building an app using the inrupt/solid-client library. Essentially I am trying to access a binary file’s ACL but I am failing so far to do so.

I’ve been loosely following this tutorial, but I cannot manage to get it to work with arbitrary files.

When invoking

await getSolidDatasetWithAcl(fileUrl);

The server responds with “Error translating between RDF formats”.

As of now, I am succeeding by invoking

await getFileWithAcl(fileURL)

Now, for the feature I’m trying to implement I would like to manipulate a file’s ACL. Therefore, I’d like to use createAclFromFallbackAcl but to do so, I’d need a resource with the type WithFallbackAcl & WithServerResourceInfo & WithAccessibleAcl. Yet, I am somehow unable to combine all those methods to retrieve the correct dataset.

Does someone have an idea how I could go about doing this?

Thanks in advance!

1 Like

Generally, IIRC, you should be able to follow that tutorial, but replacing every instance of SolidDataset in a function call with File.

So for example, to take the code snippet from “Change Access to a Resource”, that would become something like this:

import {
  getFileWithAcl,
  hasResourceAcl,
  hasAccessibleAcl,
  hasFallbackAcl,
  createAclFromFallbackAcl,
  getResourceAcl,
  setAgentResourceAccess,
  saveAclFor,
} from "@inrupt/solid-client";

async function test() {
  // Fetch the File and its associated ACLs, if available:
  const myFileWithAcl = await getFileWithAcl("https://example.com");
  
  // Obtain the File's own ACL, if available,
  // or initialise a new one, if possible:
  let resourceAcl;
  if (!hasResourceAcl(myFileWithAcl)) {
    if (!hasAccessibleAcl(myFileWithAcl)) {
      throw new Error(
        "The current user does not have permission to change access rights to this Resource."
      );
    }
    if (!hasFallbackAcl(myFileWithAcl)) {
      throw new Error(
        "The current user does not have permission to see who currently has access to this Resource."
      );
      // Alternatively, initialise a new empty ACL as follows,
      // but be aware that if you do not give someone Control access,
      // **nobody will ever be able to change Access permissions in the future**:
      // resourceAcl = createAcl(myFileWithAcl);
    }
    resourceAcl = createAclFromFallbackAcl(myFileWithAcl);
  } else {
    resourceAcl = getResourceAcl(myFileWithAcl);
  }
  
  // Give someone Control access to the given Resource:
  const updatedAcl = setAgentResourceAccess(
    resourceAcl,
    "https://example.com",
    { read: false, append: false, write: false, control: true }
  );
  
  // Now save the ACL:
  await saveAclFor(myFileWithAcl, updatedAcl);
}

(Here, myFileWithAcl is of type WithServerResourceInfo, and the function calls hasAccessibleAcl() and hasFallbackAcl() verify that it is also of types WithAccessibleAcl and WithFallbackAcl, respectively.)

2 Likes

You are absolutely right.

I didn’t think that the hasResourceAcl/hasAccessibleAcl function calls were mandatory but, of course, they are.

That was the reason why I couldn’t get my program to run.

Thank you so much for your help!

1 Like

You may also want to check out the Universal Access APIs: Access Policies: Universal API — Inrupt JavaScript Client Libraries