snapshot of https://github.com/ory/keto.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
29
contrib/cat-videos-example/docker-compose.yml
Normal file
29
contrib/cat-videos-example/docker-compose.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
version: "3.2"
|
||||
|
||||
services:
|
||||
keto:
|
||||
image: oryd/keto:v25.4.0
|
||||
working_dir: /home/ory
|
||||
ports:
|
||||
- "4466:4466"
|
||||
- "4467:4467"
|
||||
command: serve -c keto.yml
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- type: bind
|
||||
source: .
|
||||
target: /home/ory
|
||||
|
||||
keto-init:
|
||||
image: oryd/keto:v25.4.0
|
||||
working_dir: /home/ory
|
||||
environment:
|
||||
- KETO_WRITE_REMOTE=keto:4467
|
||||
volumes:
|
||||
- type: bind
|
||||
source: .
|
||||
target: /home/ory
|
||||
command:
|
||||
relation-tuple create
|
||||
./relation-tuples --insecure-disable-transport-security
|
||||
restart: on-failure
|
||||
17
contrib/cat-videos-example/keto.yml
Normal file
17
contrib/cat-videos-example/keto.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
version: v0.6.0-alpha.1
|
||||
|
||||
log:
|
||||
level: debug
|
||||
|
||||
namespaces:
|
||||
location: file://./namespaces.ts
|
||||
|
||||
dsn: memory
|
||||
|
||||
serve:
|
||||
read:
|
||||
host: 0.0.0.0
|
||||
port: 4466
|
||||
write:
|
||||
host: 0.0.0.0
|
||||
port: 4467
|
||||
13
contrib/cat-videos-example/namespaces.ts
Normal file
13
contrib/cat-videos-example/namespaces.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright © 2026 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Context, Namespace, SubjectSet } from "@ory/keto-namespace-types"
|
||||
|
||||
class User implements Namespace {}
|
||||
|
||||
class Video implements Namespace {
|
||||
related: {
|
||||
view: (User | SubjectSet<Video, "owner">)[]
|
||||
owner: User[]
|
||||
}
|
||||
}
|
||||
10
contrib/cat-videos-example/relation-tuples/cats1_owner.json
Normal file
10
contrib/cat-videos-example/relation-tuples/cats1_owner.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"namespace": "Video",
|
||||
"object": "/cats/1.mp4",
|
||||
"relation": "owner",
|
||||
"subject_set": {
|
||||
"namespace": "Video",
|
||||
"object": "/cats",
|
||||
"relation": "owner"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"namespace": "Video",
|
||||
"object": "/cats/1.mp4",
|
||||
"relation": "view",
|
||||
"subject_set": {
|
||||
"namespace": "Video",
|
||||
"object": "/cats/1.mp4",
|
||||
"relation": "owner"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"namespace": "Video",
|
||||
"object": "/cats/1.mp4",
|
||||
"relation": "view",
|
||||
"subject_set": {
|
||||
"namespace": "User",
|
||||
"object": "*"
|
||||
}
|
||||
}
|
||||
10
contrib/cat-videos-example/relation-tuples/cats2_owner.json
Normal file
10
contrib/cat-videos-example/relation-tuples/cats2_owner.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"namespace": "Video",
|
||||
"object": "/cats/2.mp4",
|
||||
"relation": "owner",
|
||||
"subject_set": {
|
||||
"namespace": "Video",
|
||||
"object": "/cats",
|
||||
"relation": "owner"
|
||||
}
|
||||
}
|
||||
10
contrib/cat-videos-example/relation-tuples/cats2_view.json
Normal file
10
contrib/cat-videos-example/relation-tuples/cats2_view.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"namespace": "Video",
|
||||
"object": "/cats/2.mp4",
|
||||
"relation": "view",
|
||||
"subject_set": {
|
||||
"namespace": "Video",
|
||||
"object": "/cats/2.mp4",
|
||||
"relation": "owner"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"namespace": "Video",
|
||||
"object": "/cats",
|
||||
"relation": "owner",
|
||||
"subject_set": {
|
||||
"namespace": "User",
|
||||
"object": "Alice"
|
||||
}
|
||||
}
|
||||
10
contrib/cat-videos-example/relation-tuples/cats_view.json
Normal file
10
contrib/cat-videos-example/relation-tuples/cats_view.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"namespace": "Video",
|
||||
"object": "/cats",
|
||||
"relation": "view",
|
||||
"subject_set": {
|
||||
"namespace": "Video",
|
||||
"object": "/cats",
|
||||
"relation": "owner"
|
||||
}
|
||||
}
|
||||
1
contrib/docs-code-samples/.gitignore
vendored
Normal file
1
contrib/docs-code-samples/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.log
|
||||
23
contrib/docs-code-samples/expand-api-display-access/00-create-tuples/cli.sh
Executable file
23
contrib/docs-code-samples/expand-api-display-access/00-create-tuples/cli.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
echo '// ownership
|
||||
directories:/photos#owner@maureen
|
||||
files:/photos/beach.jpg#owner@maureen
|
||||
files:/photos/mountains.jpg#owner@laura
|
||||
|
||||
// maureen granted access to /photos to laura
|
||||
directories:/photos#access@laura
|
||||
|
||||
// the following tuples are defined implicitly through subject set rewrites (not supported yet)
|
||||
directories:/photos#access@(directories:/photos#owner)
|
||||
files:/photos/beach.jpg#access@(files:/photos/beach.jpg#owner)
|
||||
files:/photos/beach.jpg#access@(directories:/photos#access)
|
||||
files:/photos/mountains.jpg#access@(files:/photos/mountains.jpg#owner)
|
||||
files:/photos/mountains.jpg#access@(directories:/photos#access)' | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
keto relation-tuple create -f - --insecure-disable-transport-security >/dev/null \
|
||||
&& echo "Successfully created tuples" \
|
||||
|| echo "Encountered error"
|
||||
26
contrib/docs-code-samples/expand-api-display-access/00-create-tuples/curl.sh
Executable file
26
contrib/docs-code-samples/expand-api-display-access/00-create-tuples/curl.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo '// ownership
|
||||
directories:/photos#owner@maureen
|
||||
files:/photos/beach.jpg#owner@maureen
|
||||
files:/photos/mountains.jpg#owner@laura
|
||||
|
||||
// maureen granted access to /photos to laura
|
||||
directories:/photos#access@laura
|
||||
|
||||
// the following tuples are defined implicitly through subject set rewrites (not supported yet)
|
||||
directories:/photos#access@(directories:/photos#owner)
|
||||
files:/photos/beach.jpg#access@(files:/photos/beach.jpg#owner)
|
||||
files:/photos/beach.jpg#access@(directories:/photos#access)
|
||||
files:/photos/mountains.jpg#access@(files:/photos/mountains.jpg#owner)
|
||||
files:/photos/mountains.jpg#access@(directories:/photos#access)' | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
jq "[ .[] | { relation_tuple: . , action: \"insert\" } ]" -c | \
|
||||
curl -X PATCH --silent --fail \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data @- \
|
||||
http://127.0.0.1:4467/admin/relation-tuples
|
||||
|
||||
echo "Successfully created tuples"
|
||||
@@ -0,0 +1 @@
|
||||
Successfully created tuples
|
||||
@@ -0,0 +1,92 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, write, writeService } from "@ory/keto-grpc-client"
|
||||
|
||||
const writeClient = new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const writeRequest = new write.TransactRelationTuplesRequest()
|
||||
|
||||
const insert = (tuple) => {
|
||||
const tupleDelta = new write.RelationTupleDelta()
|
||||
tupleDelta.setAction(write.RelationTupleDelta.Action.ACTION_INSERT)
|
||||
tupleDelta.setRelationTuple(tuple)
|
||||
|
||||
writeRequest.addRelationTupleDeltas(tupleDelta)
|
||||
}
|
||||
|
||||
const addSimpleTuple = (namespace, object, relation, user) => {
|
||||
const relationTuple = new relationTuples.RelationTuple()
|
||||
relationTuple.setNamespace(namespace)
|
||||
relationTuple.setObject(object)
|
||||
relationTuple.setRelation(relation)
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setId(user)
|
||||
relationTuple.setSubject(sub)
|
||||
|
||||
insert(relationTuple)
|
||||
}
|
||||
|
||||
// ownership
|
||||
addSimpleTuple("directories", "/photos", "owner", "maureen")
|
||||
addSimpleTuple("files", "/photos/beach.jpg", "owner", "maureen")
|
||||
addSimpleTuple("files", "/photos/mountains.jpg", "owner", "laura")
|
||||
// granted access
|
||||
addSimpleTuple("directories", "/photos", "access", "laura")
|
||||
|
||||
// should be subject set rewrite
|
||||
// owners have access
|
||||
;[
|
||||
["files", "/photos/beach.jpg"],
|
||||
["files", "/photos/mountains.jpg"],
|
||||
["directories", "/photos"],
|
||||
].forEach(([namespace, object]) => {
|
||||
const relationTuple = new relationTuples.RelationTuple()
|
||||
relationTuple.setNamespace(namespace)
|
||||
relationTuple.setObject(object)
|
||||
relationTuple.setRelation("access")
|
||||
|
||||
const subjectSet = new relationTuples.SubjectSet()
|
||||
subjectSet.setNamespace(namespace)
|
||||
subjectSet.setObject(object)
|
||||
subjectSet.setRelation("owner")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setSet(subjectSet)
|
||||
relationTuple.setSubject(sub)
|
||||
|
||||
insert(relationTuple)
|
||||
})
|
||||
|
||||
// should be subject set rewrite
|
||||
// access on parent means access on child
|
||||
;["/photos/beach.jpg", "/photos/mountains.jpg"].forEach((file) => {
|
||||
const relationTuple = new relationTuples.RelationTuple()
|
||||
relationTuple.setNamespace("files")
|
||||
relationTuple.setObject(file)
|
||||
relationTuple.setRelation("access")
|
||||
|
||||
const subjectSet = new relationTuples.SubjectSet()
|
||||
subjectSet.setNamespace("directories")
|
||||
subjectSet.setObject("/photos")
|
||||
subjectSet.setRelation("access")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setSet(subjectSet)
|
||||
relationTuple.setSubject(sub)
|
||||
|
||||
insert(relationTuple)
|
||||
})
|
||||
|
||||
writeClient.transactRelationTuples(writeRequest, (error) => {
|
||||
if (error) {
|
||||
console.log("Encountered error", error)
|
||||
} else {
|
||||
console.log("Successfully created tuples")
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic("Encountered error: " + err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewWriteServiceClient(conn)
|
||||
|
||||
//directories:/photos#owner@maureen
|
||||
//files:/photos/beach.jpg#owner@maureen
|
||||
//files:/photos/mountains.jpg#owner@laura
|
||||
//directories:/photos#access@laura
|
||||
//directories:/photos#access@(directories:/photos#owner)
|
||||
//files:/photos/beach.jpg#access@(files:/photos/beach.jpg#owner)
|
||||
//files:/photos/beach.jpg#access@(directories:/photos#access)
|
||||
//files:/photos/mountains.jpg#access@(files:/photos/mountains.jpg#owner)
|
||||
//files:/photos/mountains.jpg#access@(directories:/photos#access)
|
||||
|
||||
tuples := []*rts.RelationTuple{
|
||||
// ownership
|
||||
{
|
||||
Namespace: "directories",
|
||||
Object: "/photos",
|
||||
Relation: "owner",
|
||||
Subject: rts.NewSubjectID("maureen"),
|
||||
},
|
||||
{
|
||||
Namespace: "files",
|
||||
Object: "/photos/beach.jpg",
|
||||
Relation: "owner",
|
||||
Subject: rts.NewSubjectID("maureen"),
|
||||
},
|
||||
{
|
||||
Namespace: "files",
|
||||
Object: "/photos/mountains.jpg",
|
||||
Relation: "owner",
|
||||
Subject: rts.NewSubjectID("laura"),
|
||||
},
|
||||
// granted access
|
||||
{
|
||||
Namespace: "directories",
|
||||
Object: "/photos",
|
||||
Relation: "access",
|
||||
Subject: rts.NewSubjectID("laura"),
|
||||
},
|
||||
}
|
||||
// should be subject set rewrite
|
||||
// owners have access
|
||||
for _, o := range []struct{ n, o string }{
|
||||
{"files", "/photos/beach.jpg"},
|
||||
{"files", "/photos/mountains.jpg"},
|
||||
{"directories", "/photos"},
|
||||
} {
|
||||
tuples = append(tuples, &rts.RelationTuple{
|
||||
Namespace: o.n,
|
||||
Object: o.o,
|
||||
Relation: "access",
|
||||
Subject: rts.NewSubjectSet(o.n, o.o, "owner"),
|
||||
})
|
||||
}
|
||||
// should be subject set rewrite
|
||||
// access on parent means access on child
|
||||
for _, obj := range []string{"/photos/beach.jpg", "/photos/mountains.jpg"} {
|
||||
tuples = append(tuples, &rts.RelationTuple{
|
||||
Namespace: "files",
|
||||
Object: obj,
|
||||
Relation: "access",
|
||||
Subject: rts.NewSubjectSet("directories", "/photos", "access"),
|
||||
})
|
||||
}
|
||||
|
||||
_, err = client.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: rts.RelationTupleToDeltas(tuples, rts.RelationTupleDelta_ACTION_INSERT),
|
||||
})
|
||||
if err != nil {
|
||||
panic("Encountered error: " + err.Error())
|
||||
}
|
||||
|
||||
fmt.Println("Successfully created tuples")
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
|
||||
keto expand access files:/photos/beach.jpg --format json-pretty --max-depth 3 --insecure-disable-transport-security
|
||||
11
contrib/docs-code-samples/expand-api-display-access/01-expand-beach/curl.sh
Executable file
11
contrib/docs-code-samples/expand-api-display-access/01-expand-beach/curl.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=files" \
|
||||
--data-urlencode "relation=access" \
|
||||
--data-urlencode "object=/photos/beach.jpg" \
|
||||
--data-urlencode "max-depth=3" \
|
||||
http://127.0.0.1:4466/relation-tuples/expand | \
|
||||
jq
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"tuple": {
|
||||
"namespace": "",
|
||||
"object": "",
|
||||
"relation": "",
|
||||
"subject_id": "maureen"
|
||||
},
|
||||
"type": "leaf"
|
||||
}
|
||||
],
|
||||
"tuple": {
|
||||
"namespace": "",
|
||||
"object": "",
|
||||
"relation": "",
|
||||
"subject_set": {
|
||||
"namespace": "files",
|
||||
"object": "/photos/beach.jpg",
|
||||
"relation": "owner"
|
||||
}
|
||||
},
|
||||
"type": "union"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"tuple": {
|
||||
"namespace": "",
|
||||
"object": "",
|
||||
"relation": "",
|
||||
"subject_id": "laura"
|
||||
},
|
||||
"type": "leaf"
|
||||
},
|
||||
{
|
||||
"tuple": {
|
||||
"namespace": "",
|
||||
"object": "",
|
||||
"relation": "",
|
||||
"subject_set": {
|
||||
"namespace": "directories",
|
||||
"object": "/photos",
|
||||
"relation": "owner"
|
||||
}
|
||||
},
|
||||
"type": "leaf"
|
||||
}
|
||||
],
|
||||
"tuple": {
|
||||
"namespace": "",
|
||||
"object": "",
|
||||
"relation": "",
|
||||
"subject_set": {
|
||||
"namespace": "directories",
|
||||
"object": "/photos",
|
||||
"relation": "access"
|
||||
}
|
||||
},
|
||||
"type": "union"
|
||||
}
|
||||
],
|
||||
"tuple": {
|
||||
"namespace": "",
|
||||
"object": "",
|
||||
"relation": "",
|
||||
"subject_set": {
|
||||
"namespace": "files",
|
||||
"object": "/photos/beach.jpg",
|
||||
"relation": "access"
|
||||
}
|
||||
},
|
||||
"type": "union"
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, expand, expandService } from "@ory/keto-grpc-client"
|
||||
|
||||
const expandClient = new expandService.ExpandServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const subjectSet = new relationTuples.SubjectSet()
|
||||
subjectSet.setNamespace("files")
|
||||
subjectSet.setRelation("access")
|
||||
subjectSet.setObject("/photos/beach.jpg")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setSet(subjectSet)
|
||||
|
||||
const expandRequest = new expand.ExpandRequest()
|
||||
expandRequest.setSubject(sub)
|
||||
expandRequest.setMaxDepth(3)
|
||||
|
||||
// helper to get a nice result
|
||||
const subjectJSON = (subject) => {
|
||||
if (subject.hasId()) {
|
||||
return { subject_id: subject.getId() }
|
||||
}
|
||||
const set = subject.getSet()
|
||||
return {
|
||||
subject_set: {
|
||||
namespace: set.getNamespace(),
|
||||
object: set.getObject(),
|
||||
relation: set.getRelation(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// helper to get a nice result
|
||||
const prettyTree = (tree) => {
|
||||
const [nodeType, tuple, children] = [
|
||||
tree.getNodeType(),
|
||||
{
|
||||
tuple: {
|
||||
namespace: "",
|
||||
object: "",
|
||||
relation: "",
|
||||
...subjectJSON(tree.getSubject()),
|
||||
},
|
||||
},
|
||||
tree.getChildrenList(),
|
||||
]
|
||||
switch (nodeType) {
|
||||
case expand.NodeType.NODE_TYPE_LEAF:
|
||||
return { type: "leaf", ...tuple }
|
||||
case expand.NodeType.NODE_TYPE_UNION: {
|
||||
const mapped = children.map(prettyTree)
|
||||
return mapped.length > 0
|
||||
? { type: "union", children: mapped, ...tuple }
|
||||
: { type: "union", ...tuple }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expandClient.expand(expandRequest, (error, resp) => {
|
||||
if (error) {
|
||||
console.log("Encountered error:", error)
|
||||
} else {
|
||||
console.log(JSON.stringify(prettyTree(resp.getTree()), null, 2))
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
"github.com/ory/keto/ketoapi"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
client := rts.NewExpandServiceClient(conn)
|
||||
|
||||
res, err := client.Expand(context.Background(), &rts.ExpandRequest{
|
||||
Subject: rts.NewSubjectSet("files", "/photos/beach.jpg", "access"),
|
||||
MaxDepth: 3,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
tree := ketoapi.TreeFromProto[*ketoapi.RelationTuple](res.Tree)
|
||||
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", " ")
|
||||
if err := enc.Encode(tree); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
||||
13
contrib/docs-code-samples/expand-api-display-access/99-cleanup/cli.sh
Executable file
13
contrib/docs-code-samples/expand-api-display-access/99-cleanup/cli.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
keto relation-tuple get --namespace files --format json --insecure-disable-transport-security | \
|
||||
jq ".relation_tuples" | \
|
||||
keto relation-tuple delete --insecure-disable-transport-security -f - -q > /dev/null
|
||||
|
||||
keto relation-tuple get --namespace directories --format json --insecure-disable-transport-security | \
|
||||
jq ".relation_tuples" | \
|
||||
keto relation-tuple delete --insecure-disable-transport-security -f - -q > /dev/null
|
||||
27
contrib/docs-code-samples/expand-api-display-access/99-cleanup/curl.sh
Executable file
27
contrib/docs-code-samples/expand-api-display-access/99-cleanup/curl.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=files" \
|
||||
http://127.0.0.1:4466/relation-tuples | \
|
||||
jq "[ .relation_tuples[] | { relation_tuple: . , action: \"delete\" } ]" -c | \
|
||||
curl -X PATCH --silent --fail \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data @- \
|
||||
http://127.0.0.1:4467/admin/relation-tuples
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=directories" \
|
||||
http://127.0.0.1:4466/relation-tuples | \
|
||||
jq "[ .relation_tuples[] | { relation_tuple: . , action: \"delete\" } ]" -c | \
|
||||
curl -X PATCH --silent --fail \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data @- \
|
||||
http://127.0.0.1:4467/admin/relation-tuples
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, write, writeService } from "@ory/keto-grpc-client"
|
||||
|
||||
const purgeNamespace = (namespace) => {
|
||||
const query = new relationTuples.RelationQuery()
|
||||
query.setNamespace(namespace)
|
||||
const request = new write.DeleteRelationTuplesRequest()
|
||||
request.setRelationQuery(query)
|
||||
new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
).deleteRelationTuples(request, (err) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
purgeNamespace("files")
|
||||
purgeNamespace("directories")
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build docscodesamples
|
||||
// +build docscodesamples
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func purgeNamespace(nspace string) {
|
||||
rc, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
rClient := rts.NewReadServiceClient(rc)
|
||||
resp, err := rClient.ListRelationTuples(context.Background(), &rts.ListRelationTuplesRequest{
|
||||
Query: &rts.ListRelationTuplesRequest_Query{
|
||||
Namespace: nspace,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
wc, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer wc.Close()
|
||||
|
||||
deltas := make([]*rts.RelationTupleDelta, len(resp.RelationTuples))
|
||||
for i, rt := range resp.RelationTuples {
|
||||
deltas[i] = &rts.RelationTupleDelta{
|
||||
Action: rts.RelationTupleDelta_ACTION_DELETE,
|
||||
RelationTuple: proto.Clone(rt).(*rts.RelationTuple),
|
||||
}
|
||||
}
|
||||
|
||||
wClient := rts.NewWriteServiceClient(wc)
|
||||
_, err = wClient.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: deltas,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
purgeNamespace("directories")
|
||||
purgeNamespace("files")
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
dsn: memory
|
||||
log:
|
||||
level: trace
|
||||
|
||||
namespaces:
|
||||
- name: files
|
||||
id: 1
|
||||
- name: directories
|
||||
id: 2
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
echo 'Chat:memes#member@User:PM
|
||||
Chat:memes#member@User:Vincent
|
||||
Chat:memes#member@User:Julia
|
||||
|
||||
Chat:cars#member@User:PM
|
||||
Chat:cars#member@User:Julia
|
||||
|
||||
Chat:coffee-break#member@User:PM
|
||||
Chat:coffee-break#member@User:Vincent
|
||||
Chat:coffee-break#member@User:Julia
|
||||
Chat:coffee-break#member@User:Patrik' | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
keto relation-tuple create -f - >/dev/null --insecure-disable-transport-security \
|
||||
&& echo "Successfully created tuples" \
|
||||
|| echo "Encountered error"
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo 'Chat:memes#member@User:PM
|
||||
Chat:memes#member@User:Vincent
|
||||
Chat:memes#member@User:Julia
|
||||
|
||||
Chat:cars#member@User:PM
|
||||
Chat:cars#member@User:Julia
|
||||
|
||||
Chat:coffee-break#member@User:PM
|
||||
Chat:coffee-break#member@User:Vincent
|
||||
Chat:coffee-break#member@User:Julia
|
||||
Chat:coffee-break#member@User:Patrik' | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
jq "[ .[] | { relation_tuple: . , action: \"insert\" } ]" -c | \
|
||||
curl -X PATCH --silent --fail \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data @- \
|
||||
http://127.0.0.1:4467/admin/relation-tuples
|
||||
|
||||
echo "Successfully created tuples"
|
||||
@@ -0,0 +1 @@
|
||||
Successfully created tuples
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, write, writeService } from "@ory/keto-grpc-client"
|
||||
|
||||
const writeClient = new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const writeRequest = new write.TransactRelationTuplesRequest()
|
||||
|
||||
const addToChat = (chatName) => (user) => {
|
||||
const relationTuple = new relationTuples.RelationTuple()
|
||||
relationTuple.setNamespace("Chat")
|
||||
relationTuple.setObject(chatName)
|
||||
relationTuple.setRelation("member")
|
||||
|
||||
const subSet = new relationTuples.SubjectSet()
|
||||
subSet.setNamespace("User")
|
||||
subSet.setObject(user)
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setSet(subSet)
|
||||
relationTuple.setSubject(sub)
|
||||
|
||||
const tupleDelta = new write.RelationTupleDelta()
|
||||
tupleDelta.setAction(write.RelationTupleDelta.Action.ACTION_INSERT)
|
||||
tupleDelta.setRelationTuple(relationTuple)
|
||||
|
||||
writeRequest.addRelationTupleDeltas(tupleDelta)
|
||||
}
|
||||
|
||||
;["PM", "Vincent", "Julia"].forEach(addToChat("memes"))
|
||||
;["PM", "Julia"].forEach(addToChat("cars"))
|
||||
;["PM", "Vincent", "Julia", "Patrik"].forEach(addToChat("coffee-break"))
|
||||
|
||||
writeClient.transactRelationTuples(writeRequest, (error) => {
|
||||
if (error) {
|
||||
console.log("Encountered error", error)
|
||||
} else {
|
||||
console.log("Successfully created tuples")
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic("Encountered error: " + err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewWriteServiceClient(conn)
|
||||
|
||||
var tuples []*rts.RelationTuple
|
||||
// memes
|
||||
for _, user := range []string{"PM", "Vincent", "Julia"} {
|
||||
tuples = append(tuples, &rts.RelationTuple{
|
||||
Namespace: "Chat",
|
||||
Object: "memes",
|
||||
Relation: "member",
|
||||
Subject: rts.NewSubjectSet("User", user, ""),
|
||||
})
|
||||
}
|
||||
// cars
|
||||
for _, user := range []string{"PM", "Julia"} {
|
||||
tuples = append(tuples, &rts.RelationTuple{
|
||||
Namespace: "Chat",
|
||||
Object: "cars",
|
||||
Relation: "member",
|
||||
Subject: rts.NewSubjectSet("User", user, ""),
|
||||
})
|
||||
}
|
||||
// coffee-break
|
||||
for _, user := range []string{"PM", "Vincent", "Julia", "Patrik"} {
|
||||
tuples = append(tuples, &rts.RelationTuple{
|
||||
Namespace: "Chat",
|
||||
Object: "coffee-break",
|
||||
Relation: "member",
|
||||
Subject: rts.NewSubjectSet("User", user, ""),
|
||||
})
|
||||
}
|
||||
|
||||
_, err = client.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: rts.RelationTupleToDeltas(tuples, rts.RelationTupleDelta_ACTION_INSERT),
|
||||
})
|
||||
if err != nil {
|
||||
panic("Encountered error: " + err.Error())
|
||||
}
|
||||
|
||||
fmt.Println("Successfully created tuples")
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
|
||||
keto relation-tuple get --namespace Chat --relation member --subject-set User:PM --format json --insecure-disable-transport-security | \
|
||||
jq ".relation_tuples[] | .object" -r | sort
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=Chat" \
|
||||
--data-urlencode "relation=member" \
|
||||
--data-urlencode "subject_set.namespace=User" \
|
||||
--data-urlencode "subject_set.object=PM" \
|
||||
--data-urlencode "subject_set.relation=" \
|
||||
http://127.0.0.1:4466/relation-tuples | \
|
||||
jq ".relation_tuples[] | .object" -r | sort
|
||||
@@ -0,0 +1,3 @@
|
||||
cars
|
||||
coffee-break
|
||||
memes
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, read, readService } from "@ory/keto-grpc-client"
|
||||
|
||||
const readClient = new readService.ReadServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const readRequest = new read.ListRelationTuplesRequest()
|
||||
const query = new read.ListRelationTuplesRequest.Query()
|
||||
query.setNamespace("Chat")
|
||||
query.setRelation("member")
|
||||
|
||||
const subSet = new relationTuples.SubjectSet()
|
||||
subSet.setNamespace("User")
|
||||
subSet.setObject("PM")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setSet(subSet)
|
||||
query.setSubject(sub)
|
||||
|
||||
readRequest.setQuery(query)
|
||||
|
||||
readClient.listRelationTuples(readRequest, (error, resp) => {
|
||||
if (error) {
|
||||
console.log("Encountered error:", error)
|
||||
} else {
|
||||
console.log(
|
||||
resp
|
||||
.getRelationTuplesList()
|
||||
.map((tuple) => tuple.getObject())
|
||||
.sort((a, b) => (a < b ? -1 : 1))
|
||||
.join("\n"),
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewReadServiceClient(conn)
|
||||
|
||||
res, err := client.ListRelationTuples(context.Background(), &rts.ListRelationTuplesRequest{
|
||||
RelationQuery: &rts.RelationQuery{
|
||||
Namespace: new("Chat"),
|
||||
Relation: new("member"),
|
||||
Subject: rts.NewSubjectSet("User", "PM", ""),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
objects := make([]string, len(res.RelationTuples))
|
||||
for i, rt := range res.RelationTuples {
|
||||
objects[i] = rt.Object
|
||||
}
|
||||
sort.Strings(objects)
|
||||
for _, o := range objects {
|
||||
fmt.Println(o)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
|
||||
keto relation-tuple get --namespace Chat --object coffee-break --relation member --format json --insecure-disable-transport-security | \
|
||||
jq "[.relation_tuples[] | .subject_set.object] | sort | .[]" -r
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=Chat" \
|
||||
--data-urlencode "object=coffee-break" \
|
||||
--data-urlencode "relation=member" \
|
||||
http://127.0.0.1:4466/relation-tuples | \
|
||||
jq "[.relation_tuples[] | .subject_set.object] | sort | .[]" -r
|
||||
@@ -0,0 +1,4 @@
|
||||
Julia
|
||||
PM
|
||||
Patrik
|
||||
Vincent
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { read, readService } from "@ory/keto-grpc-client"
|
||||
|
||||
const readClient = new readService.ReadServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const readRequest = new read.ListRelationTuplesRequest()
|
||||
const query = new read.ListRelationTuplesRequest.Query()
|
||||
query.setNamespace("Chat")
|
||||
query.setObject("coffee-break")
|
||||
query.setRelation("member")
|
||||
|
||||
readRequest.setQuery(query)
|
||||
|
||||
readClient.listRelationTuples(readRequest, (error, resp) => {
|
||||
if (error) {
|
||||
console.log("Encountered error:", error)
|
||||
} else {
|
||||
console.log(
|
||||
resp
|
||||
.getRelationTuplesList()
|
||||
.map((tuple) => tuple.getSubject().getSet().getObject())
|
||||
.sort((a, b) => (a < b ? -1 : 1))
|
||||
.join("\n"),
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewReadServiceClient(conn)
|
||||
|
||||
res, err := client.ListRelationTuples(context.Background(), &rts.ListRelationTuplesRequest{
|
||||
RelationQuery: &rts.RelationQuery{
|
||||
Namespace: new("Chat"),
|
||||
Object: new("coffee-break"),
|
||||
Relation: new("member"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
ids := make([]string, len(res.RelationTuples))
|
||||
for i, rt := range res.RelationTuples {
|
||||
ids[i] = rt.Subject.Ref.(*rts.Subject_Set).Set.Object
|
||||
}
|
||||
sort.Strings(ids)
|
||||
for _, id := range ids {
|
||||
fmt.Println(id)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
keto relation-tuple get --namespace Chat --format json --insecure-disable-transport-security | \
|
||||
jq ".relation_tuples" | \
|
||||
keto relation-tuple delete -f - -q > /dev/null --insecure-disable-transport-security
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=Chat" \
|
||||
http://127.0.0.1:4466/relation-tuples | \
|
||||
jq "[ .relation_tuples[] | { relation_tuple: . , action: \"delete\" } ]" -c | \
|
||||
curl -X PATCH --silent --fail \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data @- \
|
||||
http://127.0.0.1:4467/admin/relation-tuples
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { write, writeService, read, readService } from "@ory/keto-grpc-client"
|
||||
|
||||
const readClient = new readService.ReadServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const query = new read.ListRelationTuplesRequest.Query()
|
||||
query.setNamespace("Chat")
|
||||
|
||||
const readRequest = new read.ListRelationTuplesRequest()
|
||||
readRequest.setQuery(query)
|
||||
|
||||
readClient.listRelationTuples(readRequest, (err, resp) => {
|
||||
const writeClient = new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const writeRequest = new write.TransactRelationTuplesRequest()
|
||||
|
||||
resp.getRelationTuplesList().forEach((tuple) => {
|
||||
const tupleDelta = new write.RelationTupleDelta()
|
||||
tupleDelta.setAction(write.RelationTupleDelta.Action.ACTION_DELETE)
|
||||
tupleDelta.setRelationTuple(tuple)
|
||||
writeRequest.addRelationTupleDeltas(tupleDelta)
|
||||
})
|
||||
|
||||
writeClient.transactRelationTuples(writeRequest, (err) => {
|
||||
if (err) {
|
||||
console.log("Unexpected err", err)
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build docscodesamples
|
||||
// +build docscodesamples
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rc, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
rClient := rts.NewReadServiceClient(rc)
|
||||
resp, err := rClient.ListRelationTuples(context.Background(), &rts.ListRelationTuplesRequest{
|
||||
Query: &rts.ListRelationTuplesRequest_Query{
|
||||
Namespace: "Chat",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
wc, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer wc.Close()
|
||||
|
||||
deltas := make([]*rts.RelationTupleDelta, len(resp.RelationTuples))
|
||||
for i, rt := range resp.RelationTuples {
|
||||
deltas[i] = &rts.RelationTupleDelta{
|
||||
Action: rts.RelationTupleDelta_ACTION_DELETE,
|
||||
RelationTuple: proto.Clone(rt).(*rts.RelationTuple),
|
||||
}
|
||||
}
|
||||
|
||||
wClient := rts.NewWriteServiceClient(wc)
|
||||
_, err = wClient.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: deltas,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
dsn: memory
|
||||
log:
|
||||
level: trace
|
||||
|
||||
namespaces:
|
||||
location: file://./list-api-display-objects-subjectset/namespaces.ts
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright © 2026 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Context, Namespace } from "@ory/keto-namespace-types"
|
||||
|
||||
class User implements Namespace {}
|
||||
|
||||
class Chat implements Namespace {
|
||||
related: {
|
||||
member: User[]
|
||||
}
|
||||
}
|
||||
20
contrib/docs-code-samples/list-api-display-objects/00-create-tuples/cli.sh
Executable file
20
contrib/docs-code-samples/list-api-display-objects/00-create-tuples/cli.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
echo 'chats:memes#member@PM
|
||||
chats:memes#member@Vincent
|
||||
chats:memes#member@Julia
|
||||
|
||||
chats:cars#member@PM
|
||||
chats:cars#member@Julia
|
||||
|
||||
chats:coffee-break#member@PM
|
||||
chats:coffee-break#member@Vincent
|
||||
chats:coffee-break#member@Julia
|
||||
chats:coffee-break#member@Patrik' | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
keto relation-tuple create -f - >/dev/null --insecure-disable-transport-security \
|
||||
&& echo "Successfully created tuples" \
|
||||
|| echo "Encountered error"
|
||||
23
contrib/docs-code-samples/list-api-display-objects/00-create-tuples/curl.sh
Executable file
23
contrib/docs-code-samples/list-api-display-objects/00-create-tuples/curl.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo 'chats:memes#member@PM
|
||||
chats:memes#member@Vincent
|
||||
chats:memes#member@Julia
|
||||
|
||||
chats:cars#member@PM
|
||||
chats:cars#member@Julia
|
||||
|
||||
chats:coffee-break#member@PM
|
||||
chats:coffee-break#member@Vincent
|
||||
chats:coffee-break#member@Julia
|
||||
chats:coffee-break#member@Patrik' | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
jq "[ .[] | { relation_tuple: . , action: \"insert\" } ]" -c | \
|
||||
curl -X PATCH --silent --fail \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data @- \
|
||||
http://127.0.0.1:4467/admin/relation-tuples
|
||||
|
||||
echo "Successfully created tuples"
|
||||
@@ -0,0 +1 @@
|
||||
Successfully created tuples
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, write, writeService } from "@ory/keto-grpc-client"
|
||||
|
||||
const writeClient = new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const writeRequest = new write.TransactRelationTuplesRequest()
|
||||
|
||||
const addToChat = (chatName) => (user) => {
|
||||
const relationTuple = new relationTuples.RelationTuple()
|
||||
relationTuple.setNamespace("chats")
|
||||
relationTuple.setObject(chatName)
|
||||
relationTuple.setRelation("member")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setId(user)
|
||||
relationTuple.setSubject(sub)
|
||||
|
||||
const tupleDelta = new write.RelationTupleDelta()
|
||||
tupleDelta.setAction(write.RelationTupleDelta.Action.ACTION_INSERT)
|
||||
tupleDelta.setRelationTuple(relationTuple)
|
||||
|
||||
writeRequest.addRelationTupleDeltas(tupleDelta)
|
||||
}
|
||||
|
||||
;["PM", "Vincent", "Julia"].forEach(addToChat("memes"))
|
||||
;["PM", "Julia"].forEach(addToChat("cars"))
|
||||
;["PM", "Vincent", "Julia", "Patrik"].forEach(addToChat("coffee-break"))
|
||||
|
||||
writeClient.transactRelationTuples(writeRequest, (error) => {
|
||||
if (error) {
|
||||
console.log("Encountered error", error)
|
||||
} else {
|
||||
console.log("Successfully created tuples")
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic("Encountered error: " + err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewWriteServiceClient(conn)
|
||||
|
||||
var tuples []*rts.RelationTuple
|
||||
// memes
|
||||
for _, user := range []string{"PM", "Vincent", "Julia"} {
|
||||
tuples = append(tuples, &rts.RelationTuple{
|
||||
Namespace: "chats",
|
||||
Object: "memes",
|
||||
Relation: "member",
|
||||
Subject: rts.NewSubjectID(user),
|
||||
})
|
||||
}
|
||||
// cars
|
||||
for _, user := range []string{"PM", "Julia"} {
|
||||
tuples = append(tuples, &rts.RelationTuple{
|
||||
Namespace: "chats",
|
||||
Object: "cars",
|
||||
Relation: "member",
|
||||
Subject: rts.NewSubjectID(user),
|
||||
})
|
||||
}
|
||||
// coffee-break
|
||||
for _, user := range []string{"PM", "Vincent", "Julia", "Patrik"} {
|
||||
tuples = append(tuples, &rts.RelationTuple{
|
||||
Namespace: "chats",
|
||||
Object: "coffee-break",
|
||||
Relation: "member",
|
||||
Subject: rts.NewSubjectID(user),
|
||||
})
|
||||
}
|
||||
|
||||
_, err = client.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: rts.RelationTupleToDeltas(tuples, rts.RelationTupleDelta_ACTION_INSERT),
|
||||
})
|
||||
if err != nil {
|
||||
panic("Encountered error: " + err.Error())
|
||||
}
|
||||
|
||||
fmt.Println("Successfully created tuples")
|
||||
}
|
||||
7
contrib/docs-code-samples/list-api-display-objects/01-list-PM/cli.sh
Executable file
7
contrib/docs-code-samples/list-api-display-objects/01-list-PM/cli.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
|
||||
keto relation-tuple get --namespace chats --relation member --subject-id PM --format json --insecure-disable-transport-security | \
|
||||
jq ".relation_tuples[] | .object" -r | sort
|
||||
10
contrib/docs-code-samples/list-api-display-objects/01-list-PM/curl.sh
Executable file
10
contrib/docs-code-samples/list-api-display-objects/01-list-PM/curl.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=chats" \
|
||||
--data-urlencode "relation=member" \
|
||||
--data-urlencode "subject_id=PM" \
|
||||
http://127.0.0.1:4466/relation-tuples | \
|
||||
jq ".relation_tuples[] | .object" -r | sort
|
||||
@@ -0,0 +1,3 @@
|
||||
cars
|
||||
coffee-break
|
||||
memes
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, read, readService } from "@ory/keto-grpc-client"
|
||||
|
||||
const readClient = new readService.ReadServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const readRequest = new read.ListRelationTuplesRequest()
|
||||
const query = new read.ListRelationTuplesRequest.Query()
|
||||
query.setNamespace("chats")
|
||||
query.setRelation("member")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setId("PM")
|
||||
query.setSubject(sub)
|
||||
|
||||
readRequest.setQuery(query)
|
||||
|
||||
readClient.listRelationTuples(readRequest, (error, resp) => {
|
||||
if (error) {
|
||||
console.log("Encountered error:", error)
|
||||
} else {
|
||||
console.log(
|
||||
resp
|
||||
.getRelationTuplesList()
|
||||
.map((tuple) => tuple.getObject())
|
||||
.sort((a, b) => (a < b ? -1 : 1))
|
||||
.join("\n"),
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewReadServiceClient(conn)
|
||||
|
||||
res, err := client.ListRelationTuples(context.Background(), &rts.ListRelationTuplesRequest{
|
||||
RelationQuery: &rts.RelationQuery{
|
||||
Namespace: new("chats"),
|
||||
Relation: new("member"),
|
||||
Subject: rts.NewSubjectID("PM"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
objects := make([]string, len(res.RelationTuples))
|
||||
for i, rt := range res.RelationTuples {
|
||||
objects[i] = rt.Object
|
||||
}
|
||||
sort.Strings(objects)
|
||||
for _, o := range objects {
|
||||
fmt.Println(o)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
|
||||
keto relation-tuple get --namespace chats --object coffee-break --relation member --format json --insecure-disable-transport-security | \
|
||||
jq "[.relation_tuples[] | .subject_id] | sort | .[]" -r
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=chats" \
|
||||
--data-urlencode "object=coffee-break" \
|
||||
--data-urlencode "relation=member" \
|
||||
http://127.0.0.1:4466/relation-tuples | \
|
||||
jq "[.relation_tuples[] | .subject_id] | sort | .[]" -r
|
||||
@@ -0,0 +1,4 @@
|
||||
Julia
|
||||
PM
|
||||
Patrik
|
||||
Vincent
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { read, readService } from "@ory/keto-grpc-client"
|
||||
|
||||
const readClient = new readService.ReadServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const readRequest = new read.ListRelationTuplesRequest()
|
||||
const query = new read.ListRelationTuplesRequest.Query()
|
||||
query.setNamespace("chats")
|
||||
query.setObject("coffee-break")
|
||||
query.setRelation("member")
|
||||
|
||||
readRequest.setQuery(query)
|
||||
|
||||
readClient.listRelationTuples(readRequest, (error, resp) => {
|
||||
if (error) {
|
||||
console.log("Encountered error:", error)
|
||||
} else {
|
||||
console.log(
|
||||
resp
|
||||
.getRelationTuplesList()
|
||||
.map((tuple) => tuple.getSubject().getId())
|
||||
.sort((a, b) => (a < b ? -1 : 1))
|
||||
.join("\n"),
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewReadServiceClient(conn)
|
||||
|
||||
res, err := client.ListRelationTuples(context.Background(), &rts.ListRelationTuplesRequest{
|
||||
RelationQuery: &rts.RelationQuery{
|
||||
Namespace: new("chats"),
|
||||
Object: new("coffee-break"),
|
||||
Relation: new("member"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
ids := make([]string, len(res.RelationTuples))
|
||||
for i, rt := range res.RelationTuples {
|
||||
ids[i] = rt.Subject.Ref.(*rts.Subject_Id).Id
|
||||
}
|
||||
sort.Strings(ids)
|
||||
for _, id := range ids {
|
||||
fmt.Println(id)
|
||||
}
|
||||
}
|
||||
9
contrib/docs-code-samples/list-api-display-objects/99-cleanup/cli.sh
Executable file
9
contrib/docs-code-samples/list-api-display-objects/99-cleanup/cli.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
keto relation-tuple get --namespace chats --format json --insecure-disable-transport-security | \
|
||||
jq ".relation_tuples" | \
|
||||
keto relation-tuple delete -f - -q > /dev/null --insecure-disable-transport-security
|
||||
16
contrib/docs-code-samples/list-api-display-objects/99-cleanup/curl.sh
Executable file
16
contrib/docs-code-samples/list-api-display-objects/99-cleanup/curl.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=chats" \
|
||||
http://127.0.0.1:4466/relation-tuples | \
|
||||
jq "[ .relation_tuples[] | { relation_tuple: . , action: \"delete\" } ]" -c | \
|
||||
curl -X PATCH --silent --fail \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data @- \
|
||||
http://127.0.0.1:4467/admin/relation-tuples
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { write, writeService, read, readService } from "@ory/keto-grpc-client"
|
||||
|
||||
const readClient = new readService.ReadServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const query = new read.ListRelationTuplesRequest.Query()
|
||||
query.setNamespace("chats")
|
||||
|
||||
const readRequest = new read.ListRelationTuplesRequest()
|
||||
readRequest.setQuery(query)
|
||||
|
||||
readClient.listRelationTuples(readRequest, (err, resp) => {
|
||||
const writeClient = new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const writeRequest = new write.TransactRelationTuplesRequest()
|
||||
|
||||
resp.getRelationTuplesList().forEach((tuple) => {
|
||||
const tupleDelta = new write.RelationTupleDelta()
|
||||
tupleDelta.setAction(write.RelationTupleDelta.Action.ACTION_DELETE)
|
||||
tupleDelta.setRelationTuple(tuple)
|
||||
writeRequest.addRelationTupleDeltas(tupleDelta)
|
||||
})
|
||||
|
||||
writeClient.transactRelationTuples(writeRequest, (err) => {
|
||||
if (err) {
|
||||
console.log("Unexpected err", err)
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build docscodesamples
|
||||
// +build docscodesamples
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rc, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
rClient := rts.NewReadServiceClient(rc)
|
||||
resp, err := rClient.ListRelationTuples(context.Background(), &rts.ListRelationTuplesRequest{
|
||||
Query: &rts.ListRelationTuplesRequest_Query{
|
||||
Namespace: "chats",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
wc, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer wc.Close()
|
||||
|
||||
deltas := make([]*rts.RelationTupleDelta, len(resp.RelationTuples))
|
||||
for i, rt := range resp.RelationTuples {
|
||||
deltas[i] = &rts.RelationTupleDelta{
|
||||
Action: rts.RelationTupleDelta_ACTION_DELETE,
|
||||
RelationTuple: proto.Clone(rt).(*rts.RelationTuple),
|
||||
}
|
||||
}
|
||||
|
||||
wClient := rts.NewWriteServiceClient(wc)
|
||||
_, err = wClient.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: deltas,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
dsn: memory
|
||||
log:
|
||||
level: trace
|
||||
|
||||
namespaces:
|
||||
- name: chats
|
||||
id: 1
|
||||
651
contrib/docs-code-samples/package-lock.json
generated
Normal file
651
contrib/docs-code-samples/package-lock.json
generated
Normal file
@@ -0,0 +1,651 @@
|
||||
{
|
||||
"name": "docs-code-samples",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "1.14.4",
|
||||
"@ory/keto-grpc-client": "0.13.0-alpha.0",
|
||||
"google-protobuf": "3.21.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@grpc/grpc-js": {
|
||||
"version": "1.14.4",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.4.tgz",
|
||||
"integrity": "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@grpc/proto-loader": "^0.8.0",
|
||||
"@js-sdsl/ordered-map": "^4.4.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz",
|
||||
"integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"long": "^5.0.0",
|
||||
"protobufjs": "^7.5.5",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"bin": {
|
||||
"proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@grpc/proto-loader": {
|
||||
"version": "0.7.15",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz",
|
||||
"integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"long": "^5.0.0",
|
||||
"protobufjs": "^7.2.5",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"bin": {
|
||||
"proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@js-sdsl/ordered-map": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
|
||||
"integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/js-sdsl"
|
||||
}
|
||||
},
|
||||
"node_modules/@ory/keto-grpc-client": {
|
||||
"version": "0.13.0-alpha.0",
|
||||
"resolved": "https://registry.npmjs.org/@ory/keto-grpc-client/-/keto-grpc-client-0.13.0-alpha.0.tgz",
|
||||
"integrity": "sha512-WN5nnQ7E5z4YgaAN4HleYlcrFZR0Lq7ShwK+97qG+zGrOYvZLGDrdTJSosKNc73en7/MsjQqtLbfk4eaBTnfTw==",
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "1.9.6",
|
||||
"google-protobuf": "^3.21.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@ory/keto-grpc-client/node_modules/@grpc/grpc-js": {
|
||||
"version": "1.9.16",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.16.tgz",
|
||||
"integrity": "sha512-wE4Ut/olIzfKqp631XrG+wbF0v1vWFN4YL9FyXC2LJiG33DsV7PLzURjrCvY/6je2ntdRkeLpPDluzSRGaVltQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@grpc/proto-loader": "^0.7.8",
|
||||
"@types/node": ">=12.12.47"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^8.13.0 || >=10.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/base64": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/codegen": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
|
||||
"integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/eventemitter": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
|
||||
"integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/fetch": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
|
||||
"integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/float": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/path": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/pool": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/utf8": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz",
|
||||
"integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "25.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
|
||||
"integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": ">=7.24.0 <7.24.7"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/google-protobuf": {
|
||||
"version": "3.21.2",
|
||||
"resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz",
|
||||
"integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA=="
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "7.6.5",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz",
|
||||
"integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@protobufjs/codegen": "^2.0.5",
|
||||
"@protobufjs/eventemitter": "^1.1.1",
|
||||
"@protobufjs/fetch": "^1.1.1",
|
||||
"@protobufjs/float": "^1.0.2",
|
||||
"@protobufjs/path": "^1.1.2",
|
||||
"@protobufjs/pool": "^1.1.0",
|
||||
"@protobufjs/utf8": "^1.1.1",
|
||||
"@types/node": ">=13.7.0",
|
||||
"long": "^5.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.24.6",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": {
|
||||
"version": "1.14.4",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.4.tgz",
|
||||
"integrity": "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==",
|
||||
"requires": {
|
||||
"@grpc/proto-loader": "^0.8.0",
|
||||
"@js-sdsl/ordered-map": "^4.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/proto-loader": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz",
|
||||
"integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==",
|
||||
"requires": {
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"long": "^5.0.0",
|
||||
"protobufjs": "^7.5.5",
|
||||
"yargs": "^17.7.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@grpc/proto-loader": {
|
||||
"version": "0.7.15",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz",
|
||||
"integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==",
|
||||
"requires": {
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"long": "^5.0.0",
|
||||
"protobufjs": "^7.2.5",
|
||||
"yargs": "^17.7.2"
|
||||
}
|
||||
},
|
||||
"@js-sdsl/ordered-map": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
|
||||
"integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="
|
||||
},
|
||||
"@ory/keto-grpc-client": {
|
||||
"version": "0.13.0-alpha.0",
|
||||
"resolved": "https://registry.npmjs.org/@ory/keto-grpc-client/-/keto-grpc-client-0.13.0-alpha.0.tgz",
|
||||
"integrity": "sha512-WN5nnQ7E5z4YgaAN4HleYlcrFZR0Lq7ShwK+97qG+zGrOYvZLGDrdTJSosKNc73en7/MsjQqtLbfk4eaBTnfTw==",
|
||||
"requires": {
|
||||
"@grpc/grpc-js": "1.9.16",
|
||||
"google-protobuf": "^3.21.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": {
|
||||
"version": "1.9.16",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.16.tgz",
|
||||
"integrity": "sha512-wE4Ut/olIzfKqp631XrG+wbF0v1vWFN4YL9FyXC2LJiG33DsV7PLzURjrCvY/6je2ntdRkeLpPDluzSRGaVltQ==",
|
||||
"requires": {
|
||||
"@grpc/proto-loader": "^0.7.8",
|
||||
"@types/node": ">=12.12.47"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
|
||||
},
|
||||
"@protobufjs/base64": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
|
||||
},
|
||||
"@protobufjs/codegen": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
|
||||
"integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g=="
|
||||
},
|
||||
"@protobufjs/eventemitter": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
|
||||
"integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg=="
|
||||
},
|
||||
"@protobufjs/fetch": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
|
||||
"integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
|
||||
"requires": {
|
||||
"@protobufjs/aspromise": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"@protobufjs/float": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
|
||||
},
|
||||
"@protobufjs/path": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
|
||||
},
|
||||
"@protobufjs/pool": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
|
||||
},
|
||||
"@protobufjs/utf8": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz",
|
||||
"integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "25.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
|
||||
"integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
|
||||
"requires": {
|
||||
"undici-types": ">=7.24.0 <7.24.7"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
},
|
||||
"google-protobuf": {
|
||||
"version": "3.21.2",
|
||||
"resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz",
|
||||
"integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
||||
},
|
||||
"long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="
|
||||
},
|
||||
"protobufjs": {
|
||||
"version": "7.6.5",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz",
|
||||
"integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==",
|
||||
"requires": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@protobufjs/codegen": "^2.0.5",
|
||||
"@protobufjs/eventemitter": "^1.1.1",
|
||||
"@protobufjs/fetch": "^1.1.1",
|
||||
"@protobufjs/float": "^1.0.2",
|
||||
"@protobufjs/path": "^1.1.2",
|
||||
"@protobufjs/pool": "^1.1.0",
|
||||
"@protobufjs/utf8": "^1.1.1",
|
||||
"@types/node": ">=13.7.0",
|
||||
"long": "^5.3.2"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"undici-types": {
|
||||
"version": "7.24.6",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"requires": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
17
contrib/docs-code-samples/package.json
Normal file
17
contrib/docs-code-samples/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "./test.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "1.14.4",
|
||||
"@ory/keto-grpc-client": "0.13.0-alpha.0",
|
||||
"google-protobuf": "3.21.2"
|
||||
},
|
||||
"overrides": {
|
||||
"@ory/keto-grpc-client": {
|
||||
"@grpc/grpc-js": "1.9.16"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
echo "messages:02y_15_4w350m3#decypher@john" | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
keto relation-tuple create -f - >/dev/null --insecure-disable-transport-security \
|
||||
&& echo "Successfully created tuple" \
|
||||
|| echo "Encountered error"
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
relationtuple='
|
||||
{
|
||||
"namespace": "messages",
|
||||
"object": "02y_15_4w350m3",
|
||||
"relation": "decypher",
|
||||
"subject_id": "john"
|
||||
}'
|
||||
|
||||
curl --fail --silent -X PUT \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data "$relationtuple" \
|
||||
http://127.0.0.1:4467/admin/relation-tuples > /dev/null \
|
||||
&& echo "Successfully created tuple" \
|
||||
|| echo "Encountered error"
|
||||
@@ -0,0 +1 @@
|
||||
Successfully created tuple
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, write, writeService } from "@ory/keto-grpc-client"
|
||||
|
||||
const writeClient = new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const relationTuple = new relationTuples.RelationTuple()
|
||||
relationTuple.setNamespace("messages")
|
||||
relationTuple.setObject("02y_15_4w350m3")
|
||||
relationTuple.setRelation("decypher")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setId("john")
|
||||
relationTuple.setSubject(sub)
|
||||
|
||||
const tupleDelta = new write.RelationTupleDelta()
|
||||
tupleDelta.setAction(write.RelationTupleDelta.Action.ACTION_INSERT)
|
||||
tupleDelta.setRelationTuple(relationTuple)
|
||||
|
||||
const writeRequest = new write.TransactRelationTuplesRequest()
|
||||
writeRequest.addRelationTupleDeltas(tupleDelta)
|
||||
|
||||
writeClient.transactRelationTuples(writeRequest, (error) => {
|
||||
if (error) {
|
||||
console.log("Encountered error", error)
|
||||
} else {
|
||||
console.log("Successfully created tuple")
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic("Encountered error: " + err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewWriteServiceClient(conn)
|
||||
|
||||
_, err = client.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: []*rts.RelationTupleDelta{
|
||||
{
|
||||
Action: rts.RelationTupleDelta_ACTION_INSERT,
|
||||
RelationTuple: &rts.RelationTuple{
|
||||
Namespace: "messages",
|
||||
Object: "02y_15_4w350m3",
|
||||
Relation: "decypher",
|
||||
Subject: rts.NewSubjectID("john"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic("Encountered error: " + err.Error())
|
||||
}
|
||||
|
||||
fmt.Println("Successfully created tuple")
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
|
||||
keto check john decypher messages:02y_15_4w350m3 --insecure-disable-transport-security
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "subject_id=john" \
|
||||
--data-urlencode "relation=decypher" \
|
||||
--data-urlencode "namespace=messages" \
|
||||
--data-urlencode "object=02y_15_4w350m3" \
|
||||
http://127.0.0.1:4466/relation-tuples/check \
|
||||
| jq -r 'if .allowed == true then "Allowed" else "Denied" end'
|
||||
@@ -0,0 +1 @@
|
||||
Allowed
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, check, checkService } from "@ory/keto-grpc-client"
|
||||
|
||||
const checkClient = new checkService.CheckServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const checkRequest = new check.CheckRequest()
|
||||
checkRequest.setNamespace("messages")
|
||||
checkRequest.setObject("02y_15_4w350m3")
|
||||
checkRequest.setRelation("decypher")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setId("john")
|
||||
checkRequest.setSubject(sub)
|
||||
|
||||
checkClient.check(checkRequest, (error, resp) => {
|
||||
if (error) {
|
||||
console.log("Encountered error:", error)
|
||||
} else {
|
||||
console.log(resp.getAllowed() ? "Allowed" : "Denied")
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
client := rts.NewCheckServiceClient(conn)
|
||||
|
||||
res, err := client.Check(context.Background(), &rts.CheckRequest{
|
||||
Namespace: "messages",
|
||||
Object: "02y_15_4w350m3",
|
||||
Relation: "decypher",
|
||||
Subject: rts.NewSubjectID("john"),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
if res.Allowed {
|
||||
fmt.Println("Allowed")
|
||||
return
|
||||
}
|
||||
fmt.Println("Denied")
|
||||
}
|
||||
14
contrib/docs-code-samples/simple-access-check-guide/99-cleanup/cli.sh
Executable file
14
contrib/docs-code-samples/simple-access-check-guide/99-cleanup/cli.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
relationtuple='
|
||||
{
|
||||
"namespace": "messages",
|
||||
"object": "02y_15_4w350m3",
|
||||
"relation": "decypher",
|
||||
"subject_id": "john"
|
||||
}'
|
||||
|
||||
keto relation-tuple delete -f <(echo "$relationtuple") -q > /dev/null --insecure-disable-transport-security
|
||||
11
contrib/docs-code-samples/simple-access-check-guide/99-cleanup/curl.sh
Executable file
11
contrib/docs-code-samples/simple-access-check-guide/99-cleanup/curl.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -X DELETE -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "subject_id=john" \
|
||||
--data-urlencode "relation=decypher" \
|
||||
--data-urlencode "namespace=messages" \
|
||||
--data-urlencode "object=02y_15_4w350m3" \
|
||||
-H 'Content-Type: application/json' \
|
||||
http://127.0.0.1:4467/admin/relation-tuples
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, write, writeService } from "@ory/keto-grpc-client"
|
||||
|
||||
const writeClient = new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const relationTuple = new relationTuples.RelationTuple()
|
||||
relationTuple.setNamespace("messages")
|
||||
relationTuple.setObject("02y_15_4w350m3")
|
||||
relationTuple.setRelation("decypher")
|
||||
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setId("john")
|
||||
relationTuple.setSubject(sub)
|
||||
|
||||
const tupleDelta = new write.RelationTupleDelta()
|
||||
tupleDelta.setAction(write.RelationTupleDelta.Action.ACTION_DELETE)
|
||||
tupleDelta.setRelationTuple(relationTuple)
|
||||
|
||||
const writeRequest = new write.TransactRelationTuplesRequest()
|
||||
writeRequest.addRelationTupleDeltas(tupleDelta)
|
||||
|
||||
writeClient.transactRelationTuples(writeRequest, (err) => {
|
||||
if (err) {
|
||||
console.log("Unexpected err", err)
|
||||
return 1
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
wc, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer func() { _ = wc.Close() }()
|
||||
|
||||
wClient := rts.NewWriteServiceClient(wc)
|
||||
_, err = wClient.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: []*rts.RelationTupleDelta{
|
||||
{
|
||||
RelationTuple: &rts.RelationTuple{
|
||||
Namespace: "messages",
|
||||
Object: "02y_15_4w350m3",
|
||||
Relation: "decypher",
|
||||
Subject: rts.NewSubjectID("john"),
|
||||
},
|
||||
Action: rts.RelationTupleDelta_ACTION_DELETE,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
dsn: memory
|
||||
log:
|
||||
level: trace
|
||||
|
||||
namespaces:
|
||||
- name: messages
|
||||
id: 1
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
printf '%s\n' \
|
||||
'File:data.txt#viewer@user_alice' \
|
||||
'File:data.txt#viewer@user_bob' \
|
||||
'File:data.txt#viewer@apikey_ci-bot' | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
keto relation-tuple create -f - >/dev/null --insecure-disable-transport-security \
|
||||
&& echo "Successfully created tuples" \
|
||||
|| echo "Encountered error"
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -X PATCH --fail --silent \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data '[
|
||||
{"action":"insert","relation_tuple":{"namespace":"File","object":"data.txt","relation":"viewer","subject_id":"user_alice"}},
|
||||
{"action":"insert","relation_tuple":{"namespace":"File","object":"data.txt","relation":"viewer","subject_id":"user_bob"}},
|
||||
{"action":"insert","relation_tuple":{"namespace":"File","object":"data.txt","relation":"viewer","subject_id":"apikey_ci-bot"}}
|
||||
]' \
|
||||
http://127.0.0.1:4467/admin/relation-tuples > /dev/null \
|
||||
&& echo "Successfully created tuples" \
|
||||
|| echo "Encountered error"
|
||||
@@ -0,0 +1 @@
|
||||
Successfully created tuples
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright © 2026 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, write, writeService } from "@ory/keto-grpc-client"
|
||||
|
||||
const writeClient = new writeService.WriteServiceClient(
|
||||
"127.0.0.1:4467",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
function insertSubjectID(subjectID) {
|
||||
const rt = new relationTuples.RelationTuple()
|
||||
rt.setNamespace("File")
|
||||
rt.setObject("data.txt")
|
||||
rt.setRelation("viewer")
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setId(subjectID)
|
||||
rt.setSubject(sub)
|
||||
const delta = new write.RelationTupleDelta()
|
||||
delta.setAction(write.RelationTupleDelta.Action.ACTION_INSERT)
|
||||
delta.setRelationTuple(rt)
|
||||
return delta
|
||||
}
|
||||
|
||||
const req = new write.TransactRelationTuplesRequest()
|
||||
for (const id of ["user_alice", "user_bob", "apikey_ci-bot"]) {
|
||||
req.addRelationTupleDeltas(insertSubjectID(id))
|
||||
}
|
||||
|
||||
writeClient.transactRelationTuples(req, (error) => {
|
||||
if (error) {
|
||||
console.log("Encountered error", error)
|
||||
} else {
|
||||
console.log("Successfully created tuples")
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright © 2026 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4467", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
client := rts.NewWriteServiceClient(conn)
|
||||
|
||||
insert := func(subjectID string) *rts.RelationTupleDelta {
|
||||
return &rts.RelationTupleDelta{
|
||||
Action: rts.RelationTupleDelta_ACTION_INSERT,
|
||||
RelationTuple: &rts.RelationTuple{
|
||||
Namespace: "File",
|
||||
Object: "data.txt",
|
||||
Relation: "viewer",
|
||||
Subject: rts.NewSubjectID(subjectID),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
_, err = client.TransactRelationTuples(context.Background(), &rts.TransactRelationTuplesRequest{
|
||||
RelationTupleDeltas: []*rts.RelationTupleDelta{
|
||||
insert("user_alice"),
|
||||
insert("user_bob"),
|
||||
insert("apikey_ci-bot"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Successfully created tuples")
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_READ_REMOTE="127.0.0.1:4466"
|
||||
|
||||
keto check user_alice viewer File:data.txt --insecure-disable-transport-security
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -G --silent \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data-urlencode "namespace=File" \
|
||||
--data-urlencode "object=data.txt" \
|
||||
--data-urlencode "relation=viewer" \
|
||||
--data-urlencode "subject_id=user_alice" \
|
||||
http://127.0.0.1:4466/relation-tuples/check \
|
||||
| jq -r 'if .allowed == true then "Allowed" else "Denied" end'
|
||||
@@ -0,0 +1 @@
|
||||
Allowed
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright © 2026 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import grpc from "@ory/keto-grpc-client/node_modules/@grpc/grpc-js/build/src/index.js"
|
||||
import { relationTuples, check, checkService } from "@ory/keto-grpc-client"
|
||||
|
||||
const checkClient = new checkService.CheckServiceClient(
|
||||
"127.0.0.1:4466",
|
||||
grpc.credentials.createInsecure(),
|
||||
)
|
||||
|
||||
const req = new check.CheckRequest()
|
||||
req.setNamespace("File")
|
||||
req.setObject("data.txt")
|
||||
req.setRelation("viewer")
|
||||
const sub = new relationTuples.Subject()
|
||||
sub.setId("user_alice")
|
||||
req.setSubject(sub)
|
||||
|
||||
checkClient.check(req, (error, resp) => {
|
||||
if (error) {
|
||||
console.log("Encountered error:", error)
|
||||
} else {
|
||||
console.log(resp.getAllowed() ? "Allowed" : "Denied")
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright © 2026 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.NewClient("127.0.0.1:4466", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
client := rts.NewCheckServiceClient(conn)
|
||||
|
||||
res, err := client.Check(context.Background(), &rts.CheckRequest{
|
||||
Namespace: "File",
|
||||
Object: "data.txt",
|
||||
Relation: "viewer",
|
||||
Subject: rts.NewSubjectID("user_alice"),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if res.Allowed {
|
||||
fmt.Println("Allowed")
|
||||
return
|
||||
}
|
||||
fmt.Println("Denied")
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export KETO_WRITE_REMOTE="127.0.0.1:4467"
|
||||
|
||||
# During the migration phase, write every new tuple as both SubjectID and SubjectSet.
|
||||
printf '%s\n' \
|
||||
'File:data.txt#viewer@user_charlie' \
|
||||
'File:data.txt#viewer@User:charlie' | \
|
||||
keto relation-tuple parse -f - --format json | \
|
||||
keto relation-tuple create -f - >/dev/null --insecure-disable-transport-security \
|
||||
&& echo "Successfully created tuples" \
|
||||
|| echo "Encountered error"
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# During migration, write every new tuple as both SubjectID and SubjectSet.
|
||||
curl -X PATCH --fail --silent \
|
||||
-H 'Content-Type: application/json' \
|
||||
--retry 7 --retry-connrefused \
|
||||
--data '[
|
||||
{"action":"insert","relation_tuple":{"namespace":"File","object":"data.txt","relation":"viewer","subject_id":"user_charlie"}},
|
||||
{"action":"insert","relation_tuple":{"namespace":"File","object":"data.txt","relation":"viewer","subject_set":{"namespace":"User","object":"charlie","relation":""}}}
|
||||
]' \
|
||||
http://127.0.0.1:4467/admin/relation-tuples > /dev/null \
|
||||
&& echo "Successfully created tuples" \
|
||||
|| echo "Encountered error"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user