Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

Commit

Permalink
Merge pull request #12 from darksoil-studio/viktor
Browse files Browse the repository at this point in the history
incorporation of feedback and added elements
  • Loading branch information
zaunders authored Oct 9, 2024
2 parents b9ccae0 + 0566f00 commit b216c41
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 23 deletions.
98 changes: 98 additions & 0 deletions docs/elements/role-details.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# `<role-detail>`

## Usage

0. If you haven't already, [go through the setup for the module](/setup).

1. Import the `<role-detail>` element somewhere in the javascript side of your web-app like this:

```js
import '@darksoil-studio/roles/dist/elements/role-detail.js'
```

2. Use it in the html side of your web-app like this:

```html
<role-detail>
</role-detail>
```

> [!WARNING]
> Like all the elements in this module, `<role-detail>` needs to be placed inside an initialized `<roles-context>`.
## Demo

Here is an interactive demo of the element:

<element-demo>
</element-demo>



<script setup>
import { onMounted } from "vue";
import { ProfilesClient, ProfilesStore } from '@holochain-open-dev/profiles';
import { demoProfiles, ProfilesZomeMock } from '@holochain-open-dev/profiles/dist/mocks.js';
import { decodeHashFromBase64, encodeHashToBase64 } from '@holochain/client';
import { render } from "lit";
import { html, unsafeStatic } from "lit/static-html.js";

import { RolesZomeMock, sampleRoleClaim } from "../../ui/src/mocks.ts";
import { RolesStore } from "../../ui/src/roles-store.ts";
import { RolesClient } from "../../ui/src/roles-client.ts";

onMounted(async () => {
// Elements need to be imported on the client side, not the SSR side
// Reference: https://vitepress.dev/guide/ssr-compat#importing-in-mounted-hook
await import('@api-viewer/docs/lib/api-docs.js');
await import('@api-viewer/demo/lib/api-demo.js');
await import('@holochain-open-dev/profiles/dist/elements/profiles-context.js');
if (!customElements.get('roles-context')) await import('../../ui/src/elements/roles-context.ts');
if (!customElements.get('role-detail')) await import('../../ui/src/elements/role-detail.ts');

const profiles = await demoProfiles();

const profilesMock = new ProfilesZomeMock(
profiles,
Array.from(profiles.keys())[0]
);
const profilesStore = new ProfilesStore(new ProfilesClient(profilesMock, "roles_test"));

const mock = new RolesZomeMock();
const client = new RolesClient(mock, "roles_test");

const roleClaim = await sampleRoleClaim(client);

const record = await mock.create_role_claim(roleClaim);

const store = new RolesStore(client, {
roles_config: [{
role: 'editor',
singular_name: 'editor',
plural_name: 'editor',
description: 'editor',
}]
});

render(html`
<profiles-context .store=${profilesStore}>
<roles-context .store=${store}>
<api-demo src="custom-elements.json" only="role-detail" exclude-knobs="store">
<template data-element="role-detail" data-target="host">
<role-detail ></role-detail>
</template>
</api-demo>
</roles-context>
</profiles-context>
`, document.querySelector('element-demo'))
})


</script>

## API Reference

