Skip to content

Delegated access example

CI edited this page Apr 2, 2019 · 2 revisions

In this example we demonstrate how identities use the delegated access mechanism to access a resource without being in the resource's sharing group.

The example consists of three parts:

  1. Alice creates a resource for Bob
  2. Charlie requests the delegated access to Bob's identity and Bob authorizes the request
  3. Charlie gets the Bob's resource and decrypts an Alice's message to Bob using the resource
Show code
var DataPeps = require("datapeps-sdk");

global["TextEncoder"] = require("text-encoding").TextEncoder;
global["TextDecoder"] = require("text-encoding").TextDecoder;

global.fetch = require("node-fetch");
global.Headers = global.fetch.Headers;

async function main() {
  let aliceLogin = "aliceliddell";
  let bobLogin = "bobmorane";
  let charlieLogin = "charliebucket";

  // Alice logs in
  let aliceSession = await DataPeps.Session.login(aliceLogin, "aliceP@ssw0rd");

  // Alice creates a resource for herself and Bob
  let resource = await new DataPeps.ResourceAPI(aliceSession).create(
    "text",
    null,
    [bobLogin]
  );

  // Alice encrypts a message to Bob
  let messageToBob = "Hello, Bob!";
  console.log("Alice's message to Bob:", messageToBob);
  let encryptedMessageToBob = resource.encrypt(
    new TextEncoder().encode(messageToBob)
  );

  // Bob logs in
  let bobSession = await DataPeps.Session.login(bobLogin, "bobP@ssw0rd");

  // Bob gets the resource
  let bobResource = await new DataPeps.ResourceAPI(bobSession).get(resource.id);
  console.log("Bob gets the resource");

  // Charlie logs in
  let charlieSession = await DataPeps.Session.login(
    charlieLogin,
    "charlieP@ssw0rd"
  );

  // Charlie cannot get the resource
  let errorOccurred = false;
  try {
    let charlieResource = await new DataPeps.ResourceAPI(charlieSession).get(
      resource.id
    );
  } catch (e) {
    if (
      e instanceof DataPeps.Error &&
      e.kind === DataPeps.ServerError.ResourceNotFound
    ) {
      console.log("Charlie cannot get the resource");
      errorOccurred = true;
    } else throw e;
  }
  if (!errorOccurred) {
    throw "ERROR: Charlie could get the resource";
  }

  // Charlie requests a delegated access from Bob
  let signFunction = ({ login, publicKey }) => {
    let loginBytes = new TextEncoder().encode(login);
    let toSign = new Uint8Array(loginBytes.byteLength + publicKey.byteLength);
    toSign.set(loginBytes, 0);
    toSign.set(publicKey, loginBytes.byteLength);
    let signature = charlieSession.sign(toSign);
    return Promise.resolve({ sign: signature, requester: charlieLogin });
  };
  let charlieAccessRequest = await DataPeps.DelegatedAccess.request(
    bobLogin,
    signFunction
  );

  // Bob accepts Charlie's access request
  let bobAccessResolver = await new DataPeps.DelegatedAccessAPI(
    bobSession
  ).resolveAccessRequest(charlieAccessRequest.id);
  await bobAccessResolver.resolve(bobLogin);

  // Charlie gets the delegated access to Bob's resources
  let bobDelegatedSession = await charlieAccessRequest.waitSession();

  // Charlie gets the resource shared by Alice and Bob
  bobResourceFetchedByCharlie = await new DataPeps.ResourceAPI(
    bobDelegatedSession
  ).get(resource.id);

  // Charlie decrypts the Alice's message to Bob
  let decryptedMessageToBob = bobResourceFetchedByCharlie.decrypt(
    encryptedMessageToBob
  );
  console.log(
    "Alice's message to Bob decrypted by Charlie:",
    new TextDecoder().decode(decryptedMessageToBob)
  );
}

main().catch(e => console.log("An error occurred: ", e));

Running the example

Before running the example make sure you followed the steps described here.

To fetch the code run the following command in the examples directory:

git clone https://gist.github.com/edeea27a13b400ab24fb93c374cdd2a3.git delegating-access

To run this example execute the following command in the examples directory:

node delegating-access/delegating-access.js