Skip to content

Commit

Permalink
Merge pull request #19 from divarvel/secret-project
Browse files Browse the repository at this point in the history
biscuit v2
  • Loading branch information
divarvel authored Oct 6, 2021
2 parents 1ad4f08 + 9e965c3 commit b5d25f4
Show file tree
Hide file tree
Showing 56 changed files with 4,604 additions and 2,032 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This is the repository for a collection of haskell libraries providing support f

You will find below the main lib and its companions:

* [biscuit](./biscuit/) — Main library, providing minting and signature checking of biscuit tokens, as well as a datalog engine allowing to compute the validity of a token in a given context
* [biscuit](./biscuit/) — Main library, providing minting and signature verification of biscuit tokens, as well as a datalog engine allowing to compute the validity of a token in a given context
* [biscuit-servant](./biscuit-servant) — Servant combinators, for a smooth integration in your API

## Supported biscuit versions
Expand Down
8 changes: 8 additions & 0 deletions biscuit-servant/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.PHONY: ghcid
ghcid:
ghcid -l -c 'cabal repl'

.PHONY: ghcid-tests
ghcid-tests:
ghcid -l -c 'cabal repl biscuit-servant-test' -T main

.PHONY: configure
configure:
cabal configure --enable-tests --test-show-details=direct --disable-optimization
Expand Down
6 changes: 3 additions & 3 deletions biscuit-servant/biscuit-servant.cabal
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cabal-version: 2.0

name: biscuit-servant
version: 0.1.1.0
version: 0.2.0.0
category: Security
synopsis: Servant support for the Biscuit security token
description: Please see the README on GitHub at <https://github.com/divarvel/biscuit-haskell#readme>
Expand Down Expand Up @@ -33,7 +33,7 @@ library
ghc-options: -Wall
build-depends:
base >= 4.7 && <5,
biscuit-haskell ^>= 0.1,
biscuit-haskell ^>= 0.2,
bytestring ^>= 0.10,
mtl ^>= 2.2,
text ^>= 1.2,
Expand All @@ -45,7 +45,7 @@ test-suite biscuit-servant-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
AppWithVerifier
AppWithAuthorizer
ClientHelpers
hs-source-dirs:
test
Expand Down
466 changes: 249 additions & 217 deletions biscuit-servant/src/Auth/Biscuit/Servant.hs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module AppWithVerifier where
module AppWithAuthorizer where

import Auth.Biscuit
import Auth.Biscuit.Servant
Expand All @@ -31,7 +31,7 @@ call3 b =
let (_ :<|> _ :<|> e3) = client @API Proxy (protect b)
in e3

