{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module Spec.Samples
( specs
) where
import qualified Data.ByteString as ByteString
import Test.Tasty
import Test.Tasty.HUnit
import Auth.Biscuit (ParseError (..), parse)
import Auth.Biscuit.Datalog.AST (Block)
import Auth.Biscuit.Datalog.Parser (block)
import Auth.Biscuit.Token (Biscuit (..))
readFromFile :: FilePath -> IO (Either ParseError Biscuit)
readFromFile path =
parse <$> ByteString.readFile ("test/samples/" <> path)
getAuthority :: Biscuit -> Block
getAuthority = snd . snd . authority
getBlocks :: Biscuit -> [Block]
getBlocks = fmap (snd . snd) . blocks
specs :: TestTree
specs = testGroup "Biscuit samples"
[ testCase "test1_basic" $ do
result <- readFromFile "test1_basic.bc"
getAuthority <$> result @?= Right
[block|
right(#authority, "file1", #read);
right(#authority, "file2", #read);
right(#authority, "file1", #write);
|]
getBlocks <$> result @?= Right
[ [block|
check if
resource(#ambient, $0),
operation(#ambient, #read),
right(#authority, $0, #read);
|]
]
, testCase "test9_expired_token" $ do
result <- readFromFile "test9_expired_token.bc"
getAuthority <$> result @?= Right mempty
getBlocks <$> result @?= Right
[ [block|
check if resource(#ambient, "file1");
check if time(#ambient, $date), $date <= 2018-12-20T00:00:00+00:00;
|]
]
, testCase "test13_block_rules" $ do
result <- readFromFile "test13_block_rules.bc"
getAuthority <$> result @?= Right
[block|
right(#authority, "file1", #read);
right(#authority, "file2", #read);
|]
getBlocks <$> result @?= Right
[ [block|
valid_date("file1") <- time(#ambient, $0), resource(#ambient, "file1"), $0 <= 2030-12-31T12:59:59+00:00;
valid_date($1) <- time(#ambient, $0), resource(#ambient, $1), $0 <= 1999-12-31T12:59:59+00:00, !["file1"].contains($1);
check if valid_date($0), resource(#ambient, $0);
|]
]
, testCase "test17_expressions" $ do
result <- readFromFile "test17_expressions.bc"
getAuthority <$> result @?= Right
[block|
check if true;
check if !false;
check if !false;
check if false or true;
check if 1 < 2;
check if 2 > 1;
check if 1 <= 2;
check if 1 <= 1;
check if 2 >= 1;
check if 2 >= 2;
check if 3 == 3;
check if 1 + 2 * 3 - 4 / 2 == 5;
check if "hello world".starts_with("hello") && "hello world".ends_with("world");
check if "aaabde".matches("a*c?.e");
check if "abcD12" == "abcD12";
check if 2019-12-04T09:46:41+00:00 < 2020-12-04T09:46:41+00:00;
check if 2020-12-04T09:46:41+00:00 > 2019-12-04T09:46:41+00:00;
check if 2019-12-04T09:46:41+00:00 <= 2020-12-04T09:46:41+00:00;
check if 2020-12-04T09:46:41+00:00 >= 2020-12-04T09:46:41+00:00;
check if 2020-12-04T09:46:41+00:00 >= 2019-12-04T09:46:41+00:00;
check if 2020-12-04T09:46:41+00:00 >= 2020-12-04T09:46:41+00:00;
check if 2020-12-04T09:46:41+00:00 == 2020-12-04T09:46:41+00:00;
check if #abc == #abc;
check if hex:12ab == hex:12ab;
check if [1, 2].contains(2);
check if [2019-12-04T09:46:41+00:00, 2020-12-04T09:46:41+00:00].contains(2020-12-04T09:46:41+00:00);
check if [false, true].contains(true);
check if ["abc", "def"].contains("abc");
check if [hex:12ab, hex:34de].contains(hex:34de);
check if [#hello, #world].contains(#hello);
|]
getBlocks <$> result @?= Right []
]