Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support appending to file without read/write access #1521

Open
Otto-AA opened this issue Mar 16, 2022 · 5 comments
Open

Support appending to file without read/write access #1521

Otto-AA opened this issue Mar 16, 2022 · 5 comments
Labels
enhancement New feature request

Comments

@Otto-AA
Copy link
Contributor

Otto-AA commented Mar 16, 2022

Search terms you've used

I've searched for "patch" and "append"

Feature suggestion

The Solid rest-api describes that we can use a PATCH request to append data with SPARQL. I would like to see an implementation of this, which allows appending a Thing to a specific file with only append access.

Expected functionality/enhancement

Something along await appendToFile(url, thing). I'm not very familiar to the solid-client API, so there may be a better solution.

Actual functionality/enhancement

Currently it seems possible to update a file only if one has read and write access.

Use Cases

I would use it to let people append themself to secret groups.

Indirectly this allows granting access to a file shareMe.txt via a link:

  1. create file myGroup where everbody can append, but not read (so the content is secret)
  2. give a group with a cryptographically random name (asdfasdf) access to shareMe.txt
  3. create a Link which contains the random name (https://example-sharer.com/#key=asdfasdf)
  4. anybody with this link can append themself to group asdfasdf and thus has access to shareMe.txt

Additional information

@Otto-AA Otto-AA added the enhancement New feature request label Mar 16, 2022
@Vinnl
Copy link
Contributor

Vinnl commented Mar 17, 2022

solid-client already sends PATCH requests when you build on top of a previously fetched SolidDataset. So if you first fetch the SolidDataset that contains the group, then add people to the group's Thing, then save that SolidDataset again, that should do what you want.

@Otto-AA
Copy link
Contributor Author

Otto-AA commented Mar 19, 2022

Hi Vinnl, thanks for the fast response.

From my testing, saveSolidDatasetAt requires WRITE permissions to the file (and APPEND does not suffice, even if only adding to the file).

I've tested it with the script below which resulted in this output:

success: https://sheep.solidcommunity.net/private/editors.ttl
error: https://sheep.solidcommunity.net/private/posters.ttl - 401
error: https://sheep.solidcommunity.net/private/submitters.ttl - 401

The files are initially empty and have public access to WRITE (editors), READ (posters) and APPEND (posters, subbmitters).

This is the testing script:

const { saveSolidDatasetAt, createSolidDataset, createThing, buildThing, setThing } = require("@inrupt/solid-client")
const { RDF, SCHEMA_INRUPT } = require('@inrupt/vocab-common-rdf')

const main = async () => {
    let courseSolidDataset = createSolidDataset();
    const newBookThing1 = buildThing(createThing({ name: "book2" }))
        .addStringNoLocale(SCHEMA_INRUPT.name, "ABC123 of Example Literature")
        .addUrl(RDF.type, "https://schema.org/Book")
        .build();
    courseSolidDataset = setThing(courseSolidDataset, newBookThing1);

    await testSaving('https://sheep.solidcommunity.net/private/editors.ttl', courseSolidDataset)
    await testSaving('https://sheep.solidcommunity.net/private/posters.ttl', courseSolidDataset)
    await testSaving('https://sheep.solidcommunity.net/private/submitters.ttl', courseSolidDataset)
}

const testSaving = async(url, dataset) => {
    try {
        const savedSolidDataset = await saveSolidDatasetAt(url, dataset);
        console.log(`success: ${url}`)
    } catch (err) {
        console.log(`error: ${url} - ${err.response?.status ?? err.message}`)
    }
}

main()

@Vinnl
Copy link
Contributor

Vinnl commented Mar 19, 2022

@Otto-AA Yes, that's why I said "when you build on top of a previously fetched SolidDataset". You are creating a new SolidDataset every time (createSolidDataset()), so solid-client will attempt to overwrite whatever is already at that location (hence requiring Write permissions). Off the top of my head (i.e. I didn't run this to test), if I change your code to the following, it should only require Append access:

const { saveSolidDatasetAt, createSolidDataset, createThing, buildThing, setThing } = require("@inrupt/solid-client")
const { RDF, SCHEMA_INRUPT } = require('@inrupt/vocab-common-rdf')

const main = async () => {
    let editorsSolidDataset = await getSolidDataset("https://sheep.solidcommunity.net/private/editors.ttl");
    const newBookThing1 = buildThing(createThing({ name: "book2" }))
        .addStringNoLocale(SCHEMA_INRUPT.name, "ABC123 of Example Literature")
        .addUrl(RDF.type, "https://schema.org/Book")
        .build();
    editorsSolidDataset = setThing(editorsSolidDataset, newBookThing1);

    await testSaving('https://sheep.solidcommunity.net/private/editors.ttl', editorsSolidDataset);
}

const testSaving = async(url, dataset) => {
    try {
        const savedSolidDataset = await saveSolidDatasetAt(url, dataset);
        console.log(`success: ${url}`)
    } catch (err) {
        console.log(`error: ${url} - ${err.response?.status ?? err.message}`)
    }
}

main()

@Otto-AA
Copy link
Contributor Author

Otto-AA commented Mar 19, 2022

Sorry if I was not clear enough, or I'm still not getting your point.

As far as I understand your example requires READ access (getSolidDataset fails without READ access). The spec and at least NSS support appending with only APPEND access (even without READ and WRITE). This can be done with a INSERT SPARQL statement I think (but I don't know if this is defined in the spec, or only implemented this way by NSS).

This is what I try to achieve: appending without being able to read or modify existing contents.

@Vinnl
Copy link
Contributor

Vinnl commented Mar 19, 2022

Ah yes, if you want to append without read access, that would indeed need an addition to the API, e.g. something like saveSolidDatasetAt("https://example.com", { forceAppend: true }). (Also note that I don't work on solid-client/at Inrupt any more, so someone else will have to do that 🙂 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature request
Projects
None yet
Development

No branches or pull requests

2 participants