-
-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extract hs-ucan from fission-core #571
Conversation
This reverts commit b6504d9.
Don't you like it when your TODO list grows while you're chasing TODO items? :P
|
fission-web-server/library/Fission/Web/Server/Handler/User/Verify.hs
Outdated
Show resolved
Hide resolved
@@ -27,7 +27,7 @@ data Heroku = Heroku | |||
data Authorization = Authorization | |||
{ sender :: Either Heroku DID | |||
, about :: Entity User | |||
, potency :: Potency | |||
, potency :: Maybe Potency -- Nothing indicates "just used for signature checking" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than dealing with the Maybe
for all possible call sites in the future, could we consider either abstracting over Potency
, or parsing that case to a different data type? It's not usable if only checking the signature, no? This type is specialized to look at the database with User
, so it's not a general use thing. Let's make error cases as unrepresentable as possible, if possible!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make error cases as unrepresentable as possible, if possible!
The newPotency
type lacks a variant the old one had before:AuthNOnly
. So basicallyOld.Potency
is isomorphic toMaybe New.Potency
. So I don't think there should be any changes in terms of what's representable. I basically moved the comment forNothing
over from the definition of the oldPotency
type.
In any way, as soon as hs-ucan is updated to UCAN 0.8 and I'm incorporating that into the fission stuff, this will change.
case eitherDecodeStrict resolvedBS of | ||
Left _ -> Left $ InvalidJWT resolvedBS | ||
Right jwt -> Right (JWT.contentOf (decodeUtf8Lenient resolvedBS), jwt) | ||
Right (UCAN.contentOf (decodeUtf8Lenient resolvedBS)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you can see an effect of one of the changes.
I've changed the UCAN.Resolver
class to only resolve to UCAN.RawContent
, instead of also decoding the JWT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I have some vague memories of also going down this path (several times?) and then putting the JWT back in 🤔 I can't remember what the scenario was — something about needing the decoded case in various code paths? — so not going to say to not do this, but just mentioning it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I just now realized that RawContent
isn't the whole JWT encoded. It's only the part without the signature. That's what I get for not reading its docs!
I'll fix this in another PR. I'm thinking that the easiest way is to return either ByteString
from resolve
, or some kind of newtype?
, toBase58Text | ||
, fromRawBytes | ||
, stripOptionalPrefix | ||
, stripOptionalPrefixBS | ||
, stripOptionalPrefixLazyBS | ||
, stripOptionalSuffix | ||
, stripOptionalSuffixBS | ||
, stripOptionalSuffixLazyBS | ||
, stripPadding | ||
, stripQuotes | ||
, stripQuotesBS | ||
, stripQuotesLazyBS | ||
, stripN | ||
, stripNBS | ||
, stripNewline | ||
, toBase58Text | ||
, textShow | ||
, wrapIn | ||
, module Web.UCAN.Internal.UTF8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't quite sure what to do with the .Internal
stuff that we've been depending on in fission-core.
So what I did was split it up, you can see me removing stuff from the fission-core .Internal.UTF8
module here, and instead reexporting the Web.UCAN.Internal.UTF8
module, where that stuff was moved to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm good point! A bunch of this stuff is actually now available in other libraries. We could switch to those, or break out a fission-utils
or something 🤔
@@ -12,30 +16,30 @@ append-only rights, so | |||
|
|||
-- | How much power allowed in an authorization | |||
data Potency | |||
= AuthNOnly -- ^ Read signature only -- just a proof. Cannot delegate further. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the AuthNOnly
constructor here, in favor of using Maybe Potency
instead of Potency
everywhere.
The reason is that in hs-ucan
we don't want to depend on Potency
(because it's also fission-specific), but we need to decode to some potency in case the ptc
key is missing completely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, for this version of UCAN totally.
Thinking out loud: as we bring things to up date, I imagine that we'll have something like...
data Capabilities custom
= AuthNOnly -- None
| UserDefined [custom] -- Some
| AllByParenthood DID -- All (e.g. Linking)
...but obviously we need to actually solidify that in the v0.8 spec before we do that.
canDelegate rsc rscProof = | ||
case (rsc, rscProof) of | ||
(FissionFileSystem path, FissionFileSystem proofPath) -> | ||
case (isPrivate path, isPrivate proofPath, pathSubset path proofPath) of | ||
(True, True, _) -> | ||
bitwiseContains proofPath path | ||
|
||
(_, _, True) -> | ||
True | ||
|
||
_ -> | ||
False | ||
|
||
(RegisteredDomain _, RegisteredDomain Complete) -> | ||
True | ||
|
||
(FissionApp _, FissionApp Complete) -> | ||
True | ||
|
||
_ -> | ||
rsc == rscProof |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is code adapted from a previous function Fission.Web.Auth.Token.JWT.Proof.WNFS.compareSubsets
import Web.UCAN.Resolver.Error as Resolver | ||
|
||
class Monad m => Resolver m where | ||
resolve :: CID -> m (Either Resolver.Error UCAN.RawContent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's what I've been talking about (above?): The Resolver
class now returns
Either Resolver.Error UCAN.RawContent
instead of
Either Resolver.Error (UCAN.RawContent, UCAN.UCAN fct ptc rsc)
,
which just makes it a little simpler by getting rid of some dependencies on what fct
, ptc
and rsc
are.
I've changed the base branch to |
instance DelegationSemantics rsc => DelegationSemantics (Scope rsc) where | ||
Complete `canDelegate` _ = True | ||
(Subset _) `canDelegate` Complete = False | ||
(Subset rscProof) `canDelegate` (Subset rsc) = rscProof `canDelegate` rsc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Add ipfs in hie.yaml * Move fission-core tests into fission-core * Move Fission.Test.Web.Server.Auth to Fission.Test.Web.Auth * Move some modules around * Move SemVer and Potency over * Move key stuff * Move Internal & Orphanage stuff * Format files * Remove remaining dependencies * Remove hie.yaml * Move over hs-ucan stuff * Remove most Fission.Prelude imports from hs-ucan * Abstract out facts & resource types in JWT * Format files * Make hs-ucan and fission-core compile * Make fission-core compile & run * Rename a test function * Move AlreadyExists back to fission-core * Format files & don't duplicate UTF8 helpers * Also re-export symmetric in Fission/Key * Use type alias instead of newtype * Move things from Web.JWT or Ucan.Internal to Web.Ucan * Rename JWT stuff into Ucan * Make Resolver use only a single type param * Format files * Revert "Format files" This reverts commit b6504d9. * Format files * Get everything compiling except for fission-web-server * Make everything COMPILE AGAIN 🙌 * Use the same uppercase UCAN everywhere * Upgrade cachix/install-nix-action@v16 * Move Potency type to fission-core (& make it Maybe) * Add a test for Potency * Make everything compile (& format) * Rename `ResourceSemantics` to `DelegationSemantics` * Once and forall fix this broken test * Initialise test suite in hs-ucan * Write partial order property tests for canDelegate * Copy over some tests and write some new * Fix signature * Don't use Flow * Fix imports * Switch LICENSE to Apache 2 * Use >>= instead of <&> * Remove unneccesary AllowAmbigousTypes * We need more $$$ * Even more $$$
This is work on #561
To do this, some dependencies on fission-specific UCAN stuff had to be broken up. The main point here being the definition of
Fact
and the resource typeScope Resource
. (In hindsight I thinkScope
actually still belongs to hs-ucan, but now I've already done it this way, and we'll have to change these parts of the code when supporting the new UCAN version anyway.)That means that we can't directly run
JWT.check
and know how to check delegation validity in UCANs. So I've abstracted that logic out into aResourceSemantics
class:(Which is structurally equivalent to something like a
PartialOrder
typeclass, but I like giving it a dedicated name.)There are still some parts that need work.
Error.AlreadyExists
should be a hs-ucan module..Internal
modules again, making sure that we really only have modules in there that make senseI think I want to introduce aMy current thinking is: Let's introduce that file once we have something to put into it.Web.JWT
module, which reexportsWeb.JWT.Types
.newtype JWT
andnewtype Proof
or both are type aliases. But if I didn't type-aliasProof
, I'd be taking non-newtyped proofs out of JWTs and just re-newtype them. I'm thinking that this might get obsolete when I start working on hs-ucan anyway. I have some recursion-schemes thoughts.Web.JWT.*
for the hs-ucan stuff. I'd love some input. MaybeWeb.Ucan.*
?Proof.Resolver
class, which now has 3 type parameters instead of one.And a final TODO item unrelated to hs-ucan or fission-core: