Skip to content

Commit

Permalink
Add ability to load communities from users DWN
Browse files Browse the repository at this point in the history
  • Loading branch information
sondreb committed Nov 8, 2024
1 parent 2e4f977 commit f8c5536
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 23 deletions.
1 change: 1 addition & 0 deletions app/src/app/admin.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export class AdminService {

readonly #APPS: { [key: string]: string } = {
registries: 'did:dht:jtubj7jooigmx9y7dz13j9kxhoy3pyo6jzizh3irkmwity3saxko',
communities: 'did:dht:jtubj7jooigmx9y7dz13j9kxhoy3pyo6jzizh3irkmwity3saxko',
};

readonly #ADMIN_DIDS: string[] = [
Expand Down
17 changes: 14 additions & 3 deletions app/src/app/admin/admin.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@
<div class="margin">
<h2>Communities</h2>
<!-- Add community management buttons here -->
<button mat-button (click)="logRecords()">Log Communities</button>
<!-- <button mat-button (click)="logRecords()">Log Communities</button>
<button mat-button (click)="deleteRegistries()">Delete Communities</button>
<button mat-button (click)="fillRegistries()">Populate Communities</button>
<button mat-button (click)="fillRegistries()">Populate Communities</button> -->
</div>
<div class="margin">
<h2>Owners</h2>
<!-- <button mat-button (click)="logPermissions()">Show Roles</button> -->
<button mat-button (click)="givePermissionsToCommunity()">Give Roles to Admins</button>

@if (roles() && roles().length > 0) {
<h3>User's with roles:</h3>
@for(role of roles(); track role) {
<div>{{ role }}</div>
} }
</div>
</mat-tab>

Expand All @@ -25,7 +36,7 @@ <h2>Admins</h2>
<div class="margin">
<h2>Owners</h2>
<button mat-button (click)="logPermissions()">Show Roles</button>
<button mat-button (click)="givePermissions()">Give Roles to Admins</button>
<button mat-button (click)="givePermissionsToRegistry()">Give Roles to Admins</button>

@if (roles() && roles().length > 0) {
<h3>User's with roles:</h3>
Expand Down
66 changes: 63 additions & 3 deletions app/src/app/admin/admin.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { HttpClient } from '@angular/common/http';
import { registry } from '../../protocols';
import { community } from '../../protocols';
import { AdminService } from '../admin.service';
import { LayoutService } from '../layout.service';
import { IdentityService } from '../identity.service';
Expand Down Expand Up @@ -102,9 +103,15 @@ export class AdminComponent {
}
}

