Skip to content
This repository has been archived by the owner on Aug 14, 2019. It is now read-only.

Clay permissions #610

Merged
merged 39 commits into from
Feb 14, 2018
Merged

Clay permissions #610

merged 39 commits into from
Feb 14, 2018

Conversation

Fang-
Copy link
Member

@Fang- Fang- commented Feb 8, 2018

As discussed internally, permissions for the filesystem.

Permissions are set for all revisions of a node. If a node doesn't have permissions set, those of the parent node are used. If no permissions are set all the way up to root, we default to fully private.

The clay interface sees some additions to support basic permissions management.

++task:

  • {$cred our/ship nom/@ta cew/crew} for setting permission groups.
  • {$crew our/ship} for getting permission groups.
  • {$perm our/ship des/desk pax/path rit/rite} for setting permissions for a node.
  • A %p ++care for reading permissions set for a node on a local desk.

++gift:

  • {$cruz cez/(map @ta crew)}, the response to %crew requests.
  • {$rule red/dict wit/dict}, the response to %p file requests.

And a notable change that was required for making permission checks actually functional:
The interface for %warp file request now includes a ship which has to be set to the requesting ship.
When doing a %warp for local data, you just set it to our, as you do for many other tasks. When doing a %west for foreign data, the target ship automatically turns it into a %warp with the original sender specified.

Read requests from foreign ships come in as %wests. They now get re-sent to the local clay as %werps, which get dealt with as %warps that require permission checks. No checks are done for write requests, because those only originate locally right now.

Eventually, the above will be more elegantly solved from within arvo itself, passing vanes a pair of recipients and responsible ships for each incoming event. Not to mention making a global our available once the new boot sequence lands. Changing this to make use of that shouldn't be difficult.

Aside, having to take original requester into account when deduping requests likely completely obliterates any use that still saw. We're fine to keep it in, but at this point it might be costing more performance than it'll ever gain us.

Need to do more thorough testing and implement a state adapter, but it boots (off an updated pill at least) and seems to work as advertised so far, so I'd say that's good enough for review/discussion.

@Fang- Fang- added request for comments needs further discussion %clay labels Feb 8, 2018
Fang added 2 commits February 8, 2018 14:39
This also makes live-updating to this new clay easier.
@Fang-
Copy link
Member Author

Fang- commented Feb 8, 2018

Changing the %warp interface was giving problems, new-style %warp events were being sent before clay itself got properly updates to handle them.
Settled on adding %werp for incoming external read requests and leaving %warp unchanged. This makes upgrading easier, doesn't break compatibility, and keeps the internal file request interface clean.

Fang added 4 commits February 8, 2018 21:58
For some reason it/hood's not getting compiled against the latest zuse?
Set permissions for that during boot and clay update.
Copy link
Contributor

@belisarius222 belisarius222 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks structurally sound, and I think it'll work. Some stylistic comments and a few questions before I'll sign off on it.

@@ -367,6 +375,7 @@
::
:: -- current time `now`
:: -- current duct `hen`
:: -- foreign requester `for`, if any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this in the state anywhere.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lingering trace of experimentation. Will delete.

@@ -421,6 +430,8 @@
dom=*dome
dok=~
mer=~
per=[[/ %black ~] ~ ~]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not want to default everything to private, i.e. a whitelist with no elements?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the defaults for local copies of foreign desks. Those are not accessible by outsiders over the network. In a previous iteration of the PR setting these to be readable was required.
That said, the current version always says "no permission checks" for all internal requests, so there's no need to set permissions here explicitly anymore.

@@ -2193,7 +2238,7 @@
:: Gets a map of the data at the given path and all children of it.
::
++ lobes-at-path
|= {yon/aeon pax/path}
|= {for/(unit ship) yon/aeon pax/path}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like an unused argument.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be used, since this is how %many requests get their data. Going to add a permission check here.

=+ yak=(tako-to-yaki u.tak)
=+ len=(lent pax)
=- (levy ~(tap in -) |=(p/path (allowed-by who p per.red)))
%+ roll ~(tap in (~(del in ~(key by q.yak)) pax))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems likely to be a duplicate of the usual %y / %z logic. If so it might be good to make a little helper function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not an exact match. %y wants just the path, %z wants lobes too, and they both want only the path tails, where the permission check just wants the full paths.
The logic it still fairly transferable though, the data structures here are easy enough to work with. Having one function for "get child nodes with tail paths" seems to give a net gain to simplicity.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm having trouble finding a helper function here that isn't in some way terrible to use for two out of three cases. Problem is that if we do a dir listing for /one with the following data stored, then we still want to see ./two show up, but we can't provide a lobe alongside that, unlike for ./three

