feat: updated model and tests. working v1.0
This commit is contained in:
6
README.md
Normal file
6
README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Atlantis FGA model
|
||||||
|
|
||||||
|
To test the model run:
|
||||||
|
```
|
||||||
|
fga model test --tests test.fga.model
|
||||||
|
```
|
||||||
50
fga.mod
50
fga.mod
@@ -1,48 +1,4 @@
|
|||||||
model
|
schema: "1.2"
|
||||||
schema 1.1
|
|
||||||
|
|
||||||
type system
|
|
||||||
relations
|
|
||||||
define can_create_organization: [ user, group#member ] or superuser
|
|
||||||
define superuser: [ user, group#member ]
|
|
||||||
|
|
||||||
type organization
|
|
||||||
relations
|
|
||||||
define can_create_group: admin or superuser from system
|
|
||||||
define member: [ group#member ]
|
|
||||||
define admin: [ user ] or superuser from system
|
|
||||||
define system: [ system ]
|
|
||||||
|
|
||||||
type group
|
|
||||||
relations
|
|
||||||
define member: [ user, group#member ]
|
|
||||||
define admin: [ user ] or admin from org
|
|
||||||
define can_impersonate: admin
|
|
||||||
define org: [ organization ]
|
|
||||||
|
|
||||||
type user
|
|
||||||
relations
|
|
||||||
define can_edit_profile: [ user ]
|
|
||||||
define can_view_profile: [ user ] or admin from group
|
|
||||||
define group: [ group ]
|
|
||||||
|
|
||||||
tyoe license
|
|
||||||
relations
|
|
||||||
define view: [ user with valid_time, group#member with valid_time ]
|
|
||||||
define run: [ user with valid_time, group#member with valid_time ] and view
|
|
||||||
|
|
||||||
type archive
|
|
||||||
relations
|
|
||||||
define edit: [ user ] or admin
|
|
||||||
define view: view from license
|
|
||||||
define run: run from license
|
|
||||||
define run_any: [ user, group#member ] and view and run
|
|
||||||
define run_transport: ([ user, group#member ] or run_any) and view and run
|
|
||||||
define run_sedimentation: ([ user, group#member ] or run_any) and view and run
|
|
||||||
define run_wc: ([ user, group#member ] or run_any) and view and run
|
|
||||||
define admin: [ user ] or admin from group
|
|
||||||
define group: [ group ]
|
|
||||||
define license: [ license ]
|
|
||||||
|
|
||||||
condition valid_time(now: timestamp, start_time: timestamp, end_time: timestamp) { now >= start_time && now <= end_time }
|
|
||||||
|
|
||||||
|
contents:
|
||||||
|
- model.fga
|
||||||
|
|||||||
60
model.fga
Normal file
60
model.fga
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
module model
|
||||||
|
|
||||||
|
type system
|
||||||
|
relations
|
||||||
|
define can_create_organization: [ user, group#member ] or superuser
|
||||||
|
define superuser: [ user, group#member ]
|
||||||
|
|
||||||
|
type organization
|
||||||
|
relations
|
||||||
|
define can_create_group: admin or superuser from parent
|
||||||
|
define member: [ group#member ]
|
||||||
|
define admin: [ user ] or superuser from parent
|
||||||
|
define parent: [ system ]
|
||||||
|
|
||||||
|
type group
|
||||||
|
relations
|
||||||
|
define member: [ user, group#member ]
|
||||||
|
define admin: [ user ] or admin from parent
|
||||||
|
define can_impersonate: admin
|
||||||
|
define parent: [ organization ]
|
||||||
|
|
||||||
|
type user
|
||||||
|
relations
|
||||||
|
define can_edit_profile: [ user ]
|
||||||
|
define can_view_profile: [ user ] or admin from group
|
||||||
|
define group: [ group ]
|
||||||
|
|
||||||
|
type grant
|
||||||
|
relations
|
||||||
|
define read: [
|
||||||
|
user with valid_period,
|
||||||
|
user:* with valid_period,
|
||||||
|
group#member with valid_period
|
||||||
|
] or execute
|
||||||
|
define execute: [ user with valid_allocation, group#member with valid_allocation ]
|
||||||
|
|
||||||
|
type archive
|
||||||
|
relations
|
||||||
|
define can_edit: owner or admin
|
||||||
|
define can_view: owner or admin or read from has_grant or execute from has_grant
|
||||||
|
define can_share: owner or admin
|
||||||
|
define can_run: execute from has_grant
|
||||||
|
define run_any: [ user, group#member ] and can_view and can_run
|
||||||
|
define run_transport: ([ user, group#member ] or run_any) and can_run
|
||||||
|
define run_sedimentation: ([ user, group#member ] or run_any) and can_run
|
||||||
|
define run_wc: ([ user, group#member ] or run_any) and can_run
|
||||||
|
define owner: [ user ]
|
||||||
|
define admin: [ user ] or admin from parent
|
||||||
|
define parent: [ group ]
|
||||||
|
define has_grant: [ grant ]
|
||||||
|
|
||||||
|
condition valid_period(time: timestamp, start_time: timestamp, end_time: timestamp) {
|
||||||
|
start_time == end_time || // no time restriction
|
||||||
|
(time >= start_time && time <= end_time)
|
||||||
|
}
|
||||||
|
|
||||||
|
condition valid_allocation(usage: double, quota: double, time: timestamp, start_time: timestamp, end_time: timestamp) {
|
||||||
|
(start_time == end_time || time >= start_time && time <= end_time) &&
|
||||||
|
(quota < 0.0 || usage < quota)
|
||||||
|
}
|
||||||
1
scripts/clean_tuples.sh
Normal file
1
scripts/clean_tuples.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
fga tuple read | jq '[ .tuples[] | .key ]'
|
||||||
@@ -6,6 +6,6 @@ pkgs.mkShell {
|
|||||||
|
|
||||||
FGA_API_URL = "https://openfga.dev.oceanbox.io";
|
FGA_API_URL = "https://openfga.dev.oceanbox.io";
|
||||||
FGA_STORE_ID = "01J6C1NBX36E1B928HFSB123XQ";
|
FGA_STORE_ID = "01J6C1NBX36E1B928HFSB123XQ";
|
||||||
FGA_MODEL_ID = "01J6FK82QP8TER7MXD8F4AVJJK";
|
# FGA_MODEL_ID = "";
|
||||||
# FGA_API_TOKEN = "";
|
# FGA_API_TOKEN = "";
|
||||||
}
|
}
|
||||||
|
|||||||
172
test.fga.yaml
Normal file
172
test.fga.yaml
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
name: Model tests
|
||||||
|
model_file: fga.mod
|
||||||
|
tuple_file: tuples.fga.csv
|
||||||
|
tests:
|
||||||
|
- name: Organization membership
|
||||||
|
check:
|
||||||
|
- user: user:a
|
||||||
|
object: organization:acme
|
||||||
|
assertions:
|
||||||
|
member: true
|
||||||
|
admin: false
|
||||||
|
|
||||||
|
- user: user:b
|
||||||
|
object: organization:acme
|
||||||
|
assertions:
|
||||||
|
member: true
|
||||||
|
admin: true
|
||||||
|
|
||||||
|
- user: user:root
|
||||||
|
object: organization:acme
|
||||||
|
assertions:
|
||||||
|
member: false
|
||||||
|
admin: true
|
||||||
|
|
||||||
|
- name: list objects
|
||||||
|
list_objects:
|
||||||
|
- user: user:a
|
||||||
|
type: archive
|
||||||
|
context:
|
||||||
|
time: "2024-01-01T00:10:00Z"
|
||||||
|
usage: 10.0
|
||||||
|
assertions:
|
||||||
|
can_view:
|
||||||
|
- archive:a
|
||||||
|
can_run:
|
||||||
|
- archive:a
|
||||||
|
|
||||||
|
- user: user:b
|
||||||
|
type: archive
|
||||||
|
context:
|
||||||
|
time: "2024-01-01T00:10:00Z"
|
||||||
|
usage: 10.0
|
||||||
|
assertions:
|
||||||
|
can_view:
|
||||||
|
- archive:a
|
||||||
|
- archive:b
|
||||||
|
can_run:
|
||||||
|
- archive:b
|
||||||
|
|
||||||
|
- user: user:b
|
||||||
|
type: archive
|
||||||
|
context:
|
||||||
|
time: "2025-01-01T00:10:00Z"
|
||||||
|
usage: 101.0
|
||||||
|
assertions:
|
||||||
|
can_view:
|
||||||
|
- archive:a # as admin
|
||||||
|
can_run: []
|
||||||
|
|
||||||
|
- user: user:c
|
||||||
|
type: archive
|
||||||
|
context:
|
||||||
|
time: "2024-01-01T00:10:00Z"
|
||||||
|
usage: 0.0
|
||||||
|
assertions:
|
||||||
|
can_view:
|
||||||
|
- archive:b
|
||||||
|
can_run: []
|
||||||
|
|
||||||
|
- user: user:d
|
||||||
|
type: archive
|
||||||
|
context:
|
||||||
|
time: "2025-01-01T00:10:00Z"
|
||||||
|
usage: 101.0
|
||||||
|
assertions:
|
||||||
|
can_view:
|
||||||
|
- archive:a
|
||||||
|
can_run:
|
||||||
|
- archive:a
|
||||||
|
|
||||||
|
- name: list grants
|
||||||
|
list_users:
|
||||||
|
- object: grant:a
|
||||||
|
user_filter:
|
||||||
|
- type: user
|
||||||
|
context:
|
||||||
|
time: "2024-01-01T00:10:00Z"
|
||||||
|
usage: 0.0
|
||||||
|
assertions:
|
||||||
|
read:
|
||||||
|
users:
|
||||||
|
- user:a
|
||||||
|
- user:b
|
||||||
|
- user:d
|
||||||
|
execute:
|
||||||
|
users:
|
||||||
|
- user:a
|
||||||
|
- user:d
|
||||||
|
|
||||||
|
- object: grant:a
|
||||||
|
user_filter:
|
||||||
|
- type: user
|
||||||
|
context:
|
||||||
|
time: "2025-01-01T00:10:00Z"
|
||||||
|
usage: 101.0
|
||||||
|
assertions:
|
||||||
|
read:
|
||||||
|
users:
|
||||||
|
- user:d
|
||||||
|
execute:
|
||||||
|
users:
|
||||||
|
- user:d
|
||||||
|
|
||||||
|
- object: grant:b
|
||||||
|
user_filter:
|
||||||
|
- type: user
|
||||||
|
context:
|
||||||
|
time: "2024-01-01T00:10:00Z"
|
||||||
|
usage: 1.0
|
||||||
|
assertions:
|
||||||
|
read:
|
||||||
|
users:
|
||||||
|
- user:b
|
||||||
|
- user:c
|
||||||
|
execute:
|
||||||
|
users:
|
||||||
|
- user:b
|
||||||
|
|
||||||
|
- object: grant:b
|
||||||
|
user_filter:
|
||||||
|
- type: user
|
||||||
|
context:
|
||||||
|
time: "2025-01-01T00:10:00Z"
|
||||||
|
usage: 101.0
|
||||||
|
assertions:
|
||||||
|
read:
|
||||||
|
users: []
|
||||||
|
execute:
|
||||||
|
users: []
|
||||||
|
|
||||||
|
- name: list archives
|
||||||
|
list_users:
|
||||||
|
- object: archive:a
|
||||||
|
user_filter:
|
||||||
|
- type: user
|
||||||
|
context:
|
||||||
|
time: "2024-01-01T00:10:00Z"
|
||||||
|
usage: 99.0
|
||||||
|
assertions:
|
||||||
|
can_view:
|
||||||
|
users:
|
||||||
|
- user:a
|
||||||
|
- user:b
|
||||||
|
- user:d
|
||||||
|
- user:root
|
||||||
|
can_run:
|
||||||
|
users:
|
||||||
|
- user:a
|
||||||
|
- user:d
|
||||||
|
|
||||||
|
- object: archive:b
|
||||||
|
user_filter:
|
||||||
|
- type: user
|
||||||
|
context:
|
||||||
|
time: "2025-01-01T00:10:00Z"
|
||||||
|
usage: 999.0
|
||||||
|
assertions:
|
||||||
|
can_view:
|
||||||
|
users:
|
||||||
|
- user:root
|
||||||
|
can_run:
|
||||||
|
users: []
|
||||||
33
tuples.fga.csv
Normal file
33
tuples.fga.csv
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
user_type,user_id,relation,object_type,object_id,condition_name,condition_context
|
||||||
|
|
||||||
|
user,root,superuser,system,atlantis,,
|
||||||
|
|
||||||
|
system,atlantis,parent,organization,acme,,
|
||||||
|
system,atlantis,parent,organization,newco,,
|
||||||
|
|
||||||
|
organization,acme,parent,group,a,,
|
||||||
|
organization,acme,parent,group,b,,
|
||||||
|
organization,newco,parent,group,c,,
|
||||||
|
|
||||||
|
group,a#member,member,organization,acme,,
|
||||||
|
group,b#member,member,organization,acme,,
|
||||||
|
group,c#member,member,organization,newco,,
|
||||||
|
|
||||||
|
user,a,member,group,a,,
|
||||||
|
user,b,member,group,b,,
|
||||||
|
user,c,member,group,c,,
|
||||||
|
|
||||||
|
user,b,admin,organization,acme,,
|
||||||
|
|
||||||
|
group,a,parent,archive,a,,
|
||||||
|
group,b,parent,archive,a,,
|
||||||
|
group,c,parent,archive,b,,
|
||||||
|
|
||||||
|
group,a#member,execute,grant,a,valid_allocation,"{""quota"": ""100.0"", ""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2025-01-01T00:00:00Z""}"
|
||||||
|
group,b#member,read,grant,a,valid_period,"{""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2025-01-01T00:00:00Z""}"
|
||||||
|
group,b#member,execute,grant,b,valid_allocation,"{""quota"": ""100.0"", ""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2025-01-01T00:00:00Z""}"
|
||||||
|
group,c#member,read,grant,b,valid_period,"{""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2025-01-01T00:00:00Z""}"
|
||||||
|
user,d,execute,grant,a,valid_allocation,"{""quota"": ""-1.0"", ""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2024-01-01T00:00:00Z""}"
|
||||||
|
|
||||||
|
grant,a,has_grant,archive,a,,
|
||||||
|
grant,b,has_grant,archive,b,,
|
||||||
|
58
tuples.json
58
tuples.json
@@ -1,58 +0,0 @@
|
|||||||
{
|
|
||||||
"continuation_token":"",
|
|
||||||
"tuples": [
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"condition": {
|
|
||||||
"context": {
|
|
||||||
"start_time":"2024-08-01T00:00:00Z"
|
|
||||||
},
|
|
||||||
"name":"valid_time"
|
|
||||||
},
|
|
||||||
"object":"archive:a",
|
|
||||||
"relation":"view",
|
|
||||||
"user":"group:a#member"
|
|
||||||
},
|
|
||||||
"timestamp":"2024-08-29T16:37:55.474797Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"object":"group:a",
|
|
||||||
"relation":"member",
|
|
||||||
"user":"user:a"
|
|
||||||
},
|
|
||||||
"timestamp":"2024-08-29T16:45:07.056316Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"object":"archive:a",
|
|
||||||
"relation":"run_transport",
|
|
||||||
"user":"group:a#member"
|
|
||||||
},
|
|
||||||
"timestamp":"2024-08-29T17:04:35.100234Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"condition": {
|
|
||||||
"context": {
|
|
||||||
"end_time":"2024-09-01T00:00:00Z",
|
|
||||||
"start_time":"2024-08-01T00:00:00Z"
|
|
||||||
},
|
|
||||||
"name":"valid_time"
|
|
||||||
},
|
|
||||||
"object":"archive:a",
|
|
||||||
"relation":"run",
|
|
||||||
"user":"group:a#member"
|
|
||||||
},
|
|
||||||
"timestamp":"2024-08-29T17:41:35.007293Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"object":"archive:a",
|
|
||||||
"relation":"run_any",
|
|
||||||
"user":"group:a#member"
|
|
||||||
},
|
|
||||||
"timestamp":"2024-08-29T17:42:54.720477Z"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user