type H = WithVerifier Handler
type H = WithAuthorizer Handler
type API = RequireBiscuit :> ProtectedAPI
type ProtectedAPI =
"endpoint1" :> Get '[JSON] Int
Expand All @@ -46,21 +46,21 @@ server :: Server API
server b =
let nowFact = do
now <- liftIO getCurrentTime
pure [verifier|now(#ambient, ${now});|]
handleAuth :: WithVerifier Handler x -> Handler x
pure [authorizer|time(${now});|]
handleAuth :: WithAuthorizer Handler x -> Handler x
handleAuth =
handleBiscuit b
. withPriorityVerifierM nowFact
. withPriorityVerifier [verifier|allow if right(#authority, #admin);|]
. withFallbackVerifier [verifier|allow if right(#authority, #anon);|]
. withPriorityAuthorizerM nowFact
. withPriorityAuthorizer [authorizer|allow if right("admin");|]
. withFallbackAuthorizer [authorizer|allow if right("anon");|]
handlers = handler1 :<|> handler2 :<|> handler3
in hoistServer @ProtectedAPI Proxy handleAuth handlers

handler1 :: H Int
handler1 = withVerifier [verifier|allow if right(#authority, #one);|] $ pure 1
handler1 = withAuthorizer [authorizer|allow if right("one");|] $ pure 1

handler2 :: Int -> H Int
handler2 v = withVerifier [verifier|allow if right(#authority, #two, ${v});|] $ pure 2
handler2 v = withAuthorizer [authorizer|allow if right("two", ${v});|] $ pure 2

handler3 :: H Int
handler3 = withVerifier [verifier|deny if true;|] $ pure 3
handler3 = withAuthorizer [authorizer|deny if true;|] $ pure 3
45 changes: 22 additions & 23 deletions biscuit-servant/test/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,21 @@ import Data.Text.Encoding (decodeUtf8)
import Data.Time (UTCTime, addUTCTime, getCurrentTime)
import Test.Hspec

import AppWithVerifier (app, call1, call2, call3)
import AppWithAuthorizer (app, call1, call2, call3)
import ClientHelpers (runC, withApp)

main :: IO ()
main = do
keypair <- fromPrivateKey appPrivateKey
let appPk = toPublic appSecretKey
later <- addUTCTime (60*5) <$> getCurrentTime
earlier <- addUTCTime (-60) <$> getCurrentTime
let appPk = publicKey keypair
adminB <- toText <$> mkAdminBiscuit keypair
anonB <- toText <$> mkAnonBiscuit keypair
e1 <- toText <$> mkE1Biscuit keypair
e21 <- toText <$> mkE2Biscuit 1 keypair
e22 <- toText <$> mkE2Biscuit 2 keypair
ttld <- toText <$> (addTtl later =<< mkAdminBiscuit keypair)
expd <- toText <$> (addTtl earlier =<< mkAdminBiscuit keypair)
adminB <- toText <$> mkAdminBiscuit appSecretKey
anonB <- toText <$> mkAnonBiscuit appSecretKey
e1 <- toText <$> mkE1Biscuit appSecretKey
e21 <- toText <$> mkE2Biscuit 1 appSecretKey
e22 <- toText <$> mkE2Biscuit 2 appSecretKey
ttld <- toText <$> (addTtl later =<< mkAdminBiscuit appSecretKey)
expd <- toText <$> (addTtl earlier =<< mkAdminBiscuit appSecretKey)
print adminB
hspec $
around (withApp $ app appPk) $
Expand All @@ -50,24 +49,24 @@ main = do
runC port (call1 ttld) `shouldReturn` Right 1
runC port (call1 expd) `shouldReturn` Left (Just "Biscuit failed checks")

appPrivateKey :: PrivateKey
appPrivateKey = fromJust . parsePrivateKeyHex $ "c2b7507af4f849fd028d0f7e90b04a4e74d9727b358fca18b65beffd86c47209"
appSecretKey :: SecretKey
appSecretKey = fromJust . parseSecretKeyHex $ "c2b7507af4f849fd028d0f7e90b04a4e74d9727b358fca18b65beffd86c47209"

toText :: Biscuit -> Text
toText :: BiscuitProof p => Biscuit p Verified -> Text
toText = decodeUtf8 . serializeB64

mkAdminBiscuit :: Keypair -> IO Biscuit
mkAdminBiscuit kp = mkBiscuit kp [block|right(#authority, #admin);|]
mkAdminBiscuit :: SecretKey -> IO (Biscuit Open Verified)
mkAdminBiscuit sk = mkBiscuit sk [block|right("admin");|]

mkAnonBiscuit :: Keypair -> IO Biscuit
mkAnonBiscuit kp = mkBiscuit kp [block|right(#authority, #anon);|]
mkAnonBiscuit :: SecretKey -> IO (Biscuit Open Verified)
mkAnonBiscuit sk = mkBiscuit sk [block|right("anon");|]

mkE1Biscuit :: Keypair -> IO Biscuit
mkE1Biscuit kp = mkBiscuit kp [block|right(#authority, #one);|]
mkE1Biscuit :: SecretKey -> IO (Biscuit Open Verified)
mkE1Biscuit sk = mkBiscuit sk [block|right("one");|]

mkE2Biscuit :: Int -> Keypair -> IO Biscuit
mkE2Biscuit v kp = mkBiscuit kp [block|right(#authority, #two, ${v});|]
mkE2Biscuit :: Int -> SecretKey -> IO (Biscuit Open Verified)
mkE2Biscuit v sk = mkBiscuit sk [block|right("two", ${v});|]

addTtl :: UTCTime -> Biscuit -> IO Biscuit
addTtl :: UTCTime -> Biscuit Open Verified -> IO (Biscuit Open Verified)
addTtl expiration =
addBlock [block|check if now(#ambient,$now), $now < ${expiration};|]
addBlock [block|check if time($now), $now < ${expiration};|]
6 changes: 5 additions & 1 deletion biscuit/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.PHONY: ghcid
ghcid:
ghcid -l -c 'stack ghci biscuit-haskell:lib biscuit-haskell:biscuit-haskell-test' -T main
ghcid -l -c 'cabal repl'

.PHONY: ghcid-tests
ghcid-tests:
ghcid -l -c 'cabal repl biscuit-haskell-test' -T main

.PHONY: configure
configure:
Expand Down
2 changes: 1 addition & 1 deletion biscuit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<img src="https://raw.githubusercontent.com/divarvel/biscuit-haskell/main/assets/biscuit-logo.png" align=right>

Main library for biscuit tokens support, providing minting and signature checking of biscuit tokens, as well as a datalog engine allowing to compute the validity of a token in a given context.
Main library for biscuit tokens support, providing minting and signature verification of biscuit tokens, as well as a datalog engine allowing to compute the validity of a token in a given context.

## Supported biscuit versions

Expand Down
19 changes: 9 additions & 10 deletions biscuit/benchmarks/Bench.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ import Criterion.Main
import Auth.Biscuit
import Data.Maybe (fromJust)

buildToken :: Keypair -> IO Biscuit
buildToken keypair = do
mkBiscuit keypair [block|user_id(#authority, "user_1234");|]
buildToken :: SecretKey -> IO (Biscuit Open Verified)
buildToken sk = do
mkBiscuit sk [block|user_id("user_1234");|]

-- Our benchmark harness.
main = do
keypair <- newKeypair
biscuit <- buildToken keypair
let pubkey = publicKey keypair
sk <- newSecret
biscuit <- buildToken sk
let pk = toPublic sk
let biscuitBs = serialize biscuit
defaultMain [
bgroup "biscuit" [ bench "mkBiscuit" $ whnfIO (buildToken keypair)
, bench "parse" $ whnf parse biscuitBs
bgroup "biscuit" [ bench "mkBiscuit" $ whnfIO (buildToken sk)
, bench "parse" $ whnf (parse pk) biscuitBs
, bench "serialize" $ whnf serialize biscuit
, bench "checkSig" $ whnfIO (checkBiscuitSignature biscuit pubkey)
, bench "verify" $ whnfIO (verifyBiscuit biscuit [verifier|allow if user_id(#authority, "user_1234");|] pubkey)
, bench "verify" $ whnfIO (authorizeBiscuit biscuit [authorizer|allow if user_id("user_1234");|])
]
]
22 changes: 11 additions & 11 deletions biscuit/biscuit-haskell.cabal
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cabal-version: 2.0

name: biscuit-haskell
version: 0.1.1.0
version: 0.2.0.0
category: Security
synopsis: Library support for the Biscuit security token
description: Please see the README on GitHub at <https://github.com/divarvel/biscuit-haskell#readme>
Expand All @@ -25,13 +25,14 @@ library
exposed-modules:
Auth.Biscuit
Auth.Biscuit.Utils
Auth.Biscuit.Crypto
Auth.Biscuit.Datalog.AST
Auth.Biscuit.Datalog.Executor
Auth.Biscuit.Datalog.Parser
Auth.Biscuit.Datalog.ScopedExecutor
Auth.Biscuit.Example
Auth.Biscuit.Proto
Auth.Biscuit.ProtoBufAdapter
Auth.Biscuit.Sel
Auth.Biscuit.Timer
Auth.Biscuit.Token
other-modules:
Expand All @@ -48,12 +49,12 @@ library
bytestring ^>= 0.10,
text ^>= 1.2,
containers ^>= 0.6,
cryptonite ^>= 0.27,
memory ^>= 0.15,
template-haskell ^>= 2.16,
attoparsec ^>= 0.13,
primitive ^>= 0.7,
base64 ^>= 0.4,
cereal ^>= 0.5,
libsodium ^>= 1.0,
mtl ^>= 2.2,
parser-combinators ^>= 1.2,
protobuf ^>= 0.2,
Expand Down Expand Up @@ -81,10 +82,8 @@ executable biscuit-haskell-exe
, bytestring
, cereal
, containers
, libsodium
, mtl
, parser-combinators
, primitive
, protobuf
, random
, template-haskell
Expand All @@ -98,20 +97,22 @@ test-suite biscuit-haskell-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Spec.Crypto
Spec.NewCrypto
Spec.Executor
Spec.Parser
Spec.Quasiquoter
Spec.RevocationIds
Spec.Roundtrip
Spec.Samples
Spec.SampleReader
Spec.ScopedExecutor
Spec.Verification
Paths_biscuit_haskell
hs-source-dirs:
test
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
async
, aeson
, attoparsec
, base >=4.7 && <5
, base16-bytestring ^>=0.1
Expand All @@ -120,10 +121,9 @@ test-suite biscuit-haskell-test
, bytestring
, cereal
, containers
, libsodium
, cryptonite
, mtl
, parser-combinators
, primitive
, protobuf
, random
, tasty
Expand All @@ -140,7 +140,7 @@ benchmark biscuit-bench
main-is: Bench.hs
hs-source-dirs: benchmarks
default-language: Haskell2010
ghc-options: -O -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T
ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T
build-depends: base
, criterion
, biscuit-haskell
Loading

0 comments on commit b5d25f4

Please sign in to comment.