/one/two/x
/one/two/y
/one/three

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, no need to force it if it doesn't feel right.

|= {w/whom h/?}
?: h &
?: ?=($& -.w) =(w &+who)
(~(has in (fall (~(get by cez) p.w) ~)) who)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could (~(get by cez) p.w) ever fail? I feel like that should be a ~(got by ...)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It totally can. Either I added a group which I haven't defined yet, or I deleted a group and there's still references to it lingering.

::.
$cred
=. cez.ruf
?~ cew.q.hic (~(del by cez.ruf) nom.q.hic)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q.hic could really use an alias. Comparing p.q.hic and p.q.q.hic a little later in this function is cruel and unusual punishment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, even just aliasing q.hic to req makes a world of difference.
I also made a commit that adds actual faces to the ++task. Not sure if that's boyscouting a bit too aggressively.

?: ?=($warp -.q.hic)
[~ q.hic]
:_ [%warp q.q.hic r.q.hic]
?: =(p.q.hic p.q.q.hic) ~&([%huh-this-west-may-be-weird p.q.hic] ~)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's weird about it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing but the fact that I left a debug statement in it. Cleaning up.

:: :* %someones-warping
:: rav=u.q.q.q.hic
:: rav=u.q.r.q.hic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no way I can reasonably review u.q.r.q.hic. I realize this was already the style in this part of the code, but it's not fit for human consumption.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This particular comment can probably just get removed, but I agree that I should probably add a few =* here.

=/ cul
|= a/cult-2 ^- cult
|= a/cult-3 ^- cult
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be cleaner as a |^ since it has so many internal functions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, on it!

@@ -280,7 +281,7 @@
(sync %home our %base)
(init-sync %home our %base)
=. +> ?. ?=(?($duke $king $czar) can) +>
(sync %kids our %base)
(show %kids):(sync %kids our %base)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why this change was necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all local desks are fully private by default, we need to make our %kids desk public explicitly if we want people to be able to sync with it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a comment here would be helpful.

|= pes/regs
^+ pes
=- (~(gas in *regs) -)
%+ murn ~(tap by pes)
Copy link
Contributor

@belisarius222 belisarius222 Feb 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this could be a ++skim instead of a ++murn.

@belisarius222
Copy link
Contributor

Looks good to me. How's the testing coming?

@Fang-
Copy link
Member Author

Fang- commented Feb 13, 2018

As you might deduce from the commits, testing pointed to a few issues that needed solving. Everything now works as expected.
Both upgrading from livenet, booting using old pill and booting using new pill all work fine and don't break syncs.

For the record, and for the future, here are the beginnings of a clay testing lib. Should work nearly identically for other vanes. Also see this bigger one for jael.
Didn't do much actual testing with this because the testing framework wasn't playing well with it and I just wanted to get this PR finished.

Included is a pair of generators for setting the readability of desks (or "directories" therein). |public and |private %desk /optional/path.

Unless there's anything other than the %kids desk that needs to remain public (web.plan maybe?), I'll call this fine to be merged. @belisarius222, want to take a final look at this?

@belisarius222
Copy link
Contributor

Re-reviewed. Looks good to me.

@belisarius222 belisarius222 merged commit e094ca4 into urbit:master Feb 14, 2018
@Fang-
Copy link
Member Author

Fang- commented Feb 14, 2018

I lied about the booting btw (thanks, last-minute additions), kiln does complain about not finding one of the new clay types if you don't boot with a new-clay pill. So we'll want to make sure to push an up-to-date latest.pill when this goes onto the network.

@belisarius222
Copy link
Contributor

Does that mean this needs to be breached in?

@Fang-
Copy link
Member Author

Fang- commented Feb 14, 2018

It doesn't need to be breached in, but I just double-checked, and the kiln changes did break the updating. Particularly, it says it can't find ++rite, a new clay type.

We could do like a partial update that doesn't include the offending kiln changes, and then push out the second half separately.
I think the slightly better solution is to do what we did when we saw similar behavior with ++riot (also used by kiln), and just include the relevant structures in kiln directly. We can then (after this has been pushed to live) remove the structure definitions from kiln for cleanliness. That won't have to be pushed out immediately. Sound good?

(I guess ultimately this is an issue of kiln not getting recompiled alongside a zuse change...)

This was referenced Feb 14, 2018
@Fang- Fang- deleted the clay-permissions branch February 21, 2018 12:21
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
%clay request for comments needs further discussion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants