diff --git a/packages/database/features/groupAccess.feature b/packages/database/features/groupAccess.feature new file mode 100644 index 000000000..075c7ce42 --- /dev/null +++ b/packages/database/features/groupAccess.feature @@ -0,0 +1,36 @@ +Feature: Group content access + User story: + * As a user of the Obsidian plugin + * Logged in through a given space's anonymous account + * I want to be able to create a group including another user outside my space + * giving that user access to my private content + + Acceptance criteria: + * The second user should not have access to the content before I publish my content to the group + * The second user should have access after I publish my content to the group + + Background: + Given the database is blank + And the user user1 opens the Roam plugin in space s1 + And the user user2 opens the Roam plugin in space s2 + + Scenario Outline: Creating content + When Document are added to the database: + | $id | source_local_id | created | last_modified | _author_id | _space_id | + | d1 | ld1 | 2025/01/01 | 2025/01/01 | user1 | s1 | + And Content are added to the database: + | $id | source_local_id | _document_id | text | created | last_modified | scale | _author_id | _space_id | + | ct1 | lct1 | d1 | Claim | 2025/01/01 | 2025/01/01 | document | user1 | s1 | + Then a user logged in space s1 should see 2 PlatformAccount in the database + And a user logged in space s1 should see 1 Content in the database + And a user logged in space s2 should see 2 PlatformAccount in the database + But a user logged in space s2 should see 0 Content in the database + When user of space s1 creates group my_group + And user of space s1 adds space s2 to group my_group + Then a user logged in space s1 should see 1 Content in the database + But a user logged in space s2 should see 0 Content in the database + And ContentAccess are added to the database: + | _account_uid | _content_id | + | my_group | ct1 | + Then a user logged in space s1 should see 1 Content in the database + Then a user logged in space s2 should see 1 Content in the database diff --git a/packages/database/features/step-definitions/stepdefs.ts b/packages/database/features/step-definitions/stepdefs.ts index c7c8bb903..699171475 100644 --- a/packages/database/features/step-definitions/stepdefs.ts +++ b/packages/database/features/step-definitions/stepdefs.ts @@ -64,6 +64,19 @@ Given("the database is blank", async () => { assert.equal(r.error, null); r = await client.from("AgentIdentifier").delete().neq("account_id", -1); assert.equal(r.error, null); + const r3 = await client.from("group_membership").select("group_id"); + assert.equal(r3.error, null); + const groupIds = new Set((r3.data || []).map(({group_id})=>group_id)); + for (const id of groupIds) { + const ur = await client.auth.admin.deleteUser(id); + assert.equal(ur.error, null); + } + const r2 = await client.from("PlatformAccount").select("dg_account").not('dg_account', 'is', 'null'); + assert.equal(r2.error, null); + for (const {dg_account} of r2.data || []) { + const r = await client.auth.admin.deleteUser(dg_account!); + assert.equal(r.error, null); + } r = await client.from("PlatformAccount").delete().neq("id", -1); assert.equal(r.error, null); r = await client.from("Space").delete().neq("id", -1); @@ -389,3 +402,40 @@ Then("query results should look like this", (table: DataTable) => { assert.deepEqual(truncatedResults, values); } }); + +When("user of space {word} creates group {word}", async (spaceName: string, name: string)=>{ + const localRefs = (world.localRefs || {}) as Record; + const spaceId = localRefs[spaceName]; + if (spaceId === undefined) assert.fail("spaceId"); + const client = await getLoggedinDatabase(spaceId as number); + try{ + const response = await client.functions.invoke<{group_id: string}>("create-group", {body:{name}}); + assert.equal(response.error, null); + localRefs[name] = response.data!.group_id; + } catch (error) { + console.error((error as any).actual); + throw error; + } +}) + +When("user of space {word} adds space {word} to group {word}", + async (space1Name: string, space2Name:string, groupName: string)=>{ + const localRefs = (world.localRefs || {}) as Record; + const space1Id = localRefs[space1Name] as number; + const space2Id = localRefs[space2Name] as number; + const groupId = localRefs[groupName] as string; + if (space1Id === undefined) assert.fail("space1Id"); + if (space2Id === undefined) assert.fail("space2Id"); + if (groupId === undefined) assert.fail("groupId"); + const client1 = await getLoggedinDatabase(space1Id as number); + const client2 = await getLoggedinDatabase(space2Id as number); + const r1 = await client2.from("PlatformAccount").select("dg_account").eq("account_local_id", spaceAnonUserEmail("Roam", space2Id)).maybeSingle(); + assert.equal(r1.error, null); + const memberId = r1.data?.dg_account; + assert(!!memberId); + const r2 = await client1.from("group_membership").insert({ + group_id: groupId, + member_id: memberId! + }); + assert.equal(r2.error, null); +})