urbit/pkg/arvo/app/group-store.hoon

556 lines
13 KiB
Plaintext
Raw Normal View History

2020-05-15 01:50:04 +03:00
:: group-store: Store groups of ships
2019-11-21 02:18:45 +03:00
::
2020-05-15 01:50:04 +03:00
:: group-store stores groups of ships, so that resources in other apps can be
:: associated with a group. The current model of group-store rolls
:: permissions and invites inside this store for simplicity reasons, although
:: these should be prised apart in a future revision of group store.
::
2020-05-21 07:30:02 +03:00
::
2020-05-15 01:50:04 +03:00
:: ## Scry paths
::
:: /y/groups:
:: A listing of the current groups
:: /x/groups/[resource]:
2020-05-15 01:50:04 +03:00
:: The group itself
:: /x/groups/[resource]/join/[ship]:
2020-05-21 07:30:02 +03:00
:: A flag indicated if the ship is permitted to join
2020-05-15 01:50:04 +03:00
::
:: ## Subscription paths
::
:: /groups:
:: A stream of the current updates to the state, sending the initial state
:: upon subscribe.
::
:: ## Pokes
::
:: %group-action:
:: Modify the group. Further documented in /sur/group-store.hoon
::
::
/- *group, permission-store
/+ store=group-store, default-agent, verb, dbug, resource
2019-11-21 02:18:45 +03:00
|%
+$ card card:agent:gall
::
+$ versioned-state
$% state-zero
2020-05-15 01:50:04 +03:00
state-one
2019-11-21 02:18:45 +03:00
==
::
+$ state-zero
$: %0
=groups:state-zero:store
2020-05-15 01:50:04 +03:00
==
::
::
+$ state-one
$: %1
2019-11-21 02:18:45 +03:00
=groups
==
::
2020-05-15 01:50:04 +03:00
+$ diff
$% [%group-update update:store]
[%group-initial groups]
==
2019-11-21 02:18:45 +03:00
--
::
2020-05-15 01:50:04 +03:00
=| state-one
2019-11-21 02:18:45 +03:00
=* state -
::
%- agent:dbug
%+ verb |
2019-11-21 02:18:45 +03:00
^- agent:gall
=<
|_ =bowl:gall
+* this .
group-core +>
2020-01-04 00:06:42 +03:00
gc ~(. group-core bowl)
2019-11-21 02:18:45 +03:00
def ~(. (default-agent this %|) bowl)
::
2020-05-21 07:30:02 +03:00
++ on-init on-init:def
2019-11-21 02:18:45 +03:00
++ on-save !>(state)
++ on-load
2020-05-15 01:50:04 +03:00
|= =old=vase
=/ old !<(versioned-state old-vase)
?: ?=(%1 -.old)
`this(state old)
|^
:- ~[kick-all]
=* paths ~(key by groups.old)
=/ [unmanaged=(list path) managed=(list path)]
(skid ~(tap in paths) |=(=path =('~' (snag 0 path))))
=. groups (all-unmanaged unmanaged)
=. groups (all-managed managed)
this
::
++ all-managed
|= paths=(list path)
^+ groups
?~ paths
groups
=/ [rid=resource =group]
(migrate-group i.paths)
%= $
paths t.paths
::
groups
(~(put by groups) rid group)
==
::
++ all-unmanaged
|= paths=(list path)
^+ groups
?~ paths
groups
=/ [=resource =group]
(migrate-unmanaged i.paths)
%= $
paths t.paths
::
groups
(~(put by groups) resource group)
==
++ kick-all
^- card
:+ %give %kick
:_ ~
%~ tap by
%+ roll ~(val by sup.bowl)
|= [[=ship pax=path] paths=(set path)]
(~(put in paths) pax)
::
++ migrate-unmanaged
|= pax=path
^- [resource group]
=/ [=policy members=(set ship)]
(unmanaged-permissions pax)
?> =('~' -.pax)
=. pax +.pax
=/ rid=resource
(de-path:resource pax)
=/ =tags
(~(put ju *tags) %admin entity.rid)
[rid members tags policy %.y]
::
++ unmanaged-permissions
|= pax=path
^- [policy (set ship)]
=/ perm
(need (scry-group-permissions pax))
?: ?=(%black kind.perm)
:- [%open ~ who.perm]
~
:_ who.perm
*invite:policy
::
++ migrate-group
|= pax=path
=/ members
(~(got by groups.old) pax)
=^ =policy members
(migrate-permissions pax members)
=/ rid=resource
(de-path:resource pax)
=/ =tags
(~(put ju *tags) %admin entity.rid)
[rid members tags policy %.n]
::
++ migrate-permissions
|= [pax=path ships=(set ship)]
^- [policy (set ship)]
=/ perm
(scry-group-permissions pax)
?~ perm
[*invite:policy ships]
?> ?=(%white kind.u.perm)
[[%invite ~] (~(uni in ships) who.u.perm)]
::
++ scry-unmanaged-groups
^- (set path)
.^ (set path)
%gx
(scot %p our.bowl)
%permission-store
(scot %da now.bowl)
/keys/noun
==
::
++ scry-group-permissions
|= pax=path
^- (unit permission:permission-store)
.^ (unit permission:permission-store)
%gx
(scot %p our.bowl)
%permission-store
(scot %da now.bowl)
;: weld
/permission
pax
/noun
==
==
--
2019-11-21 02:18:45 +03:00
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?> (team:title our.bowl src.bowl)
=^ cards state
2020-05-21 07:30:02 +03:00
?: ?=(?(%group-update %group-action) mark)
2020-05-15 01:50:04 +03:00
(poke-group-update:gc !<(update:store vase))
2019-11-21 02:18:45 +03:00
(on-poke:def mark vase)
[cards this]
::
++ on-watch
|= =path
^- (quip card _this)
?> (team:title our.bowl src.bowl)
2020-05-15 01:50:04 +03:00
?> ?=([%groups ~] path)
:_ this
2020-05-21 07:30:02 +03:00
[%give %fact ~ %group-update !>([%initial groups])]~
2019-11-21 02:18:45 +03:00
::
++ on-leave on-leave:def
::
++ on-peek
|= =path
^- (unit (unit cage))
?+ path (on-peek:def path)
2020-05-27 07:32:43 +03:00
[%y %groups ~]
=/ =arch
:- ~
%- malt
%+ turn
~(tap by groups)
|= [rid=resource *]
2020-05-27 07:32:43 +03:00
^- [@ta ~]
=/ group=^path
(en-path:resource rid)
2020-05-27 07:32:43 +03:00
[(spat group) ~]
``noun+!>(arch)
::
[%x %groups %ship @ @ ~]
=/ rid=(unit resource)
(de-path-soft:resource t.t.path)
?~ rid ~
``noun+!>((peek-group u.rid))
2020-05-27 07:32:43 +03:00
::
[%x %groups %ship @ @ %join @ ~]
=/ rid=(unit resource)
(de-path-soft:resource t.t.path)
2020-05-21 07:30:02 +03:00
=/ =ship
(slav %p i.t.t.t.t.t.t.path)
?~ rid ~
``noun+!>((peek-group-join u.rid ship))
2019-11-21 02:18:45 +03:00
==
::
2020-01-04 00:06:42 +03:00
++ on-agent on-agent:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
2019-11-21 02:18:45 +03:00
--
::
|_ bol=bowl:gall
2020-05-21 07:30:02 +03:00
++ peek-group
|= rid=resource
2020-05-21 07:30:02 +03:00
^- (unit group)
(~(get by groups) rid)
2020-05-21 07:30:02 +03:00
++ peek-group-join
|= [rid=resource =ship]
2020-05-21 07:30:02 +03:00
=/ =group
(~(gut by groups) rid *group)
2020-05-15 01:50:04 +03:00
=* policy policy.group
?- -.policy
%invite
|((~(has in pending.policy) ship) (~(has in members.group) ship))
%open
!|((~(has in banned.policy) ship) (~(has in ban-ranks.policy) (clan:title ship)))
2020-05-15 01:50:04 +03:00
==
::
++ poke-group-update
|= =update:store
2019-11-21 02:18:45 +03:00
^- (quip card _state)
?> (team:title our.bol src.bol)
2020-05-15 01:50:04 +03:00
|^
?- -.update
%add-group (add-group +.update)
%add-members (add-members +.update)
%remove-members (remove-members +.update)
%add-tag (add-tag +.update)
%remove-tag (remove-tag +.update)
%change-policy (change-policy +.update)
%remove-group (remove-group +.update)
2020-05-27 07:32:43 +03:00
%groupify (groupify +.update)
2020-05-15 01:50:04 +03:00
%initial-group (initial-group +.update)
%initial [~ state]
2019-11-21 02:18:45 +03:00
==
2020-05-27 07:32:43 +03:00
:: +groupify: unset .hidden flag
::
++ groupify
|= [rid=resource ~]
2020-05-27 07:32:43 +03:00
^- (quip card _state)
=/ =group
(~(got by groups) rid)
2020-05-27 07:32:43 +03:00
=. hidden.group %.n
=. groups
(~(put by groups) rid group)
2020-05-27 07:32:43 +03:00
:_ state
(send-diff %groupify rid ~)
2020-05-15 01:50:04 +03:00
:: +add-group: add group to store
::
2020-05-21 07:30:02 +03:00
:: always include ship in own groups, no-op if group already exists
2020-05-15 01:50:04 +03:00
::
++ add-group
|= [rid=resource =policy hidden=?]
2020-05-15 01:50:04 +03:00
^- (quip card _state)
?< (~(has by groups) rid)
2020-05-21 07:30:02 +03:00
=| =group
=. members.group
(~(put in members.group) our.bol)
=. policy.group policy
2020-05-27 07:32:43 +03:00
=. hidden.group hidden
2020-05-27 09:19:29 +03:00
=. tags.group
(~(put ju tags.group) %admin our.bol)
2020-05-15 01:50:04 +03:00
=. groups
(~(put by groups) rid group)
2020-05-15 01:50:04 +03:00
:_ state
(send-diff %add-group rid policy hidden)
2020-05-15 01:50:04 +03:00
:: +add-members: add members to group
::
++ add-members
|= [rid=resource new-ships=(set ship)]
2020-05-15 01:50:04 +03:00
^- (quip card _state)
=/ =group (~(got by groups) rid)
2020-05-15 01:50:04 +03:00
=. members.group (~(uni in members.group) new-ships)
2020-05-21 07:30:02 +03:00
=* policy policy.group
=. policy
?. ?=(%invite -.policy)
policy
=. pending.policy
(~(dif in pending.policy) new-ships)
policy
2020-05-15 01:50:04 +03:00
=. groups
(~(put by groups) rid group)
2020-05-15 01:50:04 +03:00
:_ state
(send-diff %add-members rid new-ships)
2020-05-15 01:50:04 +03:00
:: +remove-members: remove members from group
::
:: no-op if group does not exist
2020-05-21 07:30:02 +03:00
::
2020-05-15 01:50:04 +03:00
::
++ remove-members
|= [rid=resource ships=(set ship)]
2020-05-15 01:50:04 +03:00
^- (quip card _state)
?. (~(has by groups) rid) [~ state]
2020-05-15 01:50:04 +03:00
=/ =group
(~(got by groups) rid)
2020-05-15 01:50:04 +03:00
=. members.group
(~(dif in members.group) ships)
2020-05-27 09:19:29 +03:00
=. tags.group
2020-05-21 07:30:02 +03:00
(remove-tags group ships)
2020-05-15 01:50:04 +03:00
=. groups
(~(put by groups) rid group)
2020-05-15 01:50:04 +03:00
:_ state
(send-diff %remove-members rid ships)
2020-05-15 01:50:04 +03:00
:: +add-tag: add tag to ships
::
2020-05-27 09:19:29 +03:00
:: crash if ships are not in group
2020-05-15 01:50:04 +03:00
::
++ add-tag
|= [rid=resource =tag ships=(set ship)]
2020-05-15 01:50:04 +03:00
^- (quip card _state)
=/ =group
(~(got by groups) rid)
2020-05-15 01:50:04 +03:00
?> ?=(~ (~(dif in ships) members.group))
2020-05-27 09:19:29 +03:00
=. tags.group
(merge-tags tags.group ships (sy tag ~))
2020-05-15 01:50:04 +03:00
=. groups
(~(put by groups) rid group)
2020-05-15 01:50:04 +03:00
:_ state
(send-diff %add-tag rid tag ships)
2020-05-15 01:50:04 +03:00
:: +remove-tag: remove tag from ships
::
:: crash if ships are not in group or tag does not exist
2020-05-15 01:50:04 +03:00
::
++ remove-tag
|= [rid=resource =tag ships=(set ship)]
2020-05-15 01:50:04 +03:00
^- (quip card _state)
=/ =group
(~(got by groups) rid)
2020-05-15 01:50:04 +03:00
?> ?& ?=(~ (~(dif in ships) members.group))
2020-05-27 09:19:29 +03:00
(~(has by tags.group) tag)
2020-05-15 01:50:04 +03:00
==
2020-05-27 09:19:29 +03:00
=/ tag-ships
(~(got by tags.group) tag)
=. tag-ships
(~(dif in tag-ships) ships)
=. tags.group
(~(put by tags.group) tag tag-ships)
=. groups
(~(put by groups) rid group)
2020-05-15 01:50:04 +03:00
:_ state
(send-diff %remove-tag rid tag ships)
2020-05-15 01:50:04 +03:00
:: initial-group: initialize foreign group
::
++ initial-group
|= [rid=resource =group]
2020-05-15 01:50:04 +03:00
^- (quip card _state)
=. groups
(~(put by groups) rid group)
2020-05-15 01:50:04 +03:00
:_ state
(send-diff %initial-group rid group)
2020-05-15 01:50:04 +03:00
:: +change-policy: modify group access control
::
2020-05-21 07:30:02 +03:00
:: If the change will kick members, then send a separate
:: %remove-members diff after the %change-policy diff
2020-05-15 01:50:04 +03:00
++ change-policy
|= [rid=resource =diff:policy]
2020-05-15 01:50:04 +03:00
^- (quip card _state)
?. (~(has by groups) rid)
2020-05-15 01:50:04 +03:00
[~ state]
=/ =group
(~(got by groups) rid)
2020-05-15 01:50:04 +03:00
|^
2020-05-21 07:30:02 +03:00
=^ cards group
?- -.diff
%open (open +.diff)
%invite (invite +.diff)
%replace (replace +.diff)
2020-05-15 01:50:04 +03:00
==
=. groups
(~(put by groups) rid group)
2020-05-15 01:50:04 +03:00
:_ state
2020-05-21 07:30:02 +03:00
%+ weld
(send-diff %change-policy rid diff)
2020-05-21 07:30:02 +03:00
cards
2020-05-15 01:50:04 +03:00
::
++ open
|= =diff:open:policy
?- -.diff
%allow-ranks (allow-ranks +.diff)
%ban-ranks (ban-ranks +.diff)
%allow-ships (allow-ships +.diff)
%ban-ships (ban-ships +.diff)
==
::
++ invite
|= =diff:invite:policy
?- -.diff
%add-invites (add-invites +.diff)
%remove-invites (remove-invites +.diff)
==
::
2020-05-15 01:50:04 +03:00
++ allow-ranks
|= ranks=(set rank:title)
2020-05-21 07:30:02 +03:00
^- (quip card _group)
?> ?=(%open -.policy.group)
=. ban-ranks.policy.group
(~(dif in ban-ranks.policy.group) ranks)
2020-05-21 07:30:02 +03:00
`group
2020-05-15 01:50:04 +03:00
::
++ ban-ranks
|= ranks=(set rank:title)
2020-05-21 07:30:02 +03:00
^- (quip card _group)
?> ?=(%open -.policy.group)
=. ban-ranks.policy.group
(~(uni in ban-ranks.policy.group) ranks)
2020-05-21 07:30:02 +03:00
`group
2020-05-15 01:50:04 +03:00
::
++ allow-ships
|= ships=(set ship)
2020-05-21 07:30:02 +03:00
^- (quip card _group)
?> ?=(%open -.policy.group)
=. banned.policy.group
(~(dif in banned.policy.group) ships)
`group
2020-05-15 01:50:04 +03:00
::
++ ban-ships
|= ships=(set ship)
2020-05-21 07:30:02 +03:00
^- (quip card _group)
?> ?=(%open -.policy.group)
=. banned.policy.group
(~(uni in banned.policy.group) ships)
=/ to-remove=(set ship)
(~(int in members.group) banned.policy.group)
:- ~[(poke-us %remove-members rid to-remove)]
2020-05-21 07:30:02 +03:00
group
::
++ add-invites
|= ships=(set ship)
^- (quip card _group)
?> ?=(%invite -.policy.group)
=. pending.policy.group
(~(uni in pending.policy.group) ships)
`group
::
++ remove-invites
|= ships=(set ship)
^- (quip card _group)
?> ?=(%invite -.policy.group)
=. pending.policy.group
(~(uni in pending.policy.group) ships)
`group
++ replace
|= =policy
^- (quip card _group)
=. policy.group
policy
`group
2020-05-15 01:50:04 +03:00
--
:: +remove-group: remove group from store
::
:: no-op if group does not exist
++ remove-group
|= [rid=resource ~]
2020-05-15 01:50:04 +03:00
^- (quip card _state)
?. (~(has by groups) rid)
2020-05-15 01:50:04 +03:00
`state
=. groups
(~(del by groups) rid)
2020-05-15 01:50:04 +03:00
:_ state
(send-diff %remove-group rid ~)
2020-05-15 01:50:04 +03:00
::
--
2020-05-25 08:52:54 +03:00
++ merge-tags
|= [=tags ships=(set ship) new-tags=(set tag)]
2020-05-27 09:19:29 +03:00
^+ tags
=/ tags-list ~(tap in new-tags)
2020-05-25 08:52:54 +03:00
|-
2020-05-27 09:19:29 +03:00
?~ tags-list
tags
=* tag i.tags-list
=/ old-ships=(set ship)
(~(gut by tags) tag ~)
2020-05-25 08:52:54 +03:00
%= $
2020-05-27 09:19:29 +03:00
tags-list t.tags-list
2020-05-25 08:52:54 +03:00
::
2020-05-27 09:19:29 +03:00
tags
%+ ~(put by tags)
tag
(~(uni in old-ships) ships)
2020-05-25 08:52:54 +03:00
==
2020-05-21 07:30:02 +03:00
++ remove-tags
|= [=group ships=(set ship)]
2020-05-27 09:19:29 +03:00
^- tags
%- malt
2020-05-25 08:52:54 +03:00
%+ turn
2020-05-27 09:19:29 +03:00
~(tap by tags.group)
2020-05-21 07:30:02 +03:00
|= [=tag tagged=(set ship)]
:- tag
(~(dif in tagged) ships)
::
++ poke-us
|= =action:store
^- card
[%pass / %agent [our.bol %group-store] %poke %group-action !>(action)]
2020-05-15 01:50:04 +03:00
:: +send-diff: update subscribers of new state
2019-11-21 02:18:45 +03:00
::
2020-05-15 01:50:04 +03:00
:: We only allow subscriptions on /groups
:: so just give the fact there.
2019-11-21 02:18:45 +03:00
++ send-diff
2020-05-15 01:50:04 +03:00
|= =update:store
2019-11-21 02:18:45 +03:00
^- (list card)
2020-05-15 01:50:04 +03:00
[%give %fact ~[/groups] %group-update !>(update)]~
2019-11-21 02:18:45 +03:00
::
--