biscuit-haskell 0.3.0.1 → 0.4.0.0
raw patch · 41 files changed
+2439/−1820 lines, 41 filesbinary-addedPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- ChangeLog.md +13/−0
- README.md +3/−3
- biscuit-haskell.cabal +1/−1
- src/Auth/Biscuit/Datalog/Executor.hs +41/−39
- src/Auth/Biscuit/Datalog/ScopedExecutor.hs +39/−34
- src/Auth/Biscuit/ProtoBufAdapter.hs +46/−38
- src/Auth/Biscuit/Symbols.hs +0/−4
- src/Auth/Biscuit/Token.hs +10/−15
- src/Auth/Biscuit/Utils.hs +32/−3
- test/Spec/Executor.hs +19/−0
- test/Spec/SampleReader.hs +46/−24
- test/Spec/ScopedExecutor.hs +6/−6
- test/samples/current/samples.json +2183/−1653
- test/samples/current/test001_basic.bc binary
- test/samples/current/test002_different_root_key.bc binary
- test/samples/current/test003_invalid_signature_format.bc binary
- test/samples/current/test004_random_block.bc binary
- test/samples/current/test005_invalid_signature.bc binary
- test/samples/current/test006_reordered_blocks.bc binary
- test/samples/current/test007_scoped_rules.bc binary
- test/samples/current/test008_scoped_checks.bc binary
- test/samples/current/test009_expired_token.bc binary
- test/samples/current/test010_authorizer_scope.bc binary
- test/samples/current/test011_authorizer_authority_caveats.bc binary
- test/samples/current/test012_authority_caveats.bc binary
- test/samples/current/test013_block_rules.bc binary
- test/samples/current/test014_regex_constraint.bc binary
- test/samples/current/test015_multi_queries_caveats.bc binary
- test/samples/current/test016_caveat_head_name.bc binary
- test/samples/current/test017_expressions.bc binary
- test/samples/current/test018_unbound_variables_in_rule.bc binary
- test/samples/current/test019_generating_ambient_from_variables.bc binary
- test/samples/current/test020_sealed.bc binary
- test/samples/current/test021_parsing.bc binary
- test/samples/current/test022_default_symbols.bc binary
- test/samples/current/test023_execution_scope.bc binary
- test/samples/current/test024_third_party.bc binary
- test/samples/current/test025_check_all.bc binary
- test/samples/current/test026_public_keys_interning.bc binary
- test/samples/current/test027_integer_wraparound.bc binary
- test/samples/current/test028_expressions_v4.bc binary
@@ -1,5 +1,18 @@ # Changelog for biscuit-haskell +## 0.4.0.0++- abort authorization on evaluation error as mandated by the spec+- use utf8 byte count in `{string}.length()` as mandated by the spec+- fix security issue with third-party blocks public key interning++## 0.3.0.1++- GHC 9.6 and 9.8 support+- Support for `!=`+- Fixed-sized arithmetic and overflow detection+- Allow parsing chained method calls+ ## 0.3.0.0 - GHC 9.2 support
@@ -1,6 +1,6 @@ # biscuit-haskell [![CI-badge][CI-badge]][CI-url] [![Hackage][hackage]][hackage-url] -<img src="https://raw.githubusercontent.com/biscuit-auth/biscuit-haskell/main/assets/biscuit-logo.png" align=right>+<img src="https://raw.githubusercontent.com/biscuit-auth/biscuit-haskell/main/assets/logo-black-white-bg.png" align=right> 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. @@ -96,8 +96,8 @@ pure $ serializeB64 newBiscuit ``` -[CI-badge]: https://img.shields.io/github/workflow/status/Divarvel/biscuit-haskell/CI?style=flat-square-[CI-url]: https://github.com/Divarvel/biscuit-haskell/actions+[CI-badge]: https://img.shields.io/github/actions/workflow/status/biscuit-auth/biscuit-haskell/github-actions.yml?style=flat-square&branch=main+[CI-url]: https://github.com/biscuit-auth/biscuit-haskell/actions [Hackage]: https://img.shields.io/hackage/v/biscuit-haskell?color=purple&style=flat-square [hackage-url]: https://hackage.haskell.org/package/biscuit-haskell [gcouprie]: https://github.com/geal
@@ -1,7 +1,7 @@ cabal-version: 2.0 name: biscuit-haskell-version: 0.3.0.1+version: 0.4.0.0 category: Security synopsis: Library support for the Biscuit security token description: Please see the README on GitHub at <https://github.com/biscuit-auth/biscuit-haskell#readme>
@@ -53,6 +53,7 @@ import qualified Data.Set as Set import Data.Text (Text, isInfixOf, unpack) import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text import Data.Void (absurd) import Numeric.Natural (Natural) import qualified Text.Regex.TDFA as Regex@@ -60,7 +61,7 @@ import Validation (Validation (..), failure) import Auth.Biscuit.Datalog.AST-import Auth.Biscuit.Utils (maybeToRight)+import Auth.Biscuit.Utils (allM, anyM, maybeToRight, setFilterM) -- | A variable name type Name = Text@@ -105,6 +106,8 @@ | ResultError ResultError -- ^ The evaluation ran to completion, but checks and policies were not -- fulfilled.+ | EvaluationError String+ -- ^ Datalog evaluation failed while evaluating an expression deriving (Eq, Show) -- | Settings for the executor runtime restrictions.@@ -186,40 +189,40 @@ countFacts :: FactGroup -> Int countFacts (FactGroup facts) = sum $ Set.size <$> Map.elems facts --- todo handle Check All-checkCheck :: Limits -> Natural -> Natural -> FactGroup -> EvalCheck -> Validation (NonEmpty Check) ()-checkCheck l blockCount checkBlockId facts c@Check{cQueries,cKind} =+checkCheck :: Limits -> Natural -> Natural -> FactGroup -> EvalCheck -> Either String (Validation (NonEmpty Check) ())+checkCheck l blockCount checkBlockId facts c@Check{cQueries,cKind} = do let isQueryItemOk = case cKind of One -> isQueryItemSatisfied l blockCount checkBlockId facts All -> isQueryItemSatisfiedForAllMatches l blockCount checkBlockId facts- in if any (isJust . isQueryItemOk) cQueries- then Success ()- else failure (toRepresentation c)+ hasOkQueryItem <- anyM (fmap isJust . isQueryItemOk) cQueries+ pure $ if hasOkQueryItem+ then Success ()+ else failure (toRepresentation c) -checkPolicy :: Limits -> Natural -> FactGroup -> EvalPolicy -> Maybe (Either MatchedQuery MatchedQuery)-checkPolicy l blockCount facts (pType, query) =- let bindings = fold $ mapMaybe (isQueryItemSatisfied l blockCount blockCount facts) query- in if not (null bindings)- then Just $ case pType of- Allow -> Right $ MatchedQuery{matchedQuery = toRepresentation <$> query, bindings}- Deny -> Left $ MatchedQuery{matchedQuery = toRepresentation <$> query, bindings}- else Nothing+checkPolicy :: Limits -> Natural -> FactGroup -> EvalPolicy -> Either String (Maybe (Either MatchedQuery MatchedQuery))+checkPolicy l blockCount facts (pType, query) = do+ bindings <- fold . fold <$> traverse (isQueryItemSatisfied l blockCount blockCount facts) query+ pure $ if not (null bindings)+ then Just $ case pType of+ Allow -> Right $ MatchedQuery{matchedQuery = toRepresentation <$> query, bindings}+ Deny -> Left $ MatchedQuery{matchedQuery = toRepresentation <$> query, bindings}+ else Nothing -isQueryItemSatisfied :: Limits -> Natural -> Natural -> FactGroup -> QueryItem' 'Eval 'Representation -> Maybe (Set Bindings)-isQueryItemSatisfied l blockCount blockId allFacts QueryItem{qBody, qExpressions, qScope} =+isQueryItemSatisfied :: Limits -> Natural -> Natural -> FactGroup -> QueryItem' 'Eval 'Representation -> Either String (Maybe (Set Bindings))+isQueryItemSatisfied l blockCount blockId allFacts QueryItem{qBody, qExpressions, qScope} = do let removeScope = Set.map snd facts = toScopedFacts $ keepAuthorized' False blockCount allFacts qScope blockId- bindings = removeScope $ getBindingsForRuleBody l facts qBody qExpressions- in if Set.size bindings > 0- then Just bindings- else Nothing+ bindings <- removeScope <$> getBindingsForRuleBody l facts qBody qExpressions+ pure $ if Set.size bindings > 0+ then Just bindings+ else Nothing -- | Given a set of scoped facts and a rule body, we generate a set of variable -- bindings that satisfy the rule clauses (predicates match, and expression constraints -- are fulfilled), and ensure that all bindings where predicates match also fulfill -- expression constraints. This is the behaviour of `check all`.-isQueryItemSatisfiedForAllMatches :: Limits -> Natural -> Natural -> FactGroup -> QueryItem' 'Eval 'Representation -> Maybe (Set Bindings)-isQueryItemSatisfiedForAllMatches l blockCount blockId allFacts QueryItem{qBody, qExpressions, qScope} =+isQueryItemSatisfiedForAllMatches :: Limits -> Natural -> Natural -> FactGroup -> QueryItem' 'Eval 'Representation -> Either String (Maybe (Set Bindings))+isQueryItemSatisfiedForAllMatches l blockCount blockId allFacts QueryItem{qBody, qExpressions, qScope} = do let removeScope = Set.map snd facts = toScopedFacts $ keepAuthorized' False blockCount allFacts qScope blockId allVariables = extractVariables qBody@@ -228,26 +231,24 @@ -- bindings that unify correctly (each variable has a single possible match) legalBindingsForFacts = reduceCandidateBindings allVariables candidateBindings -- bindings that fulfill the constraints- constraintFulfillingBindings = Set.filter (\b -> all (satisfies l b) qExpressions) legalBindingsForFacts- in if Set.size constraintFulfillingBindings > 0 -- there is at least one match that fulfills the constraints- && constraintFulfillingBindings == legalBindingsForFacts -- all matches fulfill the constraints- then Just $ removeScope constraintFulfillingBindings- else Nothing+ constraintFulfillingBindings <- setFilterM (\b -> allM (satisfies l b) qExpressions) legalBindingsForFacts+ pure $ if Set.size constraintFulfillingBindings > 0 -- there is at least one match that fulfills the constraints+ && constraintFulfillingBindings == legalBindingsForFacts -- all matches fulfill the constraints+ then Just $ removeScope constraintFulfillingBindings+ else Nothing -- | Given a rule and a set of available (scoped) facts, we find all fact -- combinations that match the rule body, and generate new facts by applying -- the bindings to the rule head (while keeping track of the facts origins)-getFactsForRule :: Limits -> Set (Scoped Fact) -> EvalRule -> Set (Scoped Fact)-getFactsForRule l facts Rule{rhead, body, expressions} =- let legalBindings :: Set (Scoped Bindings)- legalBindings = getBindingsForRuleBody l facts body expressions- newFacts = mapMaybe (applyBindings rhead) $ Set.toList legalBindings- in Set.fromList newFacts+getFactsForRule :: Limits -> Set (Scoped Fact) -> EvalRule -> Either String (Set (Scoped Fact))+getFactsForRule l facts Rule{rhead, body, expressions} = do+ legalBindings <- getBindingsForRuleBody l facts body expressions+ pure $ Set.fromList $ mapMaybe (applyBindings rhead) $ Set.toList legalBindings -- | Given a set of scoped facts and a rule body, we generate a set of variable -- bindings that satisfy the rule clauses (predicates match, and expression constraints -- are fulfilled)-getBindingsForRuleBody :: Limits -> Set (Scoped Fact) -> [Predicate] -> [Expression] -> Set (Scoped Bindings)+getBindingsForRuleBody :: Limits -> Set (Scoped Fact) -> [Predicate] -> [Expression] -> Either String (Set (Scoped Bindings)) getBindingsForRuleBody l facts body expressions = let -- gather bindings from all the facts that match the query's predicates candidateBindings = getCandidateBindings facts body@@ -255,13 +256,13 @@ -- only keep bindings combinations where each variable has a single possible match legalBindingsForFacts = reduceCandidateBindings allVariables candidateBindings -- only keep bindings that satisfy the query expressions- in Set.filter (\b -> all (satisfies l b) expressions) legalBindingsForFacts+ in setFilterM (\b -> allM (satisfies l b) expressions) legalBindingsForFacts satisfies :: Limits -> Scoped Bindings -> Expression- -> Bool-satisfies l b e = evaluateExpression l (snd b) e == Right (LBool True)+ -> Either String Bool+satisfies l b e = (== LBool True) <$> evaluateExpression l (snd b) e applyBindings :: Predicate -> Scoped Bindings -> Maybe (Scoped Fact) applyBindings p@Predicate{terms} (origins, bindings) =@@ -372,7 +373,7 @@ evalUnary Parens t = pure t evalUnary Negate (LBool b) = pure (LBool $ not b) evalUnary Negate _ = Left "Only booleans support negation"-evalUnary Length (LString t) = pure . LInteger . fromIntegral $ Text.length t+evalUnary Length (LString t) = pure . LInteger . fromIntegral $ ByteString.length $ Text.encodeUtf8 t evalUnary Length (LBytes bs) = pure . LInteger . fromIntegral $ ByteString.length bs evalUnary Length (TermSet s) = pure . LInteger . fromIntegral $ Set.size s evalUnary Length _ = Left "Only strings, bytes and sets support `.length()`"@@ -475,3 +476,4 @@ EValue term -> applyVariable b term EUnary op e' -> evalUnary op =<< evaluateExpression l b e' EBinary op e' e'' -> uncurry (evalBinary l op) =<< join bitraverse (evaluateExpression l b) (e', e'')+
@@ -30,14 +30,13 @@ gets, lift, put) import Data.Bifunctor (first) import Data.ByteString (ByteString)-import Data.Foldable (traverse_)+import Data.Foldable (sequenceA_) import Data.List (genericLength) import Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as NE import Data.Map (Map) import qualified Data.Map as Map import Data.Map.Strict ((!?))-import Data.Maybe (mapMaybe) import Data.Set (Set) import qualified Data.Set as Set import Data.Text (Text)@@ -58,11 +57,13 @@ keepAuthorized', toScopedFacts) import Auth.Biscuit.Datalog.Parser (fact) import Auth.Biscuit.Timer (timer)+import Auth.Biscuit.Utils (foldMapM, mapMaybeM)+import Data.Bitraversable (bisequence) type BlockWithRevocationId = (Block, ByteString, Maybe PublicKey) -- | A subset of 'ExecutionError' that can only happen during fact generation-data PureExecError = Facts | Iterations | BadRule+data PureExecError = Facts | Iterations | BadRule | BadExpression String deriving (Eq, Show) -- | Proof that a biscuit was authorized successfully. In addition to the matched@@ -172,6 +173,7 @@ Facts -> TooManyFacts Iterations -> TooManyIterations BadRule -> InvalidRule+ BadExpression e -> EvaluationError e allFacts <- first toExecutionError $ computeAllFacts initState let checks = bChecks <$$> ( zip [0..] (fst' <$> authority : blocks) <> [(blockCount,vBlock authorizer)]@@ -179,13 +181,14 @@ policies = vPolicies authorizer checkResults = checkChecks limits blockCount allFacts (checkToEvaluation externalKeys <$$$> checks) policyResults = checkPolicies limits blockCount allFacts (policyToEvaluation externalKeys <$> policies)- case (checkResults, policyResults) of- (Success (), Left Nothing) -> Left $ ResultError $ NoPoliciesMatched []- (Success (), Left (Just p)) -> Left $ ResultError $ DenyRuleMatched [] p- (Failure cs, Left Nothing) -> Left $ ResultError $ NoPoliciesMatched (NE.toList cs)- (Failure cs, Left (Just p)) -> Left $ ResultError $ DenyRuleMatched (NE.toList cs) p- (Failure cs, Right _) -> Left $ ResultError $ FailedChecks cs- (Success (), Right p) -> Right $ AuthorizationSuccess { matchedAllowQuery = p+ case bisequence (checkResults, policyResults) of+ Left e -> Left $ EvaluationError e+ Right (Success (), Left Nothing) -> Left $ ResultError $ NoPoliciesMatched []+ Right (Success (), Left (Just p)) -> Left $ ResultError $ DenyRuleMatched [] p+ Right (Failure cs, Left Nothing) -> Left $ ResultError $ NoPoliciesMatched (NE.toList cs)+ Right (Failure cs, Left (Just p)) -> Left $ ResultError $ DenyRuleMatched (NE.toList cs) p+ Right (Failure cs, Right _) -> Left $ ResultError $ FailedChecks cs+ Right (Success (), Right p) -> Right $ AuthorizationSuccess { matchedAllowQuery = p , allFacts , limits }@@ -195,8 +198,10 @@ state@ComputeState{sLimits,sFacts,sRules,sBlockCount,sIterations} <- get let Limits{maxFacts, maxIterations} = sLimits previousCount = countFacts sFacts- newFacts = sFacts <> extend sLimits sBlockCount sRules sFacts- newCount = countFacts newFacts+ generatedFacts :: Either PureExecError FactGroup+ generatedFacts = first BadExpression $ extend sLimits sBlockCount sRules sFacts+ newFacts <- (sFacts <>) <$> lift generatedFacts+ let newCount = countFacts newFacts -- counting the facts returned by `extend` is not equivalent to -- comparing complete counts, as `extend` may return facts that -- are already present in `sFacts`@@ -206,7 +211,7 @@ put $ state { sIterations = sIterations + 1 , sFacts = newFacts }- return addedFactsCount+ pure addedFactsCount -- | Check if every variable from the head is present in the body checkRuleHead :: EvalRule -> Bool@@ -234,39 +239,39 @@ let initState = ComputeState{sIterations = 0, ..} in computeAllFacts initState -checkChecks :: Limits -> Natural -> FactGroup -> [(Natural, [EvalCheck])] -> Validation (NonEmpty Check) ()+checkChecks :: Limits -> Natural -> FactGroup -> [(Natural, [EvalCheck])] -> Either String (Validation (NonEmpty Check) ()) checkChecks limits blockCount allFacts =- traverse_ (uncurry $ checkChecksForGroup limits blockCount allFacts)+ fmap sequenceA_ . traverse (uncurry $ checkChecksForGroup limits blockCount allFacts) -checkChecksForGroup :: Limits -> Natural -> FactGroup -> Natural -> [EvalCheck] -> Validation (NonEmpty Check) ()+checkChecksForGroup :: Limits -> Natural -> FactGroup -> Natural -> [EvalCheck] -> Either String (Validation (NonEmpty Check) ()) checkChecksForGroup limits blockCount allFacts checksBlockId =- traverse_ (checkCheck limits blockCount checksBlockId allFacts)+ fmap sequenceA_ . traverse (checkCheck limits blockCount checksBlockId allFacts) -checkPolicies :: Limits -> Natural -> FactGroup -> [EvalPolicy] -> Either (Maybe MatchedQuery) MatchedQuery-checkPolicies limits blockCount allFacts policies =- let results = mapMaybe (checkPolicy limits blockCount allFacts) policies- in case results of- p : _ -> first Just p- [] -> Left Nothing+checkPolicies :: Limits -> Natural -> FactGroup -> [EvalPolicy] -> Either String (Either (Maybe MatchedQuery) MatchedQuery)+checkPolicies limits blockCount allFacts policies = do+ results <- mapMaybeM (checkPolicy limits blockCount allFacts) policies+ pure $ case results of+ p : _ -> first Just p+ [] -> Left Nothing -- | Generate new facts by applying rules on existing facts-extend :: Limits -> Natural -> Map Natural (Set EvalRule) -> FactGroup -> FactGroup+extend :: Limits -> Natural -> Map Natural (Set EvalRule) -> FactGroup -> Either String FactGroup extend l blockCount rules facts =- let buildFacts :: Natural -> Set EvalRule -> FactGroup -> Set (Scoped Fact)+ let buildFacts :: Natural -> Set EvalRule -> FactGroup -> Either String (Set (Scoped Fact)) buildFacts ruleBlockId ruleGroup factGroup =- let extendRule :: EvalRule -> Set (Scoped Fact)+ let extendRule :: EvalRule -> Either String (Set (Scoped Fact)) extendRule r@Rule{scope} = getFactsForRule l (toScopedFacts $ keepAuthorized' False blockCount factGroup scope ruleBlockId) r- in foldMap extendRule ruleGroup+ in foldMapM extendRule ruleGroup - extendRuleGroup :: Natural -> Set EvalRule -> FactGroup+ extendRuleGroup :: Natural -> Set EvalRule -> Either String FactGroup extendRuleGroup ruleBlockId ruleGroup = -- todo pre-filter facts based on the weakest rule scope to avoid passing too many facts -- to buildFacts let authorizedFacts = facts -- test $ keepAuthorized facts $ Set.fromList [0..ruleBlockId] addRuleOrigin = FactGroup . Map.mapKeysWith (<>) (Set.insert ruleBlockId) . getFactGroup- in addRuleOrigin . fromScopedFacts $ buildFacts ruleBlockId ruleGroup authorizedFacts+ in addRuleOrigin . fromScopedFacts <$> buildFacts ruleBlockId ruleGroup authorizedFacts - in foldMap (uncurry extendRuleGroup) $ Map.toList rules+ in foldMapM (uncurry extendRuleGroup) $ Map.toList rules collectWorld :: Natural -> EvalBlock -> (Map Natural (Set EvalRule), FactGroup)@@ -278,18 +283,18 @@ , FactGroup $ Map.singleton (Set.singleton blockId) $ Set.fromList bFacts ) -queryGeneratedFacts :: [Maybe PublicKey] -> AuthorizationSuccess -> Query -> Set Bindings+queryGeneratedFacts :: [Maybe PublicKey] -> AuthorizationSuccess -> Query -> Either String (Set Bindings) queryGeneratedFacts ePks AuthorizationSuccess{allFacts, limits} = queryAvailableFacts ePks allFacts limits -queryAvailableFacts :: [Maybe PublicKey] -> FactGroup -> Limits -> Query -> Set Bindings+queryAvailableFacts :: [Maybe PublicKey] -> FactGroup -> Limits -> Query -> Either String (Set Bindings) queryAvailableFacts ePks allFacts limits q = let blockCount = genericLength ePks getBindingsForQueryItem QueryItem{qBody,qExpressions,qScope} = let facts = toScopedFacts $ keepAuthorized' True blockCount allFacts qScope blockCount- in Set.map snd $+ in Set.map snd <$> getBindingsForRuleBody limits facts qBody qExpressions- in foldMap (getBindingsForQueryItem . toEvaluation ePks) q+ in foldMapM (getBindingsForQueryItem . toEvaluation ePks) q -- | Extract a set of values from a matched variable for a specific type. -- Returning @Set Value@ allows to get all values, whatever their type.
@@ -1,5 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiWayIf #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}@@ -25,13 +26,12 @@ , thirdPartyBlockContentsToPb ) where -import Control.Monad (when)+import Control.Monad (unless, when) import Control.Monad.State (StateT, get, lift, modify)-import Data.Bitraversable (bisequence) import Data.ByteString (ByteString) import Data.Int (Int64) import qualified Data.List.NonEmpty as NE-import Data.Maybe (isNothing)+import Data.Maybe (isJust, isNothing) import qualified Data.Set as Set import qualified Data.Text as T import Data.Time (UTCTime)@@ -110,17 +110,17 @@ -- but use the global public keys table: -- symbols defined in 3rd party blocks are not visible -- to following blocks, but public keys are- when (isNothing ePk) $ modify (registerNewSymbols blockSymbols)- modify (registerNewPublicKeys $ foldMap pure ePk <> blockPks)+ when (isNothing ePk) $ do+ modify (registerNewSymbols blockSymbols)+ modify (registerNewPublicKeys blockPks) currentSymbols <- get let symbolsForCurrentBlock =- -- third party blocks use an isolated symbol table,- -- but use the global public keys table.+ -- third party blocks use an isolated symbol and public keys table, -- 3rd party blocks don't see previously defined- -- symbols, but see previously defined public keys+ -- symbols or public keys if isNothing ePk then currentSymbols- else registerNewSymbols blockSymbols $ forgetSymbols currentSymbols+ else registerNewPublicKeys blockPks $ registerNewSymbols blockSymbols newSymbolTable let bContext = PB.getField context bVersion = PB.getField version lift $ do@@ -129,18 +129,25 @@ bRules <- traverse (pbToRule s) $ PB.getField rules_v2 bChecks <- traverse (pbToCheck s) $ PB.getField checks_v2 bScope <- Set.fromList <$> traverse (pbToScope s) (PB.getField scope)- let isV3 = isNothing ePk- && Set.null bScope- && all ruleHasNoScope bRules- && all queryHasNoScope (cQueries <$> bChecks)- && all isCheckOne bChecks- && all ruleHasNoV4Operators bRules- && all queryHasNoV4Operators (cQueries <$> bChecks)- case (bVersion, isV3) of- (Just 4, _) -> pure Block {..}- (Just 3, True) -> pure Block {..}- (Just 3, False) ->- Left "Biscuit v4 fields are present, but the block version is 3."+ let v5Plus = isJust ePk+ v4Plus = not $ and+ [ Set.null bScope+ , all ruleHasNoScope bRules+ , all (queryHasNoScope . cQueries) bChecks+ , all isCheckOne bChecks+ , all ruleHasNoV4Operators bRules+ , all (queryHasNoV4Operators . cQueries) bChecks+ ]+ case (bVersion, v4Plus, v5Plus) of+ (Just 5, _, _) -> pure Block {..}+ (Just 4, _, False) -> pure Block {..}+ (Just 4, _, True) ->+ Left "Biscuit v5 features are present, but the block version is 4."+ (Just 3, False, False) -> pure Block {..}+ (Just 3, True, False) ->+ Left "Biscuit v4 features are present, but the block version is 3."+ (Just 3, _, True) ->+ Left "Biscuit v5 features are present, but the block version is 3." _ -> Left $ "Unsupported biscuit version: " <> maybe "0" show bVersion <> ". Only versions 3 and 4 are supported" @@ -148,13 +155,15 @@ -- along with the newly defined symbols blockToPb :: Bool -> Symbols -> Block -> (BlockSymbols, PB.Block) blockToPb hasExternalPk existingSymbols b@Block{..} =- let isV3 = not hasExternalPk- && Set.null bScope- && all ruleHasNoScope bRules- && all queryHasNoScope (cQueries <$> bChecks)- && all isCheckOne bChecks- && all ruleHasNoV4Operators bRules- && all queryHasNoV4Operators (cQueries <$> bChecks)+ let v4Plus = not $ and+ [Set.null bScope+ , all ruleHasNoScope bRules+ , all (queryHasNoScope . cQueries) bChecks+ , all isCheckOne bChecks+ , all ruleHasNoV4Operators bRules+ , all (queryHasNoV4Operators . cQueries) bChecks+ ]+ v5Plus = hasExternalPk bSymbols = buildSymbolTable existingSymbols b s = reverseSymbols $ addFromBlock existingSymbols bSymbols symbols = PB.putField $ getSymbolList bSymbols@@ -164,8 +173,9 @@ checks_v2 = PB.putField $ checkToPb s <$> bChecks scope = PB.putField $ scopeToPb s <$> Set.toList bScope pksTable = PB.putField $ publicKeyToPb <$> getPkList bSymbols- version = PB.putField $ if isV3 then Just 3- else Just 4+ version = PB.putField $ if | v5Plus -> Just 5+ | v4Plus -> Just 4+ | otherwise -> Just 3 in (bSymbols, PB.Block {..}) pbToFact :: Symbols -> PB.FactV2 -> Either String Fact@@ -415,17 +425,15 @@ BitwiseXor -> PB.BitwiseXor NotEqual -> PB.NotEqual -pbToThirdPartyBlockRequest :: PB.ThirdPartyBlockRequest -> Either String (Crypto.PublicKey, [Crypto.PublicKey])+pbToThirdPartyBlockRequest :: PB.ThirdPartyBlockRequest -> Either String Crypto.PublicKey pbToThirdPartyBlockRequest PB.ThirdPartyBlockRequest{previousPk, pkTable} = do- bisequence- ( pbToPublicKey $ PB.getField previousPk- , traverse pbToPublicKey $ PB.getField pkTable- )+ unless (null $ PB.getField pkTable) $ Left "Public key table provided in third-party block request"+ pbToPublicKey $ PB.getField previousPk -thirdPartyBlockRequestToPb :: (Crypto.PublicKey, [Crypto.PublicKey]) -> PB.ThirdPartyBlockRequest-thirdPartyBlockRequestToPb (previousPk, pkTable) = PB.ThirdPartyBlockRequest+thirdPartyBlockRequestToPb :: Crypto.PublicKey -> PB.ThirdPartyBlockRequest+thirdPartyBlockRequestToPb previousPk = PB.ThirdPartyBlockRequest { previousPk = PB.putField $ publicKeyToPb previousPk- , pkTable = PB.putField $ publicKeyToPb <$> pkTable+ , pkTable = PB.putField [] } pbToThirdPartyBlockContents :: PB.ThirdPartyBlockContents -> Either String (ByteString, Crypto.Signature, Crypto.PublicKey)
@@ -15,7 +15,6 @@ , addFromBlock , registerNewSymbols , registerNewPublicKeys- , forgetSymbols , reverseSymbols , getSymbolList , getPkList@@ -138,9 +137,6 @@ registerNewPublicKeys newPks s@Symbols{publicKeys} = let newPkMap = Map.fromList $ zip [getNextPublicKeyOffset s..] (newPks \\ elems publicKeys) in s { publicKeys = publicKeys <> newPkMap }--forgetSymbols :: Symbols -> Symbols-forgetSymbols s = s { symbols = commonSymbols } -- | Reverse a symbol table reverseSymbols :: Symbols -> ReverseSymbols
@@ -215,7 +215,7 @@ -- with a @trusting@ annotation. Be careful with @trusting previous@, as it queries -- facts from all blocks, even untrusted ones. queryRawBiscuitFactsWithLimits :: Biscuit openOrSealed check -> Limits -> Query- -> Set Bindings+ -> Either String (Set Bindings) queryRawBiscuitFactsWithLimits b@Biscuit{authority,blocks} = let ePks = externalKeys b getBlock ((_, block), _, _, _) = block@@ -235,7 +235,7 @@ -- 💁 If the facts you want to query are part of an allow query in the authorizer, -- you can directly get values by calling 'getBindings' on 'AuthorizationSuccess'. queryRawBiscuitFacts :: Biscuit openOrSealed check -> Query- -> Set Bindings+ -> Either String (Set Bindings) queryRawBiscuitFacts b = queryRawBiscuitFactsWithLimits b defaultLimits -- | Turn a 'Biscuit' statically known to be 'Open' into a more generic 'OpenOrSealed' 'Biscuit'@@ -306,26 +306,21 @@ -> Biscuit Open check -> IO (Biscuit Open check) addSignedBlock eSk block b@Biscuit{..} = do- let symbolsForCurrentBlock = forgetSymbols $ registerNewPublicKeys [toPublic eSk] symbols- (newSymbols, blockSerialized) = PB.encodeBlock <$> blockToPb True symbolsForCurrentBlock block+ let (_, blockSerialized) = PB.encodeBlock <$> blockToPb True newSymbolTable block lastBlock = NE.last (authority :| blocks) (_, _, lastPublicKey, _) = lastBlock Open p = proof (signedBlock, nextSk) <- signExternalBlock p eSk lastPublicKey blockSerialized pure $ b { blocks = blocks <> [toParsedSignedBlock block signedBlock]- , symbols = registerNewPublicKeys (getPkList newSymbols) symbols , proof = Open nextSk } mkThirdPartyBlock' :: SecretKey- -> [PublicKey] -> PublicKey -> Block -> (ByteString, Signature, PublicKey)-mkThirdPartyBlock' eSk pkTable lastPublicKey block =- let symbolsForCurrentBlock = registerNewPublicKeys [toPublic eSk] $- registerNewPublicKeys pkTable newSymbolTable- (_, payload) = PB.encodeBlock <$> blockToPb True symbolsForCurrentBlock block+mkThirdPartyBlock' eSk lastPublicKey block =+ let (_, payload) = PB.encodeBlock <$> blockToPb True newSymbolTable block (eSig, ePk) = sign3rdPartyBlock eSk lastPublicKey payload in (payload, eSig, ePk) @@ -336,17 +331,17 @@ -> Block -> Either String ByteString mkThirdPartyBlock eSk req block = do- (previousPk, pkTable) <- pbToThirdPartyBlockRequest =<< PB.decodeThirdPartyBlockRequest req- pure $ PB.encodeThirdPartyBlockContents . thirdPartyBlockContentsToPb $ mkThirdPartyBlock' eSk pkTable previousPk block+ previousPk<- pbToThirdPartyBlockRequest =<< PB.decodeThirdPartyBlockRequest req+ pure $ PB.encodeThirdPartyBlockContents . thirdPartyBlockContentsToPb $ mkThirdPartyBlock' eSk previousPk block -- | Generate a third-party block request. It can be used in -- conjunction with 'mkThirdPartyBlock' to generate a -- third-party block, which can be then appended to a token with -- 'applyThirdPartyBlock'. mkThirdPartyBlockReq :: Biscuit proof check -> ByteString-mkThirdPartyBlockReq Biscuit{authority,blocks,symbols} =+mkThirdPartyBlockReq Biscuit{authority,blocks} = let (_, _ , lastPk, _) = NE.last $ authority :| blocks- in PB.encodeThirdPartyBlockRequest $ thirdPartyBlockRequestToPb (lastPk, getPkTable symbols)+ in PB.encodeThirdPartyBlockRequest $ thirdPartyBlockRequestToPb lastPk -- | Given a base64-encoded third-party block, append it to a token. applyThirdPartyBlock :: Biscuit Open check -> ByteString -> Either String (IO (Biscuit Open check))@@ -621,7 +616,7 @@ -- 💁 If you are trying to extract facts from a biscuit in order to generate an -- authorizer, have a look at 'queryRawBiscuitFacts' instead. queryAuthorizerFacts :: AuthorizedBiscuit p -> Query- -> Set Bindings+ -> Either String (Set Bindings) queryAuthorizerFacts AuthorizedBiscuit{authorizedBiscuit, authorizationSuccess} = let ePks = externalKeys authorizedBiscuit in queryGeneratedFacts ePks authorizationSuccess
@@ -11,15 +11,25 @@ encodeHex, encodeHex', decodeHex,+ anyM,+ allM,+ setFilterM,+ foldMapM,+ mapMaybeM, ) where #if MIN_VERSION_base16(1,0,0)-import qualified Data.Base16.Types as Hex+import qualified Data.Base16.Types as Hex #endif-import Data.ByteString (ByteString)+import Data.Bool (bool)+import Data.ByteString (ByteString) import qualified Data.ByteString.Base16 as Hex-import Data.Text (Text)+import Data.Maybe (maybeToList)+import Data.Monoid (All (..), Any (..))+import Data.Set (Set)+import qualified Data.Set as Set+import Data.Text (Text) encodeHex :: ByteString -> Text #if MIN_VERSION_base16(1,0,0)@@ -51,3 +61,22 @@ -- but without the dependency footprint rightToMaybe :: Either b a -> Maybe a rightToMaybe = either (const Nothing) Just++anyM :: (Foldable t, Monad m) => (a -> m Bool) -> t a -> m Bool+anyM f = fmap getAny . foldMapM (fmap Any . f)++allM :: (Foldable t, Monad m) => (a -> m Bool) -> t a -> m Bool+allM f = fmap getAll . foldMapM (fmap All . f)++setFilterM :: (Ord a, Monad m) => (a -> m Bool) -> Set a -> m (Set a)+setFilterM p = foldMapM (\a -> bool mempty (Set.singleton a) <$> p a)++-- from Relude+foldMapM :: (Monoid b, Monad m, Foldable f) => (a -> m b) -> f a -> m b+foldMapM f xs = foldr step return xs mempty+ where+ step x r z = f x >>= \y -> r $! z `mappend` y+{-# INLINE foldMapM #-}++mapMaybeM :: (Monad m) => (a -> m (Maybe b)) -> [a] -> m [b]+mapMaybeM f = foldMapM (fmap maybeToList . f)
@@ -30,6 +30,7 @@ , rulesWithConstraints , ruleHeadWithNoVars , limits+ , overflow ] authGroup :: Set Fact -> FactGroup@@ -102,6 +103,7 @@ , ("!false", LBool True) , ("(true)", LBool True) , ("\"test\".length()", LInteger 4)+ , ("\"é\".length()", LInteger 2) , ("hex:ababab.length()", LInteger 3) , ("[].length()", LInteger 0) , ("[\"test\", \"test\"].length()", LInteger 1)@@ -296,3 +298,20 @@ ]) ]) ]++overflow :: TestTree+overflow =+ let subtraction = authRulesGroup $ Set.singleton+ [rule|test(true) <- -9223372036854775808 - 1 != 0|]+ multiplication = authRulesGroup $ Set.singleton+ [rule|test(true) <- 10000000000 * 10000000000 != 0|]+ addition = authRulesGroup $ Set.singleton+ [rule|test(true) <- 9223372036854775807 + 1 != 0|]+ in testGroup "Arithmetic overflow"+ [ testCase "subtraction" $+ runFactGeneration defaultLimits 1 subtraction mempty @?= Left (BadExpression "integer underflow")+ , testCase "multiplication" $+ runFactGeneration defaultLimits 1 multiplication mempty @?= Left (BadExpression "integer overflow")+ , testCase "addition" $+ runFactGeneration defaultLimits 1 addition mempty @?= Left (BadExpression "integer overflow")+ ]
@@ -1,14 +1,15 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE DerivingStrategies #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE NamedFieldPuns #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TypeApplications #-} module Spec.SampleReader where import Control.Arrow ((&&&))@@ -31,6 +32,7 @@ import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Data.Traversable (for) import GHC.Generics (Generic)+import GHC.Records (HasField (getField)) import Test.Tasty hiding (Timeout) import Test.Tasty.HUnit@@ -151,11 +153,35 @@ deriving stock (Eq, Show, Generic) deriving anyclass (FromJSON, ToJSON) +data FactSet+ = FactSet+ { origin :: [Maybe Integer]+ , facts :: [Text]+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (FromJSON, ToJSON)++data RuleSet+ = RuleSet+ { origin :: Maybe Integer+ , rules :: [Text]+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (FromJSON, ToJSON)++data CheckSet+ = CheckSet+ { origin :: Maybe Integer+ , checks :: [Text]+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (FromJSON, ToJSON)+ data WorldDesc = WorldDesc- { facts :: [Text]- , rules :: [Text]- , checks :: [Text]+ { facts :: [FactSet]+ , rules :: [RuleSet]+ , checks :: [CheckSet] , policies :: [Text] } deriving stock (Eq, Show, Generic)@@ -163,9 +189,9 @@ instance Semigroup WorldDesc where a <> b = WorldDesc- { facts = facts a <> facts b- , rules = rules a <> rules b- , checks = checks a <> checks b+ { facts = getField @"facts" a <> getField @"facts" b+ , rules = getField @"rules" a <> getField @"rules" b+ , checks = getField @"checks" a <> getField @"checks" b , policies = policies a <> policies b } @@ -210,7 +236,7 @@ compareParseErrors :: ParseError -> RustError -> Assertion compareParseErrors pe re = let mustMatch p = assertBool (show (re,pe)) $ isJust $ re ^? p- mustMatchEither ps = assertBool (show (re, pe)) $ any isJust $ (re ^?) <$> ps+ mustMatchEither ps = assertBool (show (re, pe)) $ any (isJust . (re ^?)) ps in case pe of InvalidHexEncoding -> assertFailure $ "InvalidHexEncoding can't appear here " <> show re@@ -248,6 +274,7 @@ TooManyFacts -> mustMatch $ key "RunLimit" . key "TooManyFacts" TooManyIterations -> mustMatch $ key "RunLimit" . key "TooManyIterations" InvalidRule -> mustMatch $ key "FailedLogic" . key "InvalidBlockRule"+ EvaluationError _ -> mustMatch $ key "Execution" ResultError (NoPoliciesMatched cs) -> mustMatch $ key "FailedLogic" . key "Unauthorized" ResultError (FailedChecks cs) -> mustMatch $ key "FailedLogic" . key "Unauthorized" ResultError (DenyRuleMatched cs q) -> mustMatch $ key "FailedLogic" . key "Unauthorized"@@ -307,12 +334,7 @@ mkValidation authorizer = do Right success <- authorizeBiscuit biscuit authorizer pure ValidationR- { world = Just $ WorldDesc- { facts = []- , rules = []- , checks = []- , policies = []- }+ { world = Just mempty , result = Ok 0 , authorizer_code = authorizer , revocation_ids = encodeHex <$> toList (getRevocationIds biscuit)
@@ -269,7 +269,7 @@ expected = Set.singleton $ Map.fromList [ ("user", LInteger 1234) ]- getUser <$> result @?= Right expected+ getUser <$> result @?= Right (Right expected) , testCase "Attenuation blocks can be accessed if asked nicely" $ do (p,s) <- (toPublic &&& id) <$> newSecret b <- mkBiscuit s [block|user(1234);|]@@ -280,7 +280,7 @@ [ Map.fromList [("user", LInteger 1234)] , Map.fromList [("user", LString "tampered value")] ]- getUser <$> result @?= Right expected+ getUser <$> result @?= Right (Right expected) , testCase "Signed blocks can be accessed if asked nicely" $ do (p,s) <- (toPublic &&& id) <$> newSecret (p1,s1) <- (toPublic &&& id) <$> newSecret@@ -293,7 +293,7 @@ [ Map.fromList [("user", LInteger 1234)] , Map.fromList [("user", LString "from signed")] ]- getUser <$> result @?= Right expected+ getUser <$> result @?= Right (Right expected) ] biscuitFactsAreQueried :: TestTree@@ -306,7 +306,7 @@ expected = Set.singleton $ Map.fromList [ ("user", LInteger 1234) ]- user @?= expected+ user @?= Right expected , testCase "Attenuation blocks can be accessed if asked nicely" $ do (p,s) <- (toPublic &&& id) <$> newSecret b <- mkBiscuit s [block|user(1234);|]@@ -316,7 +316,7 @@ [ Map.fromList [("user", LInteger 1234)] , Map.fromList [("user", LString "tampered value")] ]- user @?= expected+ user @?= Right expected , testCase "Signed blocks can be accessed if asked nicely" $ do (p,s) <- (toPublic &&& id) <$> newSecret (p1,s1) <- (toPublic &&& id) <$> newSecret@@ -328,5 +328,5 @@ [ Map.fromList [("user", LInteger 1234)] , Map.fromList [("user", LString "from signed")] ]- user @?= expected+ user @?= Right expected ]
@@ -1,1657 +1,2187 @@ {- "root_private_key": "12aca40167fbdd1a11037e9fd440e3d510d9d9dea70a6646aa4aaf84d718d75a",- "root_public_key": "acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189",- "testcases": [- {- "title": "basic token",- "filename": "test001_basic.bc",- "token": [- {- "symbols": [- "file1",- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"- },- {- "symbols": [- "0"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "resource(\"file1\")",- "right(\"file1\", \"read\")",- "right(\"file1\", \"write\")",- "right(\"file2\", \"read\")"- ],- "rules": [],- "checks": [- "check if resource($0), operation(\"read\"), right($0, \"read\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 1,- "check_id": 0,- "rule": "check if resource($0), operation(\"read\"), right($0, \"read\")"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file1\");\n\nallow if true;\n",- "revocation_ids": [- "3ee1c0f42ba69ec63b1f39a6b3c57d25a4ccec452233ca6d40530ecfe83af4918fa78d9346f8b7c498545b54663960342b9ed298b2c8bbe2085b80c237b56f09",- "e16ccf0820b02092adb531e36c2e82884c6c6c647b1c85184007f2ace601648afb71faa261b11f9ab352093c96187870f868588b664579c8018864b306bd5007"- ]- }- }- },- {- "title": "different root key",- "filename": "test002_different_root_key.bc",- "token": [- {- "symbols": [- "file1"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\n"- },- {- "symbols": [- "0"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"- }- ],- "validations": {- "": {- "world": null,- "result": {- "Err": {- "Format": {- "Signature": {- "InvalidSignature": "signature error: Verification equation was not satisfied"- }- }- }- },- "authorizer_code": "",- "revocation_ids": []- }- }- },- {- "title": "invalid signature format",- "filename": "test003_invalid_signature_format.bc",- "token": [- {- "symbols": [- "file1",- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"- },- {- "symbols": [- "0"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"- }- ],- "validations": {- "": {- "world": null,- "result": {- "Err": {- "Format": {- "InvalidSignatureSize": 16- }- }- },- "authorizer_code": "",- "revocation_ids": []- }- }- },- {- "title": "random block",- "filename": "test004_random_block.bc",- "token": [- {- "symbols": [- "file1",- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"- },- {- "symbols": [- "0"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"- }- ],- "validations": {- "": {- "world": null,- "result": {- "Err": {- "Format": {- "Signature": {- "InvalidSignature": "signature error: Verification equation was not satisfied"- }- }- }- },- "authorizer_code": "",- "revocation_ids": []- }- }- },- {- "title": "invalid signature",- "filename": "test005_invalid_signature.bc",- "token": [- {- "symbols": [- "file1",- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"- },- {- "symbols": [- "0"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"- }- ],- "validations": {- "": {- "world": null,- "result": {- "Err": {- "Format": {- "Signature": {- "InvalidSignature": "signature error: Verification equation was not satisfied"- }- }- }- },- "authorizer_code": "",- "revocation_ids": []- }- }- },- {- "title": "reordered blocks",- "filename": "test006_reordered_blocks.bc",- "token": [- {- "symbols": [- "file1",- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"- },- {- "symbols": [- "0"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"- },- {- "symbols": [],- "public_keys": [],- "external_key": null,- "code": "check if resource(\"file1\");\n"- }- ],- "validations": {- "": {- "world": null,- "result": {- "Err": {- "Format": {- "Signature": {- "InvalidSignature": "signature error: Verification equation was not satisfied"- }- }- }- },- "authorizer_code": "",- "revocation_ids": []- }- }- },- {- "title": "scoped rules",- "filename": "test007_scoped_rules.bc",- "token": [- {- "symbols": [- "user_id",- "alice",- "file1"- ],- "public_keys": [],- "external_key": null,- "code": "user_id(\"alice\");\nowner(\"alice\", \"file1\");\n"- },- {- "symbols": [- "0",- "1"- ],- "public_keys": [],- "external_key": null,- "code": "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0);\ncheck if resource($0), operation(\"read\"), right($0, \"read\");\n"- },- {- "symbols": [- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "owner(\"alice\", \"file2\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "operation(\"read\")",- "owner(\"alice\", \"file1\")",- "owner(\"alice\", \"file2\")",- "resource(\"file2\")",- "user_id(\"alice\")"- ],- "rules": [- "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0)"- ],- "checks": [- "check if resource($0), operation(\"read\"), right($0, \"read\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 1,- "check_id": 0,- "rule": "check if resource($0), operation(\"read\"), right($0, \"read\")"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n",- "revocation_ids": [- "02d287b0e5b22780192f8351538583c17f7d0200e064b32a1fcf07899e64ffb10e4de324f5c5ebc72c89a63e424317226cf555eb42dae81b2fd4639cf7591108",- "22e75ea200cf7b2b62b389298fe0dec973b7f9c7e54e76c3c41811d72ea82c68227bc9079b7d05986de17ef9301cccdc08f5023455386987d1e6ee4391b19f06",- "140a3631fecae550b51e50b9b822b947fb485c80070b34482fa116cdea560140164a1d0a959b40fed8a727e2f62c0b57635760c488c8bf0eda80ee591558c409"- ]- }- }- },- {- "title": "scoped checks",- "filename": "test008_scoped_checks.bc",- "token": [- {- "symbols": [- "file1"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\n"- },- {- "symbols": [- "0"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"- },- {- "symbols": [- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file2\", \"read\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "operation(\"read\")",- "resource(\"file2\")",- "right(\"file1\", \"read\")",- "right(\"file2\", \"read\")"- ],- "rules": [],- "checks": [- "check if resource($0), operation(\"read\"), right($0, \"read\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 1,- "check_id": 0,- "rule": "check if resource($0), operation(\"read\"), right($0, \"read\")"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n",- "revocation_ids": [- "567682495bf002eb84c46491e40fad8c55943d918c65e2c110b1b88511bf393072c0305a243e3d632ca5f1e9b0ace3e3582de84838c3a258480657087c267f02",- "71f0010b1034dbc62c53f67a23947b92ccba46495088567ac7ad5c4d7d65476964bee42053a6a35088110c5918f9c9606057689271fef89d84253cf98e6d4407",- "6d00d5f2a5d25dbfaa19152a81b44328b368e8fb8300b25e36754cfe8b2ce1eb2d1452ce9b1502e6f377a23aa87098fb05b5b073541624a8815ba0610f793005"- ]- }- }- },- {- "title": "expired token",- "filename": "test009_expired_token.bc",- "token": [- {- "symbols": [],- "public_keys": [],- "external_key": null,- "code": ""- },- {- "symbols": [- "file1",- "expiration"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource(\"file1\");\ncheck if time($time), $time <= 2018-12-20T00:00:00Z;\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "operation(\"read\")",- "resource(\"file1\")",- "time(2020-12-21T09:23:12Z)"- ],- "rules": [],- "checks": [- "check if resource(\"file1\")",- "check if time($time), $time <= 2018-12-20T00:00:00Z"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 1,- "check_id": 1,- "rule": "check if time($time), $time <= 2018-12-20T00:00:00Z"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file1\");\noperation(\"read\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n",- "revocation_ids": [- "b2474f3e0a5788cdeff811f2599497a04d1ad71ca48dbafb90f20a950d565dda0b86bd6c9072a727c19b6b20a1ae10d8cb88155186550b77016ffd1dca9a6203",- "0d12152670cbefe2fa504af9a92b513f1a48ae460ae5e66aaac4ed9f7dc3cc1c4c510693312b351465062169a2169fc520ce4e17e548d21982c81a74c66a3c0c"- ]- }- }- },- {- "title": "authorizer scope",- "filename": "test010_authorizer_scope.bc",- "token": [- {- "symbols": [- "file1"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\n"- },- {- "symbols": [- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file2\", \"read\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "operation(\"read\")",- "resource(\"file2\")",- "right(\"file1\", \"read\")",- "right(\"file2\", \"read\")"- ],- "rules": [],- "checks": [- "check if right($0, $1), resource($0), operation($1)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Authorizer": {- "check_id": 0,- "rule": "check if right($0, $1), resource($0), operation($1)"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\ncheck if right($0, $1), resource($0), operation($1);\n\nallow if true;\n",- "revocation_ids": [- "b9ecf192ecb1bbb10e45320c1c86661f0c6b6bd28e89fdd8fa838fe0ab3f754229f7fbbf92ad978d36f744c345c69bc156a2a91a2979a3c235a9d936d401b404",- "839728735701e589c2612e655afa2b53f573480e6a0477ae68ed71587987d1af398a31296bdec0b6eccee9348f4b4c23ca1031e809991626c579fef80b1d380d"- ]- }- }- },- {- "title": "authorizer authority checks",- "filename": "test011_authorizer_authority_caveats.bc",- "token": [- {- "symbols": [- "file1"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "operation(\"read\")",- "resource(\"file2\")",- "right(\"file1\", \"read\")"- ],- "rules": [],- "checks": [- "check if right($0, $1), resource($0), operation($1)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Authorizer": {- "check_id": 0,- "rule": "check if right($0, $1), resource($0), operation($1)"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\ncheck if right($0, $1), resource($0), operation($1);\n\nallow if true;\n",- "revocation_ids": [- "593d273d141bf23a3e89b55fffe1b3f96f683a022bb763e78f4e49f31a7cf47668c3fd5e0f580727ac9113ede302d34264597f6f1e6c6dd4167836d57aedf504"- ]- }- }- },- {- "title": "authority checks",- "filename": "test012_authority_caveats.bc",- "token": [- {- "symbols": [- "file1"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource(\"file1\");\n"- }- ],- "validations": {- "file1": {- "world": {- "facts": [- "operation(\"read\")",- "resource(\"file1\")"- ],- "rules": [],- "checks": [- "check if resource(\"file1\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "resource(\"file1\");\noperation(\"read\");\n\nallow if true;\n",- "revocation_ids": [- "0a1d14a145debbb0a2f4ce0631d3a0a48a2e0eddabefda7fabb0414879ec6be24b9ae7295c434609ada3f8cc47b8845bbd5a0d4fba3d96748ff1b824496e0405"- ]- },- "file2": {- "world": {- "facts": [- "operation(\"read\")",- "resource(\"file2\")"- ],- "rules": [],- "checks": [- "check if resource(\"file1\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 0,- "check_id": 0,- "rule": "check if resource(\"file1\")"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n",- "revocation_ids": [- "0a1d14a145debbb0a2f4ce0631d3a0a48a2e0eddabefda7fabb0414879ec6be24b9ae7295c434609ada3f8cc47b8845bbd5a0d4fba3d96748ff1b824496e0405"- ]- }- }- },- {- "title": "block rules",- "filename": "test013_block_rules.bc",- "token": [- {- "symbols": [- "file1",- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\n"- },- {- "symbols": [- "valid_date",- "0",- "1"- ],- "public_keys": [],- "external_key": null,- "code": "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z;\nvalid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1);\ncheck if valid_date($0), resource($0);\n"- }- ],- "validations": {- "file1": {- "world": {- "facts": [- "resource(\"file1\")",- "right(\"file1\", \"read\")",- "right(\"file2\", \"read\")",- "time(2020-12-21T09:23:12Z)",- "valid_date(\"file1\")"- ],- "rules": [- "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z",- "valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1)"- ],- "checks": [- "check if valid_date($0), resource($0)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "resource(\"file1\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n",- "revocation_ids": [- "d251352efd4e4c72e8a1609fce002f558f1a0bb5e36cd3d8b3a6c6599e3960880f21bea6fe1857f4ecbc2c399dd77829b154e75f1323e9dec413aad70f97650d",- "9de4f51e6019540598a957515dad52f5403e5c6cd8d2adbca1bff42a4fbc0eb8c6adab499da2fe894a8a9c9c581276bfb0fdc3d35ab2ff9f920a2c4690739903"- ]- },- "file2": {- "world": {- "facts": [- "resource(\"file2\")",- "right(\"file1\", \"read\")",- "right(\"file2\", \"read\")",- "time(2020-12-21T09:23:12Z)"- ],- "rules": [- "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z",- "valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1)"- ],- "checks": [- "check if valid_date($0), resource($0)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 1,- "check_id": 0,- "rule": "check if valid_date($0), resource($0)"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file2\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n",- "revocation_ids": [- "d251352efd4e4c72e8a1609fce002f558f1a0bb5e36cd3d8b3a6c6599e3960880f21bea6fe1857f4ecbc2c399dd77829b154e75f1323e9dec413aad70f97650d",- "9de4f51e6019540598a957515dad52f5403e5c6cd8d2adbca1bff42a4fbc0eb8c6adab499da2fe894a8a9c9c581276bfb0fdc3d35ab2ff9f920a2c4690739903"- ]- }- }- },- {- "title": "regex_constraint",- "filename": "test014_regex_constraint.bc",- "token": [- {- "symbols": [- "0",- "file[0-9]+.txt"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), $0.matches(\"file[0-9]+.txt\");\n"- }- ],- "validations": {- "file1": {- "world": {- "facts": [- "resource(\"file1\")"- ],- "rules": [],- "checks": [- "check if resource($0), $0.matches(\"file[0-9]+.txt\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 0,- "check_id": 0,- "rule": "check if resource($0), $0.matches(\"file[0-9]+.txt\")"- }- }- ]- }- }- }- },- "authorizer_code": "resource(\"file1\");\n\nallow if true;\n",- "revocation_ids": [- "1c158e1e12c8670d3f4411597276fe1caab17b7728adb7f7e9c44eeec3e3d85676e6ebe2d28c287e285a45912386cfa53e1752997630bd7a4ca6c2cd9f143500"- ]- },- "file123": {- "world": {- "facts": [- "resource(\"file123.txt\")"- ],- "rules": [],- "checks": [- "check if resource($0), $0.matches(\"file[0-9]+.txt\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "resource(\"file123.txt\");\n\nallow if true;\n",- "revocation_ids": [- "1c158e1e12c8670d3f4411597276fe1caab17b7728adb7f7e9c44eeec3e3d85676e6ebe2d28c287e285a45912386cfa53e1752997630bd7a4ca6c2cd9f143500"- ]- }- }- },- {- "title": "multi queries checks",- "filename": "test015_multi_queries_caveats.bc",- "token": [- {- "symbols": [- "must_be_present",- "hello"- ],- "public_keys": [],- "external_key": null,- "code": "must_be_present(\"hello\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "must_be_present(\"hello\")"- ],- "rules": [],- "checks": [- "check if must_be_present($0) or must_be_present($0)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "check if must_be_present($0) or must_be_present($0);\n\nallow if true;\n",- "revocation_ids": [- "d3eee8a74eacec9c51d4d1eb29b479727dfaafa9df7d4c651d07c493c56f3a5f037a51139ebd036f50d1159d12bccec3e377bbd32db90a39dd52c4776757ad0b"- ]- }- }- },- {- "title": "check head name should be independent from fact names",- "filename": "test016_caveat_head_name.bc",- "token": [- {- "symbols": [- "hello"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource(\"hello\");\n"- },- {- "symbols": [- "test"- ],- "public_keys": [],- "external_key": null,- "code": "query(\"test\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "query(\"test\")"- ],- "rules": [],- "checks": [- "check if resource(\"hello\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 0,- "check_id": 0,- "rule": "check if resource(\"hello\")"- }- }- ]- }- }- }- },- "authorizer_code": "allow if true;\n",- "revocation_ids": [- "e79679e019f1d7d3a9f9a309673aceadc7b2b2d67c0df3e7a1dccec25218e9b5935b9c8f8249243446406e3cdd86c1b35601a21cf1b119df48ca5e897cc6cd0d",- "2042ea2dca41ba3eb31196f49b211e615dcba46067be126e6035b8549bb57cdfeb24d07f2b44241bc0f70cc8ddc31e30772116d785b82bc91be8440dfdab500f"- ]- }- }- },- {- "title": "test expression syntax and all available operations",- "filename": "test017_expressions.bc",- "token": [- {- "symbols": [- "hello world",- "hello",- "world",- "aaabde",- "a*c?.e",- "abd",- "aaa",- "b",- "de",- "abcD12",- "abcD12x",- "abc",- "def"- ],- "public_keys": [],- "external_key": null,- "code": "check if true;\ncheck if !false;\ncheck if !false && true;\ncheck if false or true;\ncheck if (true || false) && true;\ncheck if 1 < 2;\ncheck if 2 > 1;\ncheck if 1 <= 2;\ncheck if 1 <= 1;\ncheck if 2 >= 1;\ncheck if 2 >= 2;\ncheck if 3 == 3;\ncheck if 1 != 3;\ncheck if 1 + 2 * 3 - 4 / 2 == 5;\ncheck if 1 | 2 ^ 3 == 0;\ncheck if \"hello world\".starts_with(\"hello\") && \"hello world\".ends_with(\"world\");\ncheck if \"aaabde\".matches(\"a*c?.e\");\ncheck if \"aaabde\".contains(\"abd\");\ncheck if \"aaabde\" == \"aaa\" + \"b\" + \"de\";\ncheck if \"abcD12\" == \"abcD12\";\ncheck if \"abcD12x\" != \"abcD12\";\ncheck if 2019-12-04T09:46:41Z < 2020-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z > 2019-12-04T09:46:41Z;\ncheck if 2019-12-04T09:46:41Z <= 2020-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z >= 2020-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z >= 2019-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z >= 2020-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z == 2020-12-04T09:46:41Z;\ncheck if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z;\ncheck if hex:12ab == hex:12ab;\ncheck if hex:12abcd != hex:12ab;\ncheck if [1, 2].contains(2);\ncheck if [2019-12-04T09:46:41Z, 2020-12-04T09:46:41Z].contains(2020-12-04T09:46:41Z);\ncheck if [false, true].contains(true);\ncheck if [\"abc\", \"def\"].contains(\"abc\");\ncheck if [hex:12ab, hex:34de].contains(hex:34de);\ncheck if [1, 2] == [1, 2];\ncheck if [1, 4] != [1, 2];\n"- }- ],- "validations": {- "": {- "world": {- "facts": [],- "rules": [],- "checks": [- "check if !false",- "check if !false && true",- "check if \"aaabde\" == \"aaa\" + \"b\" + \"de\"",- "check if \"aaabde\".contains(\"abd\")",- "check if \"aaabde\".matches(\"a*c?.e\")",- "check if \"abcD12\" == \"abcD12\"",- "check if \"abcD12x\" != \"abcD12\"",- "check if \"hello world\".starts_with(\"hello\") && \"hello world\".ends_with(\"world\")",- "check if (true || false) && true",- "check if 1 != 3",- "check if 1 + 2 * 3 - 4 / 2 == 5",- "check if 1 < 2",- "check if 1 <= 1",- "check if 1 <= 2",- "check if 1 | 2 ^ 3 == 0",- "check if 2 > 1",- "check if 2 >= 1",- "check if 2 >= 2",- "check if 2019-12-04T09:46:41Z < 2020-12-04T09:46:41Z",- "check if 2019-12-04T09:46:41Z <= 2020-12-04T09:46:41Z",- "check if 2020-12-04T09:46:41Z == 2020-12-04T09:46:41Z",- "check if 2020-12-04T09:46:41Z > 2019-12-04T09:46:41Z",- "check if 2020-12-04T09:46:41Z >= 2019-12-04T09:46:41Z",- "check if 2020-12-04T09:46:41Z >= 2020-12-04T09:46:41Z",- "check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z",- "check if 3 == 3",- "check if [\"abc\", \"def\"].contains(\"abc\")",- "check if [1, 2] == [1, 2]",- "check if [1, 2].contains(2)",- "check if [1, 4] != [1, 2]",- "check if [2019-12-04T09:46:41Z, 2020-12-04T09:46:41Z].contains(2020-12-04T09:46:41Z)",- "check if [false, true].contains(true)",- "check if [hex:12ab, hex:34de].contains(hex:34de)",- "check if false or true",- "check if hex:12ab == hex:12ab",- "check if hex:12abcd != hex:12ab",- "check if true"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "allow if true;\n",- "revocation_ids": [- "3e51db5f0453929a596485b59e89bf628a301a33d476132c48a1c0a208805809f15bdf99593733c1b5f30e8c1f473ee2f78042f81fd0557081bafb5370e65d0c"- ]- }- }- },- {- "title": "invalid block rule with unbound_variables",- "filename": "test018_unbound_variables_in_rule.bc",- "token": [- {- "symbols": [],- "public_keys": [],- "external_key": null,- "code": "check if operation(\"read\");\n"- },- {- "symbols": [- "unbound",- "any1",- "any2"- ],- "public_keys": [],- "external_key": null,- "code": "operation($unbound, \"read\") <- operation($any1, $any2);\n"- }- ],- "validations": {- "": {- "world": null,- "result": {- "Err": {- "FailedLogic": {- "InvalidBlockRule": [- 0,- "operation($unbound, \"read\") <- operation($any1, $any2)"- ]- }- }- },- "authorizer_code": "",- "revocation_ids": [- "c536d07f08f6f73da69a2f49310045168e059b8c07e3ddf25afd524df358a0397744b31a139eced043cb5f7a29dacbe3a510ce449fc792e53623186767cefc0c",- "8588c74c3701e8d4be770769b4e1054dbb5ea5f231a89d205000802b8718859ea1d596af207a41b1b0f7d05959180c227ea8954e903f13ade3ce3384d1e6a70a"- ]- }- }- },- {- "title": "invalid block rule generating an #authority or #ambient symbol with a variable",- "filename": "test019_generating_ambient_from_variables.bc",- "token": [- {- "symbols": [],- "public_keys": [],- "external_key": null,- "code": "check if operation(\"read\");\n"- },- {- "symbols": [- "any"- ],- "public_keys": [],- "external_key": null,- "code": "operation(\"read\") <- operation($any);\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "operation(\"read\")",- "operation(\"write\")"- ],- "rules": [- "operation(\"read\") <- operation($any)"- ],- "checks": [- "check if operation(\"read\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 0,- "check_id": 0,- "rule": "check if operation(\"read\")"- }- }- ]- }- }- }- },- "authorizer_code": "operation(\"write\");\n\nallow if true;\n",- "revocation_ids": [- "4819e7360fdb840e54e94afcbc110e9b0652894dba2b8bf3b8b8f2254aaf00272bba7eb603c153c7e50cca0e5bb8e20449d70a1b24e7192e902c64f94848a703",- "4a4c59354354d2f91b3a2d1e7afa2c5eeaf8be9f7b163c6b9091817551cc8661f0f3e0523b525ef9a5e597c0dd1f32e09e97ace531c150dba335bb3e1d329d00"- ]- }- }- },- {- "title": "sealed token",- "filename": "test020_sealed.bc",- "token": [- {- "symbols": [- "file1",- "file2"- ],- "public_keys": [],- "external_key": null,- "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"- },- {- "symbols": [- "0"- ],- "public_keys": [],- "external_key": null,- "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "operation(\"read\")",- "resource(\"file1\")",- "right(\"file1\", \"read\")",- "right(\"file1\", \"write\")",- "right(\"file2\", \"read\")"- ],- "rules": [],- "checks": [- "check if resource($0), operation(\"read\"), right($0, \"read\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "resource(\"file1\");\noperation(\"read\");\n\nallow if true;\n",- "revocation_ids": [- "b279f8c6fee5ea3c3fcb5109d8c6b35ba3fecea64d83a4dc387102b9401633a1558ac6ac50ddd7fd9e9877f936f9f4064abd467faeca2bef3114b9695eb0580e",- "e1f0aca12704c1a3b9bb6292504ca6070462d9e043756dd209e625084e7d4053078bd4e55b6eebebbeb771d26d7794aa95f6b39ff949431548b32585a7379f0c"- ]- }- }- },- {- "title": "parsing",- "filename": "test021_parsing.bc",- "token": [- {- "symbols": [- "ns::fact_123",- "hello é\t😁"- ],- "public_keys": [],- "external_key": null,- "code": "ns::fact_123(\"hello é\t😁\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "ns::fact_123(\"hello é\t😁\")"- ],- "rules": [],- "checks": [- "check if ns::fact_123(\"hello é\t😁\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "check if ns::fact_123(\"hello é\t😁\");\n\nallow if true;\n",- "revocation_ids": [- "4797a528328c8b5fb7939cc8956d8cda2513f552466eee501e26ea13a6cf6b4a381fd74ae547a9b50b627825142287d899b9d7bd1b5cfb18664a1be78320ea06"- ]- }- }- },- {- "title": "default_symbols",- "filename": "test022_default_symbols.bc",- "token": [- {- "symbols": [],- "public_keys": [],- "external_key": null,- "code": "read(0);\nwrite(1);\nresource(2);\noperation(3);\nright(4);\ntime(5);\nrole(6);\nowner(7);\ntenant(8);\nnamespace(9);\nuser(10);\nteam(11);\nservice(12);\nadmin(13);\nemail(14);\ngroup(15);\nmember(16);\nip_address(17);\nclient(18);\nclient_ip(19);\ndomain(20);\npath(21);\nversion(22);\ncluster(23);\nnode(24);\nhostname(25);\nnonce(26);\nquery(27);\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "admin(13)",- "client(18)",- "client_ip(19)",- "cluster(23)",- "domain(20)",- "email(14)",- "group(15)",- "hostname(25)",- "ip_address(17)",- "member(16)",- "namespace(9)",- "node(24)",- "nonce(26)",- "operation(3)",- "owner(7)",- "path(21)",- "query(27)",- "read(0)",- "resource(2)",- "right(4)",- "role(6)",- "service(12)",- "team(11)",- "tenant(8)",- "time(5)",- "user(10)",- "version(22)",- "write(1)"- ],- "rules": [],- "checks": [- "check if read(0), write(1), resource(2), operation(3), right(4), time(5), role(6), owner(7), tenant(8), namespace(9), user(10), team(11), service(12), admin(13), email(14), group(15), member(16), ip_address(17), client(18), client_ip(19), domain(20), path(21), version(22), cluster(23), node(24), hostname(25), nonce(26), query(27)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "check if read(0), write(1), resource(2), operation(3), right(4), time(5), role(6), owner(7), tenant(8), namespace(9), user(10), team(11), service(12), admin(13), email(14), group(15), member(16), ip_address(17), client(18), client_ip(19), domain(20), path(21), version(22), cluster(23), node(24), hostname(25), nonce(26), query(27);\n\nallow if true;\n",- "revocation_ids": [- "38094260b324eff92db2ef79e715d88c18503c0dafa400bff900399f2ab0840cedc5ac25bdd3e97860b3f9e78ca5e0df67a113eb87be50265d49278efb13210f"- ]- }- }- },- {- "title": "execution scope",- "filename": "test023_execution_scope.bc",- "token": [- {- "symbols": [- "authority_fact"- ],- "public_keys": [],- "external_key": null,- "code": "authority_fact(1);\n"- },- {- "symbols": [- "block1_fact"- ],- "public_keys": [],- "external_key": null,- "code": "block1_fact(1);\n"- },- {- "symbols": [- "var"- ],- "public_keys": [],- "external_key": null,- "code": "check if authority_fact($var);\ncheck if block1_fact($var);\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "authority_fact(1)",- "block1_fact(1)"- ],- "rules": [],- "checks": [- "check if authority_fact($var)",- "check if block1_fact($var)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 2,- "check_id": 1,- "rule": "check if block1_fact($var)"- }- }- ]- }- }- }- },- "authorizer_code": "allow if true;\n",- "revocation_ids": [- "6a3606836bc63b858f96ce5000c9bead8eda139ab54679a2a8d7a9984c2e5d864b93280acc1b728bed0be42b5b1c3be10f48a13a4dbd05fd5763de5be3855108",- "5f1468fc60999f22c4f87fa088a83961188b4e654686c5b04bdc977b9ff4666d51a3d8be5594f4cef08054d100f31d1637b50bb394de7cccafc643c9b650390b",- "3eda05ddb65ee90d715cefc046837c01de944d8c4a7ff67e3d9a9d8470b5e214a20a8b9866bfe5e0d385e530b75ec8fcfde46b7dd6d4d6647d1e955c9d2fb90d"- ]- }- }- },- {- "title": "third party",- "filename": "test024_third_party.bc",- "token": [- {- "symbols": [],- "public_keys": [- "ed25519/a424157b8c00c25214ea39894bf395650d88426147679a9dd43a64d65ae5bc25"- ],- "external_key": null,- "code": "right(\"read\");\ncheck if group(\"admin\") trusting ed25519/a424157b8c00c25214ea39894bf395650d88426147679a9dd43a64d65ae5bc25;\n"- },- {- "symbols": [],- "public_keys": [],- "external_key": "ed25519/a424157b8c00c25214ea39894bf395650d88426147679a9dd43a64d65ae5bc25",- "code": "group(\"admin\");\ncheck if right(\"read\");\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "group(\"admin\")",- "right(\"read\")"- ],- "rules": [],- "checks": [- "check if group(\"admin\") trusting ed25519/a424157b8c00c25214ea39894bf395650d88426147679a9dd43a64d65ae5bc25",- "check if right(\"read\")"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "allow if true;\n",- "revocation_ids": [- "4f61f2f2f9cefdcad03a82803638e459bef70d6fd72dbdf2bdcab78fbd23f33146e4ff9700e23acb547b820b871fa9b9fd3bb6d7a1a755afce47e9907c65600c",- "683b23943b73f53f57f473571ba266f79f1fca0633be249bc135054371a11ffb101c57150ab2f1b9a6a160b45d09567a314b7dbc84224edf6188afd5b86d9305"- ]- }- }- },- {- "title": "block rules",- "filename": "test025_check_all.bc",- "token": [- {- "symbols": [- "allowed_operations",- "A",- "B",- "op",- "allowed"- ],- "public_keys": [],- "external_key": null,- "code": "allowed_operations([\"A\", \"B\"]);\ncheck all operation($op), allowed_operations($allowed), $allowed.contains($op);\n"- }- ],- "validations": {- "A, B": {- "world": {- "facts": [- "allowed_operations([ \"A\", \"B\"])",- "operation(\"A\")",- "operation(\"B\")"- ],- "rules": [],- "checks": [- "check all operation($op), allowed_operations($allowed), $allowed.contains($op)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Ok": 0- },- "authorizer_code": "operation(\"A\");\noperation(\"B\");\n\nallow if true;\n",- "revocation_ids": [- "b4ee591001e4068a7ee8efb7a0586c3ca3a785558f34d1fa8dbfa21b41ace70de0b670ac49222c7413066d0d83e6d9edee94fb0fda4b27ea11e837304dfb4b0b"- ]- },- "A, invalid": {- "world": {- "facts": [- "allowed_operations([ \"A\", \"B\"])",- "operation(\"A\")",- "operation(\"invalid\")"- ],- "rules": [],- "checks": [- "check all operation($op), allowed_operations($allowed), $allowed.contains($op)"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 0,- "check_id": 0,- "rule": "check all operation($op), allowed_operations($allowed), $allowed.contains($op)"- }- }- ]- }- }- }- },- "authorizer_code": "operation(\"A\");\noperation(\"invalid\");\n\nallow if true;\n",- "revocation_ids": [- "b4ee591001e4068a7ee8efb7a0586c3ca3a785558f34d1fa8dbfa21b41ace70de0b670ac49222c7413066d0d83e6d9edee94fb0fda4b27ea11e837304dfb4b0b"- ]- }- }- },- {- "title": "public keys interning",- "filename": "test026_public_keys_interning.bc",- "token": [- {- "symbols": [],- "public_keys": [- "ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59"- ],- "external_key": null,- "code": "query(0);\ncheck if true trusting previous, ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59;\n"- },- {- "symbols": [],- "public_keys": [- "ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee"- ],- "external_key": "ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59",- "code": "query(1);\nquery(1, 2) <- query(1), query(2) trusting ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee;\ncheck if query(2), query(3) trusting ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee;\ncheck if query(1) trusting ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59;\n"- },- {- "symbols": [],- "public_keys": [],- "external_key": "ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee",- "code": "query(2);\ncheck if query(2), query(3) trusting ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee;\ncheck if query(1) trusting ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59;\n"- },- {- "symbols": [],- "public_keys": [],- "external_key": "ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee",- "code": "query(3);\ncheck if query(2), query(3) trusting ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee;\ncheck if query(1) trusting ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59;\n"- },- {- "symbols": [],- "public_keys": [- "ed25519/2e0118e63beb7731dab5119280ddb117234d0cdc41b7dd5dc4241bcbbb585d14"- ],- "external_key": null,- "code": "query(4);\ncheck if query(2) trusting ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee;\ncheck if query(4) trusting ed25519/2e0118e63beb7731dab5119280ddb117234d0cdc41b7dd5dc4241bcbbb585d14;\n"- }- ],- "validations": {- "": {- "world": {- "facts": [- "query(0)",- "query(1)",- "query(1, 2)",- "query(2)",- "query(3)",- "query(4)"- ],- "rules": [- "query(1, 2) <- query(1), query(2) trusting ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee"- ],- "checks": [- "check if query(1) trusting ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59",- "check if query(1, 2) trusting ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59, ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee",- "check if query(2) trusting ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee",- "check if query(2), query(3) trusting ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee",- "check if query(4) trusting ed25519/2e0118e63beb7731dab5119280ddb117234d0cdc41b7dd5dc4241bcbbb585d14",- "check if true trusting previous, ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59"- ],- "policies": [- "allow if true",- "deny if query(0) trusting ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59",- "deny if query(1, 2)",- "deny if query(3)"- ]- },- "result": {- "Ok": 3- },- "authorizer_code": "check if query(1, 2) trusting ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59, ed25519/ecfb8ed11fd9e6be133ca4dd8d229d39c7dcb2d659704c39e82fd7acf0d12dee;\n\ndeny if query(3);\ndeny if query(1, 2);\ndeny if query(0) trusting ed25519/3c8aeced6363b8a862552fb2b0b4b8b0f8244e8cef3c11c3e55fd553f3a90f59;\nallow if true;\n",- "revocation_ids": [- "bc144fef824b7ba4b266eac53e9b4f3f2d3cd443c6963833f2f8d4073bef9553f92034c2350fdd50966a9f0c09db35b142d61e0476b0133429885c787052060b",- "aba1631f8d0bea1c81447e73269f560973d03287c2b44325d1b42d10a496156dc8e78648b946bc7db7a3111d787a10c1a9da8d53fc066b1f207de7415a2e9b0b",- "539cff0f5c311dcac843a9e6c8bb445aff0d6510bfa9b17d5350747be92dc365217e89e1d733f3ead1ecc05f287f312c41831338708e788503b55517af3ad000",- "5b10f7a7b4487f4421cf7f7f6d00b24a7a71939037b65b2e44241909564082a3e1e70cf7d866eb96f0a5119b9ea395adb772faaa33252fa62a579eb15a108a0b",- "3905351588cdfc4433b510cc1ed9c11ca5c1a7bd7d9cef338bcd3f6d374c711f34edd83dd0d53c25b63bf05b49fc78addceb47905d5495580c2fd36c11bc1e0a"- ]- }- }- },- {- "title": "integer wraparound",- "filename": "test027_integer_wraparound.bc",- "token": [- {- "symbols": [],- "public_keys": [],- "external_key": null,- "code": "check if true || 10000000000 * 10000000000 != 0;\ncheck if true || 9223372036854775807 + 1 != 0;\ncheck if true || -9223372036854775808 - 1 != 0;\n"- }- ],- "validations": {- "": {- "world": {- "facts": [],- "rules": [],- "checks": [- "check if true || -9223372036854775808 - 1 != 0",- "check if true || 10000000000 * 10000000000 != 0",- "check if true || 9223372036854775807 + 1 != 0"- ],- "policies": [- "allow if true"- ]- },- "result": {- "Err": {- "FailedLogic": {- "Unauthorized": {- "policy": {- "Allow": 0- },- "checks": [- {- "Block": {- "block_id": 0,- "check_id": 0,- "rule": "check if true || 10000000000 * 10000000000 != 0"- }- },- {- "Block": {- "block_id": 0,- "check_id": 1,- "rule": "check if true || 9223372036854775807 + 1 != 0"- }- },- {- "Block": {- "block_id": 0,- "check_id": 2,- "rule": "check if true || -9223372036854775808 - 1 != 0"- }- }- ]- }- }- }- },- "authorizer_code": "allow if true;\n",- "revocation_ids": [- "70d8941198ab5daa445a11357994d93278876ee95b6500f4c4a265ad668a0111440942b762e02513e471d40265d586ea76209921068524f588dc46eb4260db07"+ "root_private_key": "99e87b0e9158531eeeb503ff15266e2b23c2a2507b138c9d1b1f2ab458df2d61",+ "root_public_key": "1055c750b1a1505937af1537c626ba3263995c33a64758aaafb1275b0312e284",+ "testcases": [+ {+ "title": "basic token",+ "filename": "test001_basic.bc",+ "token": [+ {+ "symbols": [+ "file1",+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"+ },+ {+ "symbols": [+ "0"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "resource(\"file1\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "right(\"file1\", \"read\")",+ "right(\"file1\", \"write\")",+ "right(\"file2\", \"read\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 1,+ "checks": [+ "check if resource($0), operation(\"read\"), right($0, \"read\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 1,+ "check_id": 0,+ "rule": "check if resource($0), operation(\"read\"), right($0, \"read\")"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file1\");\n\nallow if true;\n",+ "revocation_ids": [+ "7595a112a1eb5b81a6e398852e6118b7f5b8cbbff452778e655100e5fb4faa8d3a2af52fe2c4f9524879605675fae26adbc4783e0cafc43522fa82385f396c03",+ "45f4c14f9d9e8fa044d68be7a2ec8cddb835f575c7b913ec59bd636c70acae9a90db9064ba0b3084290ed0c422bbb7170092a884f5e0202b31e9235bbcc1650d"+ ]+ }+ }+ },+ {+ "title": "different root key",+ "filename": "test002_different_root_key.bc",+ "token": [+ {+ "symbols": [+ "file1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\n"+ },+ {+ "symbols": [+ "0"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": null,+ "result": {+ "Err": {+ "Format": {+ "Signature": {+ "InvalidSignature": "signature error: Verification equation was not satisfied"+ }+ }+ }+ },+ "authorizer_code": "",+ "revocation_ids": []+ }+ }+ },+ {+ "title": "invalid signature format",+ "filename": "test003_invalid_signature_format.bc",+ "token": [+ {+ "symbols": [+ "file1",+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"+ },+ {+ "symbols": [+ "0"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": null,+ "result": {+ "Err": {+ "Format": {+ "InvalidSignatureSize": 16+ }+ }+ },+ "authorizer_code": "",+ "revocation_ids": []+ }+ }+ },+ {+ "title": "random block",+ "filename": "test004_random_block.bc",+ "token": [+ {+ "symbols": [+ "file1",+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"+ },+ {+ "symbols": [+ "0"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": null,+ "result": {+ "Err": {+ "Format": {+ "Signature": {+ "InvalidSignature": "signature error: Verification equation was not satisfied"+ }+ }+ }+ },+ "authorizer_code": "",+ "revocation_ids": []+ }+ }+ },+ {+ "title": "invalid signature",+ "filename": "test005_invalid_signature.bc",+ "token": [+ {+ "symbols": [+ "file1",+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"+ },+ {+ "symbols": [+ "0"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": null,+ "result": {+ "Err": {+ "Format": {+ "Signature": {+ "InvalidSignature": "signature error: Verification equation was not satisfied"+ }+ }+ }+ },+ "authorizer_code": "",+ "revocation_ids": []+ }+ }+ },+ {+ "title": "reordered blocks",+ "filename": "test006_reordered_blocks.bc",+ "token": [+ {+ "symbols": [+ "file1",+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"+ },+ {+ "symbols": [+ "0"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"+ },+ {+ "symbols": [],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource(\"file1\");\n"+ }+ ],+ "validations": {+ "": {+ "world": null,+ "result": {+ "Err": {+ "Format": {+ "Signature": {+ "InvalidSignature": "signature error: Verification equation was not satisfied"+ }+ }+ }+ },+ "authorizer_code": "",+ "revocation_ids": []+ }+ }+ },+ {+ "title": "scoped rules",+ "filename": "test007_scoped_rules.bc",+ "token": [+ {+ "symbols": [+ "user_id",+ "alice",+ "file1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "user_id(\"alice\");\nowner(\"alice\", \"file1\");\n"+ },+ {+ "symbols": [+ "0",+ "1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0);\ncheck if resource($0), operation(\"read\"), right($0, \"read\");\n"+ },+ {+ "symbols": [+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "owner(\"alice\", \"file2\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"read\")",+ "resource(\"file2\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "owner(\"alice\", \"file1\")",+ "user_id(\"alice\")"+ ]+ },+ {+ "origin": [+ 2+ ],+ "facts": [+ "owner(\"alice\", \"file2\")"+ ]+ }+ ],+ "rules": [+ {+ "origin": 1,+ "rules": [+ "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0)"+ ]+ }+ ],+ "checks": [+ {+ "origin": 1,+ "checks": [+ "check if resource($0), operation(\"read\"), right($0, \"read\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 1,+ "check_id": 0,+ "rule": "check if resource($0), operation(\"read\"), right($0, \"read\")"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n",+ "revocation_ids": [+ "4d86c9af808dc2e0583f47282e6f5df3e09dc264d5231ec360b4519e15ddaeec60b25a9bbcb22e8d192f4d36a0da3f9243711e30535b00ee55c53cb1395f230a",+ "63208c668c66f3ba6927140ba37533593b25e03459447805d4b2a8b75adeef45794c3d7249afe506ed77ccee276160bb4052a4009302bd34871a440f070b4509",+ "d8da982888eae8c038e4894a8c06fc57d8e5f06ad2e972b9cf4bde49ad60804558a0d1938192596c702d8e4f7f12ec19201d7c33d0cd77774a0d879a33880d02"+ ]+ }+ }+ },+ {+ "title": "scoped checks",+ "filename": "test008_scoped_checks.bc",+ "token": [+ {+ "symbols": [+ "file1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\n"+ },+ {+ "symbols": [+ "0"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"+ },+ {+ "symbols": [+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file2\", \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"read\")",+ "resource(\"file2\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "right(\"file1\", \"read\")"+ ]+ },+ {+ "origin": [+ 2+ ],+ "facts": [+ "right(\"file2\", \"read\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 1,+ "checks": [+ "check if resource($0), operation(\"read\"), right($0, \"read\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 1,+ "check_id": 0,+ "rule": "check if resource($0), operation(\"read\"), right($0, \"read\")"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n",+ "revocation_ids": [+ "a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00",+ "77df45442be86a416aa02fd9d98d6d4703c634a9e3b1d293b41f5dc97849afbe7faeec8c22a210574888acc008fb64fe691ec9e8d2655586f970d9a6b6577000",+ "b31398aefe97d3db41ebc445760f216fb3aa7bf7439adcfc3a07489bfcc163970af3f4e20f5460aa24cf841101a5ab114d21acc0ee8d442bae7793b121284900"+ ]+ }+ }+ },+ {+ "title": "expired token",+ "filename": "test009_expired_token.bc",+ "token": [+ {+ "symbols": [],+ "public_keys": [],+ "external_key": null,+ "code": ""+ },+ {+ "symbols": [+ "file1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource(\"file1\");\ncheck if time($time), $time <= 2018-12-20T00:00:00Z;\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"read\")",+ "resource(\"file1\")",+ "time(2020-12-21T09:23:12Z)"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 1,+ "checks": [+ "check if resource(\"file1\")",+ "check if time($time), $time <= 2018-12-20T00:00:00Z"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 1,+ "check_id": 1,+ "rule": "check if time($time), $time <= 2018-12-20T00:00:00Z"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file1\");\noperation(\"read\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n",+ "revocation_ids": [+ "c248907bb6e5f433bbb5edf6367b399ebefca0d321d0b2ea9fc67f66dc1064ce926adb0c05d90c3e8a2833328b3578f79c4e1bca43583d9bcfb2ba6c37303d00",+ "a4edf7aaea8658bb9ae19b3ffe2adcc77cc9f16c249aeb0a85a584b5362f89f27f7c67ac0af16d7170673d6d1fb1563d1934b25ec5a461f6c01fa49805cd5e07"+ ]+ }+ }+ },+ {+ "title": "authorizer scope",+ "filename": "test010_authorizer_scope.bc",+ "token": [+ {+ "symbols": [+ "file1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\n"+ },+ {+ "symbols": [+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file2\", \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"read\")",+ "resource(\"file2\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "right(\"file1\", \"read\")"+ ]+ },+ {+ "origin": [+ 1+ ],+ "facts": [+ "right(\"file2\", \"read\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 18446744073709551615,+ "checks": [+ "check if right($0, $1), resource($0), operation($1)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Authorizer": {+ "check_id": 0,+ "rule": "check if right($0, $1), resource($0), operation($1)"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\ncheck if right($0, $1), resource($0), operation($1);\n\nallow if true;\n",+ "revocation_ids": [+ "a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00",+ "966eceb2aa937c41b25368808bab6e0698c02a4038de669d007c9c3d43602638a640083558d1576ac80cf3eb2ac6a7585527e0f6c1a65402f0935cf7f4df8005"+ ]+ }+ }+ },+ {+ "title": "authorizer authority checks",+ "filename": "test011_authorizer_authority_caveats.bc",+ "token": [+ {+ "symbols": [+ "file1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"read\")",+ "resource(\"file2\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "right(\"file1\", \"read\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 18446744073709551615,+ "checks": [+ "check if right($0, $1), resource($0), operation($1)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Authorizer": {+ "check_id": 0,+ "rule": "check if right($0, $1), resource($0), operation($1)"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\ncheck if right($0, $1), resource($0), operation($1);\n\nallow if true;\n",+ "revocation_ids": [+ "a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00"+ ]+ }+ }+ },+ {+ "title": "authority checks",+ "filename": "test012_authority_caveats.bc",+ "token": [+ {+ "symbols": [+ "file1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource(\"file1\");\n"+ }+ ],+ "validations": {+ "file1": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"read\")",+ "resource(\"file1\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if resource(\"file1\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "resource(\"file1\");\noperation(\"read\");\n\nallow if true;\n",+ "revocation_ids": [+ "6a8f90dad67ae2ac188460463914ae7326fda431c80785755f4edcc15f1a53911f7366e606ad80cbbeba94672e42713e88632a932128f1d796ce9ba7d7a0b80a"+ ]+ },+ "file2": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"read\")",+ "resource(\"file2\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if resource(\"file1\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 0,+ "check_id": 0,+ "rule": "check if resource(\"file1\")"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n",+ "revocation_ids": [+ "6a8f90dad67ae2ac188460463914ae7326fda431c80785755f4edcc15f1a53911f7366e606ad80cbbeba94672e42713e88632a932128f1d796ce9ba7d7a0b80a"+ ]+ }+ }+ },+ {+ "title": "block rules",+ "filename": "test013_block_rules.bc",+ "token": [+ {+ "symbols": [+ "file1",+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\n"+ },+ {+ "symbols": [+ "valid_date",+ "0",+ "1"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z;\nvalid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1);\ncheck if valid_date($0), resource($0);\n"+ }+ ],+ "validations": {+ "file1": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "resource(\"file1\")",+ "time(2020-12-21T09:23:12Z)"+ ]+ },+ {+ "origin": [+ null,+ 1+ ],+ "facts": [+ "valid_date(\"file1\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "right(\"file1\", \"read\")",+ "right(\"file2\", \"read\")"+ ]+ }+ ],+ "rules": [+ {+ "origin": 1,+ "rules": [+ "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z",+ "valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1)"+ ]+ }+ ],+ "checks": [+ {+ "origin": 1,+ "checks": [+ "check if valid_date($0), resource($0)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "resource(\"file1\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n",+ "revocation_ids": [+ "c46d071ff3f33434223c8305fdad529f62bf78bb5d9cbfc2a345d4bca6bf314014840e18ba353f86fdb9073d58b12b8c872ac1f8e593c2e9064b90f6c2ede006",+ "a0c4c163a0b3ca406df4ece3d1371356190df04208eccef72f77e875ed0531b5d37e243d6f388b1967776a5dfd16ef228f19c5bdd6d2820f145c5ed3c3dcdc00"+ ]+ },+ "file2": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "resource(\"file2\")",+ "time(2020-12-21T09:23:12Z)"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "right(\"file1\", \"read\")",+ "right(\"file2\", \"read\")"+ ]+ }+ ],+ "rules": [+ {+ "origin": 1,+ "rules": [+ "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z",+ "valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1)"+ ]+ }+ ],+ "checks": [+ {+ "origin": 1,+ "checks": [+ "check if valid_date($0), resource($0)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 1,+ "check_id": 0,+ "rule": "check if valid_date($0), resource($0)"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file2\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n",+ "revocation_ids": [+ "c46d071ff3f33434223c8305fdad529f62bf78bb5d9cbfc2a345d4bca6bf314014840e18ba353f86fdb9073d58b12b8c872ac1f8e593c2e9064b90f6c2ede006",+ "a0c4c163a0b3ca406df4ece3d1371356190df04208eccef72f77e875ed0531b5d37e243d6f388b1967776a5dfd16ef228f19c5bdd6d2820f145c5ed3c3dcdc00"+ ]+ }+ }+ },+ {+ "title": "regex_constraint",+ "filename": "test014_regex_constraint.bc",+ "token": [+ {+ "symbols": [+ "0",+ "file[0-9]+.txt"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), $0.matches(\"file[0-9]+.txt\");\n"+ }+ ],+ "validations": {+ "file1": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "resource(\"file1\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if resource($0), $0.matches(\"file[0-9]+.txt\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 0,+ "check_id": 0,+ "rule": "check if resource($0), $0.matches(\"file[0-9]+.txt\")"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "resource(\"file1\");\n\nallow if true;\n",+ "revocation_ids": [+ "da42718ad2631c12d3a44b7710dcc76c6c7809c6bc3a2d7eb0378c4154eae10e0884a8d54a2cd25ca3dfe01091d816ebbb9d246227baf7a359a787cb2344ad07"+ ]+ },+ "file123": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "resource(\"file123.txt\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if resource($0), $0.matches(\"file[0-9]+.txt\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "resource(\"file123.txt\");\n\nallow if true;\n",+ "revocation_ids": [+ "da42718ad2631c12d3a44b7710dcc76c6c7809c6bc3a2d7eb0378c4154eae10e0884a8d54a2cd25ca3dfe01091d816ebbb9d246227baf7a359a787cb2344ad07"+ ]+ }+ }+ },+ {+ "title": "multi queries checks",+ "filename": "test015_multi_queries_caveats.bc",+ "token": [+ {+ "symbols": [+ "must_be_present",+ "hello"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "must_be_present(\"hello\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ 0+ ],+ "facts": [+ "must_be_present(\"hello\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 18446744073709551615,+ "checks": [+ "check if must_be_present($0) or must_be_present($0)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "check if must_be_present($0) or must_be_present($0);\n\nallow if true;\n",+ "revocation_ids": [+ "b0d466d31e015fa85a075fa875f7e1c9017edd503fee9f62a5f033e1fcfa811074b6e39dfe5af2f452043db97a3f98650592a370f5685b62c5d6abf9dd10b603"+ ]+ }+ }+ },+ {+ "title": "check head name should be independent from fact names",+ "filename": "test016_caveat_head_name.bc",+ "token": [+ {+ "symbols": [+ "hello"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource(\"hello\");\n"+ },+ {+ "symbols": [+ "test"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "query(\"test\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ 1+ ],+ "facts": [+ "query(\"test\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if resource(\"hello\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 0,+ "check_id": 0,+ "rule": "check if resource(\"hello\")"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "allow if true;\n",+ "revocation_ids": [+ "ce6f804f4390e693a8853d9a4a10bd4f3c94b86b7c6d671993a6e19346bc4d20bbb52cc945e5d0d02e4e75fa5da2caa99764050190353564a0a0b4b276809402",+ "916d566cc724e0773046fc5266e9d0d804311435b8d6955b332f823ab296be9a78dfea190447732ac9f6217234cf5726becf88f65169c6de56a766af55451b0f"+ ]+ }+ }+ },+ {+ "title": "test expression syntax and all available operations",+ "filename": "test017_expressions.bc",+ "token": [+ {+ "symbols": [+ "hello world",+ "hello",+ "world",+ "aaabde",+ "a*c?.e",+ "abd",+ "aaa",+ "b",+ "de",+ "abcD12",+ "é",+ "abc",+ "def"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if true;\ncheck if !false;\ncheck if !false && true;\ncheck if false || true;\ncheck if (true || false) && true;\ncheck if true == true;\ncheck if false == false;\ncheck if 1 < 2;\ncheck if 2 > 1;\ncheck if 1 <= 2;\ncheck if 1 <= 1;\ncheck if 2 >= 1;\ncheck if 2 >= 2;\ncheck if 3 == 3;\ncheck if 1 + 2 * 3 - 4 / 2 == 5;\ncheck if \"hello world\".starts_with(\"hello\") && \"hello world\".ends_with(\"world\");\ncheck if \"aaabde\".matches(\"a*c?.e\");\ncheck if \"aaabde\".contains(\"abd\");\ncheck if \"aaabde\" == \"aaa\" + \"b\" + \"de\";\ncheck if \"abcD12\" == \"abcD12\";\ncheck if \"abcD12\".length() == 6;\ncheck if \"é\".length() == 2;\ncheck if 2019-12-04T09:46:41Z < 2020-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z > 2019-12-04T09:46:41Z;\ncheck if 2019-12-04T09:46:41Z <= 2020-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z >= 2020-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z >= 2019-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z >= 2020-12-04T09:46:41Z;\ncheck if 2020-12-04T09:46:41Z == 2020-12-04T09:46:41Z;\ncheck if hex:12ab == hex:12ab;\ncheck if [1, 2].contains(2);\ncheck if [2019-12-04T09:46:41Z, 2020-12-04T09:46:41Z].contains(2020-12-04T09:46:41Z);\ncheck if [false, true].contains(true);\ncheck if [\"abc\", \"def\"].contains(\"abc\");\ncheck if [hex:12ab, hex:34de].contains(hex:34de);\ncheck if [1, 2].contains([2]);\ncheck if [1, 2] == [1, 2];\ncheck if [1, 2].intersection([2, 3]) == [2];\ncheck if [1, 2].union([2, 3]) == [1, 2, 3];\ncheck if [1, 2, 3].intersection([1, 2]).contains(1);\ncheck if [1, 2, 3].intersection([1, 2]).length() == 2;\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if !false",+ "check if !false && true",+ "check if \"aaabde\" == \"aaa\" + \"b\" + \"de\"",+ "check if \"aaabde\".contains(\"abd\")",+ "check if \"aaabde\".matches(\"a*c?.e\")",+ "check if \"abcD12\" == \"abcD12\"",+ "check if \"abcD12\".length() == 6",+ "check if \"hello world\".starts_with(\"hello\") && \"hello world\".ends_with(\"world\")",+ "check if \"é\".length() == 2",+ "check if (true || false) && true",+ "check if 1 + 2 * 3 - 4 / 2 == 5",+ "check if 1 < 2",+ "check if 1 <= 1",+ "check if 1 <= 2",+ "check if 2 > 1",+ "check if 2 >= 1",+ "check if 2 >= 2",+ "check if 2019-12-04T09:46:41Z < 2020-12-04T09:46:41Z",+ "check if 2019-12-04T09:46:41Z <= 2020-12-04T09:46:41Z",+ "check if 2020-12-04T09:46:41Z == 2020-12-04T09:46:41Z",+ "check if 2020-12-04T09:46:41Z > 2019-12-04T09:46:41Z",+ "check if 2020-12-04T09:46:41Z >= 2019-12-04T09:46:41Z",+ "check if 2020-12-04T09:46:41Z >= 2020-12-04T09:46:41Z",+ "check if 2020-12-04T09:46:41Z >= 2020-12-04T09:46:41Z",+ "check if 3 == 3",+ "check if [\"abc\", \"def\"].contains(\"abc\")",+ "check if [1, 2, 3].intersection([1, 2]).contains(1)",+ "check if [1, 2, 3].intersection([1, 2]).length() == 2",+ "check if [1, 2] == [1, 2]",+ "check if [1, 2].contains(2)",+ "check if [1, 2].contains([2])",+ "check if [1, 2].intersection([2, 3]) == [2]",+ "check if [1, 2].union([2, 3]) == [1, 2, 3]",+ "check if [2019-12-04T09:46:41Z, 2020-12-04T09:46:41Z].contains(2020-12-04T09:46:41Z)",+ "check if [false, true].contains(true)",+ "check if [hex:12ab, hex:34de].contains(hex:34de)",+ "check if false == false",+ "check if false || true",+ "check if hex:12ab == hex:12ab",+ "check if true",+ "check if true == true"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "allow if true;\n",+ "revocation_ids": [+ "3d5b23b502b3dd920bfb68b9039164d1563bb8927210166fa5c17f41b76b31bb957bc2ed3318452958f658baa2d398fe4cf25c58a27e6c8bc42c9702c8aa1b0c"+ ]+ }+ }+ },+ {+ "title": "invalid block rule with unbound_variables",+ "filename": "test018_unbound_variables_in_rule.bc",+ "token": [+ {+ "symbols": [],+ "public_keys": [],+ "external_key": null,+ "code": "check if operation(\"read\");\n"+ },+ {+ "symbols": [+ "unbound",+ "any1",+ "any2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "operation($unbound, \"read\") <- operation($any1, $any2);\n"+ }+ ],+ "validations": {+ "": {+ "world": null,+ "result": {+ "Err": {+ "FailedLogic": {+ "InvalidBlockRule": [+ 0,+ "operation($unbound, \"read\") <- operation($any1, $any2)"+ ]+ }+ }+ },+ "authorizer_code": "",+ "revocation_ids": [+ "a44210c6a01e55eadefc7d8540c2e6eff80ab6eeedde4751de734f9d780435780680d3f42d826b7e0f0dcf4a5ba303fd4c116984bb30978813d46ed867924307",+ "b0a33e3f4cd0994c0766c196c4d11c15e5a0f9bfba79a3a2b35ddd04ddb890282a7c63336ada5c680b9f9c940c1fa7127d2699754cbc77c21e1a2d85c5ef700c"+ ]+ }+ }+ },+ {+ "title": "invalid block rule generating an #authority or #ambient symbol with a variable",+ "filename": "test019_generating_ambient_from_variables.bc",+ "token": [+ {+ "symbols": [],+ "public_keys": [],+ "external_key": null,+ "code": "check if operation(\"read\");\n"+ },+ {+ "symbols": [+ "any"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "operation(\"read\") <- operation($any);\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"write\")"+ ]+ },+ {+ "origin": [+ null,+ 1+ ],+ "facts": [+ "operation(\"read\")"+ ]+ }+ ],+ "rules": [+ {+ "origin": 1,+ "rules": [+ "operation(\"read\") <- operation($any)"+ ]+ }+ ],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if operation(\"read\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 0,+ "check_id": 0,+ "rule": "check if operation(\"read\")"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "operation(\"write\");\n\nallow if true;\n",+ "revocation_ids": [+ "a44210c6a01e55eadefc7d8540c2e6eff80ab6eeedde4751de734f9d780435780680d3f42d826b7e0f0dcf4a5ba303fd4c116984bb30978813d46ed867924307",+ "d3f8822a9b9bc0ee3933283c493ca9e711be5dd8339b5fe2eba1de3805aad4e84d3e2fb4affb4a743f1289915c167582b9425343635e45b70573ea1ee7a1ea03"+ ]+ }+ }+ },+ {+ "title": "sealed token",+ "filename": "test020_sealed.bc",+ "token": [+ {+ "symbols": [+ "file1",+ "file2"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n"+ },+ {+ "symbols": [+ "0"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"read\")",+ "resource(\"file1\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "right(\"file1\", \"read\")",+ "right(\"file1\", \"write\")",+ "right(\"file2\", \"read\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 1,+ "checks": [+ "check if resource($0), operation(\"read\"), right($0, \"read\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "resource(\"file1\");\noperation(\"read\");\n\nallow if true;\n",+ "revocation_ids": [+ "7595a112a1eb5b81a6e398852e6118b7f5b8cbbff452778e655100e5fb4faa8d3a2af52fe2c4f9524879605675fae26adbc4783e0cafc43522fa82385f396c03",+ "45f4c14f9d9e8fa044d68be7a2ec8cddb835f575c7b913ec59bd636c70acae9a90db9064ba0b3084290ed0c422bbb7170092a884f5e0202b31e9235bbcc1650d"+ ]+ }+ }+ },+ {+ "title": "parsing",+ "filename": "test021_parsing.bc",+ "token": [+ {+ "symbols": [+ "ns::fact_123",+ "hello é\t😁"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "ns::fact_123(\"hello é\t😁\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ 0+ ],+ "facts": [+ "ns::fact_123(\"hello é\t😁\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 18446744073709551615,+ "checks": [+ "check if ns::fact_123(\"hello é\t😁\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "check if ns::fact_123(\"hello é\t😁\");\n\nallow if true;\n",+ "revocation_ids": [+ "d4b2f417b6e906434fdf5058afcabfcb98d3628f814f1c9dd7e64250d9beec4465aff51bd0cb2e85d0e67dc9f613c2a42af6158c678bc6f8b4684cd3a2d0d302"+ ]+ }+ }+ },+ {+ "title": "default_symbols",+ "filename": "test022_default_symbols.bc",+ "token": [+ {+ "symbols": [],+ "public_keys": [],+ "external_key": null,+ "code": "read(0);\nwrite(1);\nresource(2);\noperation(3);\nright(4);\ntime(5);\nrole(6);\nowner(7);\ntenant(8);\nnamespace(9);\nuser(10);\nteam(11);\nservice(12);\nadmin(13);\nemail(14);\ngroup(15);\nmember(16);\nip_address(17);\nclient(18);\nclient_ip(19);\ndomain(20);\npath(21);\nversion(22);\ncluster(23);\nnode(24);\nhostname(25);\nnonce(26);\nquery(27);\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ 0+ ],+ "facts": [+ "admin(13)",+ "client(18)",+ "client_ip(19)",+ "cluster(23)",+ "domain(20)",+ "email(14)",+ "group(15)",+ "hostname(25)",+ "ip_address(17)",+ "member(16)",+ "namespace(9)",+ "node(24)",+ "nonce(26)",+ "operation(3)",+ "owner(7)",+ "path(21)",+ "query(27)",+ "read(0)",+ "resource(2)",+ "right(4)",+ "role(6)",+ "service(12)",+ "team(11)",+ "tenant(8)",+ "time(5)",+ "user(10)",+ "version(22)",+ "write(1)"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 18446744073709551615,+ "checks": [+ "check if read(0), write(1), resource(2), operation(3), right(4), time(5), role(6), owner(7), tenant(8), namespace(9), user(10), team(11), service(12), admin(13), email(14), group(15), member(16), ip_address(17), client(18), client_ip(19), domain(20), path(21), version(22), cluster(23), node(24), hostname(25), nonce(26), query(27)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "check if read(0), write(1), resource(2), operation(3), right(4), time(5), role(6), owner(7), tenant(8), namespace(9), user(10), team(11), service(12), admin(13), email(14), group(15), member(16), ip_address(17), client(18), client_ip(19), domain(20), path(21), version(22), cluster(23), node(24), hostname(25), nonce(26), query(27);\n\nallow if true;\n",+ "revocation_ids": [+ "75ce48d496fd28f99905901783a1ba46d7ff8d69f9d364d1546fd73006026eae51849ad1190a4ae521a0a1269f9c6951e226afba8fcd24fa50f679162439ae09"+ ]+ }+ }+ },+ {+ "title": "execution scope",+ "filename": "test023_execution_scope.bc",+ "token": [+ {+ "symbols": [+ "authority_fact"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "authority_fact(1);\n"+ },+ {+ "symbols": [+ "block1_fact"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "block1_fact(1);\n"+ },+ {+ "symbols": [+ "var"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if authority_fact($var);\ncheck if block1_fact($var);\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ 0+ ],+ "facts": [+ "authority_fact(1)"+ ]+ },+ {+ "origin": [+ 1+ ],+ "facts": [+ "block1_fact(1)"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 2,+ "checks": [+ "check if authority_fact($var)",+ "check if block1_fact($var)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 2,+ "check_id": 1,+ "rule": "check if block1_fact($var)"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "allow if true;\n",+ "revocation_ids": [+ "f9b49866caef5ece7be14ec5a9b36d98ca81d06b306eb0b4c57cd7436af176f40ee972f40903f87ec4460ab8b1adfcbfa9b19b20a6955a1e8dae7d88b2076005",+ "889054b9119e4440e54da1b63266a98d0f6646cde195fef206efd8b133cfb2ee7be49b32a9a5925ece452e64f9e6f6d80dab422e916c599675dd68cdea053802",+ "0a85ffbf27e08aa23665ba0d96a985b274d747556c9f016fd7f590c641ed0e4133291521aa442b320ee9ce80f5ad701b914a0c87b3dfa0cc92629dce94201806"+ ]+ }+ }+ },+ {+ "title": "third party",+ "filename": "test024_third_party.bc",+ "token": [+ {+ "symbols": [],+ "public_keys": [+ "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"+ ],+ "external_key": null,+ "code": "right(\"read\");\ncheck if group(\"admin\") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n"+ },+ {+ "symbols": [],+ "public_keys": [],+ "external_key": "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189",+ "code": "group(\"admin\");\ncheck if right(\"read\");\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ 0+ ],+ "facts": [+ "right(\"read\")"+ ]+ },+ {+ "origin": [+ 1+ ],+ "facts": [+ "group(\"admin\")"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if group(\"admin\") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"+ ]+ },+ {+ "origin": 1,+ "checks": [+ "check if right(\"read\")"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "allow if true;\n",+ "revocation_ids": [+ "470e4bf7aa2a01ab39c98150bd06aa15b4aa5d86509044a8809a8634cd8cf2b42269a51a774b65d10bac9369d013070b00187925196a8e680108473f11cf8f03",+ "342167bc54bc642b6718a276875e55b6d39e9b21e4ce13b926a3d398b6c057fc436385bf4c817a16f9ecdf0b0d950e8b8258a20aeb3fd8896c5e9c1f0a53da03"+ ]+ }+ }+ },+ {+ "title": "block rules",+ "filename": "test025_check_all.bc",+ "token": [+ {+ "symbols": [+ "allowed_operations",+ "A",+ "B",+ "op",+ "allowed"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "allowed_operations([\"A\", \"B\"]);\ncheck all operation($op), allowed_operations($allowed), $allowed.contains($op);\n"+ }+ ],+ "validations": {+ "A, B": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"A\")",+ "operation(\"B\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "allowed_operations([\"A\", \"B\"])"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check all operation($op), allowed_operations($allowed), $allowed.contains($op)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "operation(\"A\");\noperation(\"B\");\n\nallow if true;\n",+ "revocation_ids": [+ "c456817012e1d523c6d145b6d6a3475d9f7dd4383c535454ff3f745ecf4234984ce09b9dec0551f3d783abe850f826ce43b12f1fd91999a4753a56ecf4c56d0d"+ ]+ },+ "A, invalid": {+ "world": {+ "facts": [+ {+ "origin": [+ null+ ],+ "facts": [+ "operation(\"A\")",+ "operation(\"invalid\")"+ ]+ },+ {+ "origin": [+ 0+ ],+ "facts": [+ "allowed_operations([\"A\", \"B\"])"+ ]+ }+ ],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check all operation($op), allowed_operations($allowed), $allowed.contains($op)"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "FailedLogic": {+ "Unauthorized": {+ "policy": {+ "Allow": 0+ },+ "checks": [+ {+ "Block": {+ "block_id": 0,+ "check_id": 0,+ "rule": "check all operation($op), allowed_operations($allowed), $allowed.contains($op)"+ }+ }+ ]+ }+ }+ }+ },+ "authorizer_code": "operation(\"A\");\noperation(\"invalid\");\n\nallow if true;\n",+ "revocation_ids": [+ "c456817012e1d523c6d145b6d6a3475d9f7dd4383c535454ff3f745ecf4234984ce09b9dec0551f3d783abe850f826ce43b12f1fd91999a4753a56ecf4c56d0d"+ ]+ }+ }+ },+ {+ "title": "public keys interning",+ "filename": "test026_public_keys_interning.bc",+ "token": [+ {+ "symbols": [],+ "public_keys": [+ "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"+ ],+ "external_key": null,+ "code": "query(0);\ncheck if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n"+ },+ {+ "symbols": [],+ "public_keys": [+ "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463",+ "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"+ ],+ "external_key": "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189",+ "code": "query(1);\nquery(1, 2) <- query(1), query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\ncheck if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\ncheck if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n"+ },+ {+ "symbols": [],+ "public_keys": [+ "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463",+ "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"+ ],+ "external_key": "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463",+ "code": "query(2);\ncheck if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\ncheck if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n"+ },+ {+ "symbols": [],+ "public_keys": [+ "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463",+ "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"+ ],+ "external_key": "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463",+ "code": "query(3);\ncheck if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\ncheck if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n"+ },+ {+ "symbols": [],+ "public_keys": [+ "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463",+ "ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136"+ ],+ "external_key": null,+ "code": "query(4);\ncheck if query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\ncheck if query(4) trusting ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136;\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [+ {+ "origin": [+ 0+ ],+ "facts": [+ "query(0)"+ ]+ },+ {+ "origin": [+ 1+ ],+ "facts": [+ "query(1)"+ ]+ },+ {+ "origin": [+ 1,+ 2+ ],+ "facts": [+ "query(1, 2)"+ ]+ },+ {+ "origin": [+ 2+ ],+ "facts": [+ "query(2)"+ ]+ },+ {+ "origin": [+ 3+ ],+ "facts": [+ "query(3)"+ ]+ },+ {+ "origin": [+ 4+ ],+ "facts": [+ "query(4)"+ ]+ }+ ],+ "rules": [+ {+ "origin": 1,+ "rules": [+ "query(1, 2) <- query(1), query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463"+ ]+ }+ ],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"+ ]+ },+ {+ "origin": 1,+ "checks": [+ "check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189",+ "check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463"+ ]+ },+ {+ "origin": 2,+ "checks": [+ "check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189",+ "check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463"+ ]+ },+ {+ "origin": 3,+ "checks": [+ "check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189",+ "check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463"+ ]+ },+ {+ "origin": 4,+ "checks": [+ "check if query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463",+ "check if query(4) trusting ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136"+ ]+ },+ {+ "origin": 18446744073709551615,+ "checks": [+ "check if query(1, 2) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189, ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463"+ ]+ }+ ],+ "policies": [+ "deny if query(3)",+ "deny if query(1, 2)",+ "deny if query(0) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189",+ "allow if true"+ ]+ },+ "result": {+ "Ok": 3+ },+ "authorizer_code": "check if query(1, 2) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189, ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\n\ndeny if query(3);\ndeny if query(1, 2);\ndeny if query(0) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\nallow if true;\n",+ "revocation_ids": [+ "3771cefe71beb21ead35a59c8116ee82627a5717c0295f35980662abccb159fe1b37848cb1818e548656bd4fd882d0094a2daab631c76b2b72e3a093914bfe04",+ "6528db2c9a561ada9086268549a600a8a52ff434ea8183812623eec0e9b6c5d3c41ab7868808623021d92294d583afdf92f4354bcdaa1bc50453e1b89afd630d",+ "5d5679fe69bfe74b7919323515e9ecba9d01422b16be9341b57f88e695b2bb0bd7966b781001d2b9e00ee618fdc239c96e17e32cb379f13f12d6bd7b1b47ad04",+ "c37bf24c063f0310eccab8864e48dbeffcdd7240b4f8d1e01eba4fc703e6c9082b845bb55543b10f008dc7f4e78540411912ac1f36fa2aa90011dca40f323b09",+ "3f675d6c364e06405d4868c904e40f3d81c32b083d91586db814d4cb4bf536b4ba209d82f11b4cb6da293b60b20d6122fc3e0e08e80c381dee83edd848211900"+ ]+ }+ }+ },+ {+ "title": "integer wraparound",+ "filename": "test027_integer_wraparound.bc",+ "token": [+ {+ "symbols": [],+ "public_keys": [],+ "external_key": null,+ "code": "check if true || 10000000000 * 10000000000 != 0;\ncheck if true || 9223372036854775807 + 1 != 0;\ncheck if true || -9223372036854775808 - 1 != 0;\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if true || -9223372036854775808 - 1 != 0",+ "check if true || 10000000000 * 10000000000 != 0",+ "check if true || 9223372036854775807 + 1 != 0"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Err": {+ "Execution": "Overflow"+ }+ },+ "authorizer_code": "allow if true;\n",+ "revocation_ids": [+ "3346a22aae0abfc1ffa526f02f7650e90af909e5e519989026441e78cdc245b7fd126503cfdc8831325fc04307edc65238db319724477915f7040a2f6a719a05"+ ]+ }+ }+ },+ {+ "title": "test expression syntax and all available operations (v4 blocks)",+ "filename": "test028_expressions_v4.bc",+ "token": [+ {+ "symbols": [+ "abcD12x",+ "abcD12"+ ],+ "public_keys": [],+ "external_key": null,+ "code": "check if 1 != 3;\ncheck if 1 | 2 ^ 3 == 0;\ncheck if \"abcD12x\" != \"abcD12\";\ncheck if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z;\ncheck if hex:12abcd != hex:12ab;\ncheck if [1, 4] != [1, 2];\n"+ }+ ],+ "validations": {+ "": {+ "world": {+ "facts": [],+ "rules": [],+ "checks": [+ {+ "origin": 0,+ "checks": [+ "check if \"abcD12x\" != \"abcD12\"",+ "check if 1 != 3",+ "check if 1 | 2 ^ 3 == 0",+ "check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z",+ "check if [1, 4] != [1, 2]",+ "check if hex:12abcd != hex:12ab"+ ]+ }+ ],+ "policies": [+ "allow if true"+ ]+ },+ "result": {+ "Ok": 0+ },+ "authorizer_code": "allow if true;\n",+ "revocation_ids": [+ "117fa653744c859561555e6a6f5990e3a8e7817f91b87aa6991b6d64297158b4e884c92d10f49f74c96069df722aa676839b72751ca9d1fe83a7025b591de00b" ] } }
binary file changed (358 → 358 bytes)
binary file changed (321 → 321 bytes)
binary file changed (309 → 309 bytes)
binary file changed (347 → 347 bytes)
binary file changed (358 → 358 bytes)
binary file changed (485 → 485 bytes)
binary file changed (535 → 535 bytes)
binary file changed (454 → 454 bytes)
binary file changed (338 → 321 bytes)
binary file changed (302 → 302 bytes)
binary file changed (169 → 169 bytes)
binary file changed (171 → 171 bytes)
binary file changed (490 → 490 bytes)
binary file changed (205 → 205 bytes)
binary file changed (183 → 183 bytes)
binary file changed (298 → 298 bytes)
binary file changed (1609 → 1799 bytes)
binary file changed (323 → 323 bytes)
binary file changed (297 → 297 bytes)
binary file changed (390 → 390 bytes)
binary file changed (188 → 188 bytes)
binary file changed (428 → 428 bytes)
binary file changed (461 → 461 bytes)
binary file changed (458 → 458 bytes)
binary file changed (258 → 258 bytes)
binary file changed (1316 → 1547 bytes)
binary file changed (329 → 329 bytes)
binary file changed (absent → 388 bytes)