ibex icon indicating copy to clipboard operation
ibex copied to clipboard

Support for Multiple User PODs

Open rodant opened this issue 4 years ago • 4 comments

A Solid user can reference in his Solid profile document more than one storage. For example I've created a user with the webId:

https://darcy-ibex-spoterme.solid.community/profile/card#me

The profile document of this user looks like this:

@prefix : <#>.
@prefix solid: <http://www.w3.org/ns/solid/terms#>.
@prefix pro: <./>.
@prefix n0: <http://xmlns.com/foaf/0.1/>.
@prefix schem: <http://schema.org/>.
@prefix n1: <http://www.w3.org/ns/auth/acl#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix inbox: </inbox/>.
@prefix sp: <http://www.w3.org/ns/pim/space#>.
@prefix d: </>.
@prefix d0: <https://spoterme-solid-server.herokuapp.com/darcy-ibex/>.

pro:card a n0:PersonalProfileDocument; n0:maker :me; n0:primaryTopic :me.

:me
    a schem:Person, n0:Person;
    n1:trustedApp
    [ n1:mode n1:Append, n1:Read, n1:Write; n1:origin <http://localhost:8080> ];
    ldp:inbox inbox:;
    sp:preferencesFile </settings/prefs.ttl>;
    sp:storage d:, d0:;
    solid:account d:;
    solid:privateTypeIndex </settings/privateTypeIndex.ttl>;
    solid:publicTypeIndex </settings/publicTypeIndex.ttl>;
    n0:name "Darcy Ibex".

Note the triples :me sp:storage d:, d0:; . d0 references a second user storage, in this case located on the spoter.ME backend instance. Through these PIM storage triples any app can discover all the user storages.

I think it is possible to extend Darcy to support another storage different from the canonical one, which is currently constructed from the webId according to the pattern followed by the NSS server. The app could read the whole list specified with the storage predicate and select one or all according to the app logic. I've experimented and chosen the spoter.ME storage if present, otherwise the canonical one.

In darcy.js I wrote a function like this:

...
getPodRoot: async function(webId){
    const rdfStore = $rdf.graph();
    const fetcher = new $rdf.Fetcher(rdfStore);
    const PIM_SPACE = $rdf.Namespace('http://www.w3.org/ns/pim/space#');
    await fetcher.load(webId);
    const spoterPod = rdfStore.each($rdf.sym(webId), PIM_SPACE('storage')).find(
        (s) => {
          const userRoot = s.value;
          return userRoot.startsWith('https://spoterme-solid-server.herokuapp.com/');
        });

    return spoterPod ? spoterPod.value : new URL(webId).origin;
  },
...

This is a very first draft, the spoter.ME server URL can be also be discovered or read from a configuration in a more mature code. The result from this function can be initially stored in the application state along with the webId for example in the variable podRoot and accessed whenever needed for reading and creating posts/comments, main.js:

...
methods:{
    async checkLogin(){

      let vm = this;

      vm.$store.state.session = await window.solid.auth.currentSession(); //Check if logged in into solid
      console.log(vm.$store.state.session);


      if(vm.$store.state.session){ //then populate the storage data if logged in
        vm.$store.state.loggedIn = true;
        vm.$store.state.webID = vm.$store.state.session.webId;
        vm.$store.state.podRoot = await darcy.getPodRoot(vm.$store.state.session.webId);
      }

    }
  },
  created(){
    this.checkLogin()
  }
...

I can prepare the spoter.ME server for testing if you like, I could configure it to always have a POD for the user https://darcy-ibex-spoterme.solid.community/profile/card#me with a public directory as needed by Darcy. The only restriction in the current setup is that everything in the POD get lost after 30 minutes idle time. After a new server start only the user's POD and the directory public will be present. We plan to implement in the next weeks an API to allow the creation of user PODs on our server, an application could perform this action on user confirmation.

Hopping this issue to be useful, bests Antonio.

rodant avatar Jul 22 '20 16:07 rodant