async givePermissions() {
async givePermissionsToRegistry() {
for (let did of this.admin.getAdminDids()) {
await this.givePermission(did);
await this.givePermissionToCommunity(did);
}
}

async givePermissionsToCommunity() {
for (let did of this.admin.getAdminDids()) {
await this.givePermissionToCommunity(did);
}
}

Expand Down Expand Up @@ -184,7 +191,7 @@ export class AdminComponent {
// }
}

async givePermission(did: string) {
async givePermissionToRegistry(did: string) {
// Assign collaborator role to the DID.
const tags = {
role: true,
Expand Down Expand Up @@ -237,6 +244,59 @@ export class AdminComponent {
console.log('Role record:', roleRecord);
}

async givePermissionToCommunity(did: string) {
// Assign collaborator role to the DID.
const tags = {
role: true,
};

// const query = {
// data: {},
// message: {
// tags: tags,
// recipient: collaborator,
// protocol: taskDefinition.protocol,
// parentContextId: record.contextId, // Make the role a child of the list.
// // protocolPath: 'list/collaborator',
// protocolPath: 'list/collaborator',
// schema: taskDefinition.types.collaborator.schema,
// // dataFormat: taskDefinition.types.collaborator.dataFormats[0],
// },
// };

const query = {
store: false,
data: {},
message: {
tags: tags,
recipient: did,
protocol: community.uri,
// parentContextId: record.contextId, // Make the role a child of the list.
// protocolPath: 'list/collaborator',
schema: 'https://schema.ariton.app/community/globalAdmin',
protocolPath: 'globalAdmin',
// protocolRole: 'profile/admin',
// schema: registry.definition.types.profile.dataFormats.types.collaborator.schema,
// dataFormat: taskDefinition.types.collaborator.dataFormats[0],
},
};

console.log('QUERY:', query);

// This will fail if the DID already have a role assigned.
// TODO: Implement a query to see if the user already has role assigned and skip this step.
const { record: roleRecord, status: roleStatus } = await this.identity.web5.dwn.records.create(query);

const ownerDid = this.admin.getIdentifierForApp('communities');
const { status: sendStatus } = await roleRecord!.send(ownerDid);

console.log('Send status:', sendStatus);

console.log('!!!!!');
console.log('Role status:', roleStatus);
console.log('Role record:', roleRecord);
}

async deleteRegistries() {
const did = this.admin.getIdentifierForApp('registries');

Expand Down
6 changes: 6 additions & 0 deletions app/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ export const routes: Routes = [
title: 'Communities',
data: { hide: true, icon: 'diversity_2' },
},
{
path: 'community/:id/:did',
loadComponent: () => import('./community/community.component').then((c) => c.CommunityComponent),
title: 'Communities',
data: { hide: true, icon: 'diversity_2' },
},
{
path: 'friends',
loadComponent: () => import('./friends/friends.component').then((c) => c.FriendsComponent),
Expand Down
14 changes: 14 additions & 0 deletions app/src/app/community/community.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@
<app-profile-header [did]="community()!.data.owners[0]"></app-profile-header>
</mat-card-content>
</mat-card>

@if (admin.isAdmin(identity.did)) {
<mat-card class="discussion-card">
<mat-card-header>
<mat-card-title>Administration</mat-card-title>
<!-- <mat-card-subtitle [matTooltip]="community()!.record.dateCreated"
>Created {{ community()!.record.dateCreated | ago }}</mat-card-subtitle
> -->
</mat-card-header>
<mat-card-content>
<button mat-button (click)="publishCommunity()">Approve Community (Import &amp; Publish)</button>
</mat-card-content>
</mat-card>
}
</div>
</ng-template>
</mat-tab>
Expand Down
22 changes: 20 additions & 2 deletions app/src/app/community/community.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { RecordEntry } from '../data';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatTooltipModule } from '@angular/material/tooltip';
import { ProfileHeaderComponent } from '../shared/components/profile-header/profile-header.component';
import { AdminService } from '../admin.service';
import { IdentityService } from '../identity.service';

@Component({
selector: 'app-community',
Expand Down Expand Up @@ -53,10 +55,16 @@ export class CommunityComponent {

data = inject(DataService);

admin = inject(AdminService);

identity = inject(IdentityService);

selectedCommunity = signal<string | null>(null);

community = signal<RecordEntry<any> | null>(null);

searchingMembers = signal<boolean>(false);

constructor() {
effect(async () => {
if (this.app.initialized() && this.selectedCommunity()) {
Expand All @@ -65,15 +73,20 @@ export class CommunityComponent {
});
}

did = '';

ngOnInit() {
this.layout.marginOff();

this.route.paramMap.subscribe((params) => {
this.layout.resetActions();

const id = params.get('id');
const did = params.get('did');

this.did = did || '';
console.log('Loading community: ', id);
console.log('Loading owner: ', did);

if (!id || id == ':id' || id == 'home') {
this.selectedCommunity.set(null);
Expand Down Expand Up @@ -106,7 +119,12 @@ export class CommunityComponent {
this.photos.set(photos);
}

searchingMembers = signal<boolean>(false);
async publishCommunity() {
const result = await this.community()?.record.import();
// const result = await this.community()?.record.send(this.admin.getIdentifierForApp('communities'));
console.log('Community import status: ', result);
console.log('Publish community');
}

searchMembers() {
this.searchingMembers.set(true);
Expand All @@ -118,7 +136,7 @@ export class CommunityComponent {
}

async loadCommunity() {
const entry = await this.data.get(this.selectedCommunity()!);
const entry = await this.data.get(this.selectedCommunity()!, this.did);
this.community.set(entry);
}
}
4 changes: 2 additions & 2 deletions app/src/app/data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export class DataService {
return this.app.storage.load(this.configuration, tags);
}

async get(recordId: string) {
return this.app.storage.get(recordId);
async get(recordId: string, from: string | null = null) {
return this.app.storage.get(recordId, from);
}

async update(record: Record, data: any, tags: any, published = false) {
Expand Down
10 changes: 8 additions & 2 deletions app/src/app/storage.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,14 @@ export class StorageService {
return list;
}

async get<T>(recordId: string) {
var { record, status } = await this.identity.web5.dwn.records.read({ message: { filter: { recordId } } });
async get<T>(recordId: string, from: string | null = null) {
let query: any = { message: { filter: { recordId } } };

if (from) {
query.from = from;
}

var { record, status } = await this.identity.web5.dwn.records.read(query);

if (status.code !== 200) {
throw new Error(`Failed to get data (${status.code}): ${status.detail}`);
Expand Down
21 changes: 10 additions & 11 deletions app/src/protocols/community.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,38 +27,37 @@ export const protocolDefinition = {
dataFormats: ['text/plain'],
},
globalAdmin: {
schema: 'https://schema.ariton.app/community/schema/globalAdmin',
schema: 'https://schema.ariton.app/community/globalAdmin',
dataFormats: ['application/json'],
},
admin: {
schema: 'https://schema.ariton.app/community/schema/admin',
schema: 'https://schema.ariton.app/community/admin',
dataFormats: ['application/json'],
},
},
structure: {
globalAdmin: {
$role: true,
$actions: [
{
role: 'globalAdmin',
can: ['create', 'read', 'update', 'query', 'subscribe', 'co-update', 'co-delete'],
},
],
},
friend: {
$role: true,
},
community: {
$actions: [
{
role: 'globalAdmin',
can: ['create', 'update'],

//can: ['create', 'read', 'update', 'delete', 'prune', 'co-prune', 'co-delete', 'co-update'],
},
{ role: 'globalAdmin', can: ['create', 'read', 'update', 'query', 'subscribe', 'co-update', 'co-delete'] },
],

admin: {
$role: true,
$actions: [
{
role: 'globalAdmin',
can: ['create', 'update'],

can: ['create', 'read', 'update', 'query', 'subscribe', 'co-update', 'co-delete'],
//can: ['create', 'read', 'update', 'delete', 'prune', 'co-prune', 'co-delete', 'co-update'],
},
],
Expand Down

0 comments on commit f8c5536

Please sign in to comment.