Hi, I’m trying to create an app with all its data located in /app-folder. As a user I want to give access to other users to read/write to this folder based on their webId. From my understanding, I should use the unviersalAccess package provided by inrupt, but this only has methods for changing access to a specific resource. I want to be able to set access for the folder and all its children. I have also tried using the ‘setAgentDefaultAccess’ from the acl/agent module. When setting the acl it’s seems to have the right accesses, but when I try to read the dataset with the acl later, I get that it has no acl available. Have anyone run into the same problems and know what I’m doing wrong?
The code where I generate the container and set the access:
export async function createAppProfile(
session: Session | null,
name: string = '',
email: string = ''
) {
if (!session) {
throw new Error('No session found');
}
const pod = await getPodUrl(session);
const fullBaseUrl = `${pod}${BASE_APP_CONTAINER}`;
await createContainerAt(fullBaseUrl, {
fetch: session.fetch,
});
const { datasetWithAcl, acl } = await getOrCreateDatasetWithAcl(
fullBaseUrl,
session
);
const newAcl = setAgentResourceAccess(
setAgentDefaultAccess(acl, session.info.webId!, {
read: true,
write: true,
append: true,
control: true,
}),
session.info.webId!,
{ read: true, write: true, append: true, control: true } // Add resource access
);
console.log('[Create profile] New acl: ', newAcl);
await saveAclFor(datasetWithAcl, newAcl, { fetch: session.fetch });
let appProfileSolidDataset = createSolidDataset();
const appProfile = buildThing(createThing({ name: 'profile' }))
.addUrl(RDF.type, PROFILE_SCHEMA.person)
.addStringNoLocale(PROFILE_SCHEMA.name, name)
.addStringNoLocale(PROFILE_SCHEMA.email, email)
.addStringNoLocale(PROFILE_SCHEMA.teamUrl, '')
.build();
appProfileSolidDataset = setThing(appProfileSolidDataset, appProfile);
await saveSolidDatasetAt(
`${pod}/${BASE_APP_CONTAINER}/Profile`,
appProfileSolidDataset,
{ fetch: session.fetch }
);
}
The ‘getOrCreateDatasetWithAcl’ is a function that uses the example code from the docs:
export async function getOrCreateDatasetWithAcl(url: string, session: Session) {
const datasetWithAcl = await getSolidDatasetWithAcl(url, {
fetch: session.fetch,
});
let acl;
if (!hasResourceAcl(datasetWithAcl)) {
if (!hasAccessibleAcl(datasetWithAcl)) {
throw new Error(
'The current user does not have permission to change access rights to this folder.'
);
}
if (!hasFallbackAcl(datasetWithAcl)) {
acl = createAcl(datasetWithAcl);
} else {
acl = createAclFromFallbackAcl(datasetWithAcl);
}
} else {
acl = getResourceAcl(datasetWithAcl);
}
return { datasetWithAcl, acl };
}
From debugging, it looks like this always ends up creating a new acl.
Finally, I have this function that tries to fetch the newly created container with the acl:
async function getPermissions(session: Session) {
const podUrl = await getPodUrl(session);
const { acl } = await getOrCreateDatasetWithAcl(
`${podUrl}${BASE_APP_CONTAINER}`,
session
);
console.log('[Fetch members with permissions] Acl: ', acl);
const res = getAgentDefaultAccessAll(acl);
console.log('[Fetch members with permissions] Res: ', res);
return res;
}
Again, the ‘getOrCreateDatasetWithAcl’ looks to always end up in the block where it creates a new acl, even though I create and save one in the first method