`<role-detail>` is a [custom element](https://web.dev/articles/custom-elements-v1), which means that it can be used in any web app or website. Here is the reference for its API:

<api-docs src="custom-elements.json" only="role-detail">
</api-docs>
98 changes: 98 additions & 0 deletions docs/elements/roles-for-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# `<roles-for-agent>`

## Usage

0. If you haven't already, [go through the setup for the module](/setup).

1. Import the `<roles-for-agent>` element somewhere in the javascript side of your web-app like this:

```js
import '@darksoil-studio/roles/dist/elements/roles-for-agent.js'
```

2. Use it in the html side of your web-app like this:

```html
<roles-for-agent>
</roles-for-agent>
```

> [!WARNING]
> Like all the elements in this module, `<roles-for-agent>` needs to be placed inside an initialized `<roles-context>`.
## Demo

Here is an interactive demo of the element:

<element-demo>
</element-demo>



<script setup>
import { onMounted } from "vue";
import { ProfilesClient, ProfilesStore } from '@holochain-open-dev/profiles';
import { demoProfiles, ProfilesZomeMock } from '@holochain-open-dev/profiles/dist/mocks.js';
import { decodeHashFromBase64, encodeHashToBase64 } from '@holochain/client';
import { render } from "lit";
import { html, unsafeStatic } from "lit/static-html.js";

import { RolesZomeMock, sampleRoleClaim } from "../../ui/src/mocks.ts";
import { RolesStore } from "../../ui/src/roles-store.ts";
import { RolesClient } from "../../ui/src/roles-client.ts";

onMounted(async () => {
// Elements need to be imported on the client side, not the SSR side
// Reference: https://vitepress.dev/guide/ssr-compat#importing-in-mounted-hook
await import('@api-viewer/docs/lib/api-docs.js');
await import('@api-viewer/demo/lib/api-demo.js');
await import('@holochain-open-dev/profiles/dist/elements/profiles-context.js');
if (!customElements.get('roles-context')) await import('../../ui/src/elements/roles-context.ts');
if (!customElements.get('roles-for-agent')) await import('../../ui/src/elements/roles-for-agent.ts');

const profiles = await demoProfiles();

const profilesMock = new ProfilesZomeMock(
profiles,
Array.from(profiles.keys())[0]
);
const profilesStore = new ProfilesStore(new ProfilesClient(profilesMock, "roles_test"));

const mock = new RolesZomeMock();
const client = new RolesClient(mock, "roles_test");

const roleClaim = await sampleRoleClaim(client);

const record = await mock.create_role_claim(roleClaim);

const store = new RolesStore(client, {
roles_config: [{
role: 'editor',
singular_name: 'editor',
plural_name: 'editor',
description: 'editor',
}]
});

render(html`
<profiles-context .store=${profilesStore}>
<roles-context .store=${store}>
<api-demo src="custom-elements.json" only="roles-for-agent" exclude-knobs="store">
<template data-element="roles-for-agent" data-target="host">
<roles-for-agent ></roles-for-agent>
</template>
</api-demo>
</roles-context>
</profiles-context>
`, document.querySelector('element-demo'))
})


</script>

## API Reference

`<roles-for-agent>` is a [custom element](https://web.dev/articles/custom-elements-v1), which means that it can be used in any web app or website. Here is the reference for its API:

<api-docs src="custom-elements.json" only="roles-for-agent">
</api-docs>
4 changes: 2 additions & 2 deletions docs/hc_progenitor.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# hc progenitor

## Why
The hc progenitor exists in order for developers to able to instansiate apps with an initial admin inscribed in the happ DNA.
The hc progenitor exists in order for developers to able to instansiate apps in a test environment.

## Using hc progenitor
hc progenitor is using tauri...
hc progenitor is using [tauri](https://tauri.app).
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ features:

This module gives your apps the power of **role management**.

It uses a *progenitor* as initial admin and allows consuming applications to create arbitrary roles and bind the possibility of preforming actions to those roles.
It uses a list of *progenitors* as initial admins and allows consuming applications to create arbitrary roles and bind the possibility of preforming actions to those roles.
38 changes: 18 additions & 20 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,38 @@ To integrate this module into your application:


## Module design
Creating roles in fully peer-to-peer systems can be tricky. There is no node in the network that by default is able to administer the system. In order to introduce rolebased management on Holochain, someone needs to be written into the app as it is generated as the agent that has special rights, this will then be part of the rules of the app that everyone plays by (the DNA).
Creating roles in fully peer-to-peer systems can be tricky. There is no node in the network that by default is able to administer the system. In order to introduce role based management on Holochain, someone needs to be written into the app as it is generated as the agent that has special rights, this will then be part of the rules of the app that everyone plays by (the DNA).

The pattern we are using in this module is the progenitor pattern. This means that the agent that instansiates the DNA writes themselves into the DNA as the original admin. Once an original admin is created, this administrator is able to generate further roles including additional administrators. Administrators are also able to remove all of the roles from Agents (including the Admin role of the progenitor). Below you will find graphical representations of how the module works.
The pattern we are using in this module is the progenitor pattern. This means that the agent that instantiates the DNA writes themselves into the DNA as the original admin. Once an original admin is created, this administrator is able to generate further roles including additional administrators. Administrators are also able to remove all of the roles from Agents (including the Admin role of the progenitor). Below you will find graphical representations of how the module works.

**This pattern creates the requirement of a layer outside the app (like a lobby) where a user is able to create the instanciation of the app so that the public key (AgentPubKey) associated with the original user is encoded into the DNA as it is being created. Read more about this in the implementation considerations section below.**
**This pattern creates the requirement of a layer outside the app (like a lobby) where a user is able to create the instantiation of the app so that the public key (AgentPubKey) associated with the original user is encoded into the DNA as it is being created. Read more about this in the implementation considerations section below.**


### Original administrator (progenitor)
In order to create an initial admin for the app, we are using the progenitor pattern. This means, the creator of the app (of the DNA actually) is the one who is the original admin. More admins can be added like adding any other roles by the progenitor.



```mermaid
graph TD;
Agent --has--> AgentPubKey
Agent --creates--> hApp_DNA
AgentPubKey --included when creating--> hApp_DNA
Agent --joins -->hApp_DNA
Agent --claims--> ADMIN_ROLE
hApp_DNA --validates--> ADMIN_ROLE
sequenceDiagram
Alice ->> Alice: creates new DNA instance (inserting AgentPubKey in DNA details)
create participant happDNA
Alice ->> happDNA: joins app
Alice ->> Alice: claims ADMIN_ROLE at init (creates RoleClaim entry)
happDNA ->> Alice: validates claim (compares Alice to progenitor)
```

### Role assignment
In the diagram below Alice is the progenitor and is therefore granted ADMIN_ROLE when entering the DNA.

```mermaid
graph TD;
Alice -- claims on init --> ADMIN_ROLE
Alice -- creates for Caroline --> admin_role_assignment
Caroline -- uses assignment to claim --> ADMIN_ROLE
Caroline -- (now admin) creates for David --> editor_role_assignment
David -- uses assignment to claim --> EDITOR_ROLE
sequenceDiagram
Alice ->> Alice: claim ADMIN_ROLE on init<br/>(create RoleClaim entry)
create participant Bob
Alice ->> Bob: assign ADMIN_ROLE<br/>(create roleToAsignee link)
Bob ->>Bob: claim ADMIN:ROLE<br/>(create RoleClaim entry)
create participant Caroline
Bob ->> Caroline: assign EDITOR_ROLE<br/>(create roleToAsignee link)
Caroline ->> Caroline: claim EDITOR_ROLE<br/>(create RoleClaim entry)
```

## Design considerations
Expand All @@ -52,4 +50,4 @@ The possibility of actually using the capacities that an app developer is connec
It is implemented in this way in order to be sure that when someone is evaluating if an action is allowed (through a role) from an Agent, that enabling role claim must be found earlier in the source chain of that Agent to become deterministic.

## Implementation considerations
It is very important to understand that if you want to use this module, the instansiators AgentPubKey needs to be inserted into the [DNA properties](https://docs.rs/holochain_types/0.5.0-dev.0/holochain_types/prelude/struct.DnaModifiers.html#structfield.properties). This means that you need to have a running conductor that has access to an AgentPubKey that can be insterted into the app.
It is very important to understand that if you want to use this module, the instantiator's AgentPubKey needs to be inserted into the [DNA properties](https://docs.rs/holochain_types/0.5.0-dev.0/holochain_types/prelude/struct.DnaModifiers.html#structfield.properties). This means that you need to have a running conductor that has access to an AgentPubKey that can be insterted into the app.

0 comments on commit b216c41

Please sign in to comment.