diff --git a/authorizer.go b/authorizer.go index c6aca7f2..0ab90bce 100644 --- a/authorizer.go +++ b/authorizer.go @@ -6,11 +6,10 @@ package biscuit import ( "errors" "fmt" + "math" "strings" "github.com/biscuit-auth/biscuit-go/v2/datalog" - "github.com/biscuit-auth/biscuit-go/v2/pb" - "google.golang.org/protobuf/proto" ) var ( @@ -20,10 +19,10 @@ var ( ) type Authorizer interface { - AddAuthorizer(a ParsedAuthorizer) - AddBlock(b ParsedBlock) + AddAuthorizer(a ParsedAuthorizer) error + AddBlock(b ParsedBlock) error AddFact(fact Fact) - AddRule(rule Rule) + AddRule(rule Rule) error AddCheck(check Check) AddPolicy(policy Policy) Authorize() error @@ -31,17 +30,19 @@ type Authorizer interface { Biscuit() *Biscuit Reset() PrintWorld() string - LoadPolicies([]byte) error - SerializePolicies() ([]byte, error) + // LoadPolicies([]byte) error + // SerializePolicies() ([]byte, error) } type authorizer struct { - biscuit *Biscuit - baseWorld *datalog.World - world *datalog.World - baseSymbols *datalog.SymbolTable - symbols *datalog.SymbolTable - block_worlds []*datalog.World + biscuit *Biscuit + baseWorld *datalog.World + world *datalog.World + baseSymbols *datalog.SymbolTable + symbols *datalog.SymbolTable + block_worlds []*datalog.World + scopes []datalog.Scope + publicKeyToBlockId map[uint64][]uint64 checks []Check policies []Policy @@ -79,31 +80,45 @@ func NewVerifier(b *Biscuit, opts ...AuthorizerOption) (Authorizer, error) { return a, nil } -func (v *authorizer) AddAuthorizer(a ParsedAuthorizer) { - v.AddBlock(a.Block) +func (v *authorizer) AddAuthorizer(a ParsedAuthorizer) error { + if err := v.AddBlock(a.Block); err != nil { + return err + } for _, p := range a.Policies { v.AddPolicy(p) } + return nil } -func (v *authorizer) AddBlock(block ParsedBlock) { +func (v *authorizer) AddBlock(block ParsedBlock) error { for _, f := range block.Facts { v.AddFact(f) } for _, r := range block.Rules { - v.AddRule(r) + if err := v.AddRule(r); err != nil { + return err + } } for _, c := range block.Checks { v.AddCheck(c) } + return nil } func (v *authorizer) AddFact(fact Fact) { - v.world.AddFact(fact.convert(v.symbols)) + v.world.AddFact(datalog.AuthorizerOrigin(), fact.convert(v.symbols)) } -func (v *authorizer) AddRule(rule Rule) { - v.world.AddRule(rule.convert(v.symbols)) +func (v *authorizer) AddRule(rule Rule) error { + authorizerTrustedOrigins := datalog.AuthorizerTrustedOrigins(v.scopes, v.publicKeyToBlockId) + ruleTrustedOrigins := datalog.TrustedOriginsFromScopes(rule.Scopes, authorizerTrustedOrigins, math.MaxUint64, v.publicKeyToBlockId) + + datalog_rule := rule.convert(v.symbols) + if err := datalog_rule.ValidateVariables(); err != nil { + return err + } + v.world.AddRule(math.MaxUint64, ruleTrustedOrigins, datalog_rule) + return nil } func (v *authorizer) AddCheck(check Check) { @@ -120,20 +135,50 @@ func (v *authorizer) Authorize() error { // token ements should first be converted to builder elements // with the token's symbol table, then converted back // with the verifier's symbol table - for _, fact := range *v.biscuit.authority.facts { + authorityOrigin := datalog.AuthorityOrigin() + authorizerTrustedOrigins := datalog.AuthorizerTrustedOrigins(v.scopes, v.publicKeyToBlockId) + + for _, fact := range v.biscuit.authority.facts { f, err := fromDatalogFact(v.biscuit.symbols, fact) if err != nil { return fmt.Errorf("biscuit: verification failed: %s", err) } - v.world.AddFact(f.convert(v.symbols)) + v.world.AddFact(authorityOrigin, f.convert(v.symbols)) } + authorityBlockTrustedOrigins := datalog.TrustedOriginsFromScopes(v.biscuit.authority.scopes, datalog.DefaultTrustedOrigin(), 0, v.publicKeyToBlockId) for _, rule := range v.biscuit.authority.rules { r, err := fromDatalogRule(v.biscuit.symbols, rule) if err != nil { return fmt.Errorf("biscuit: verification failed: %s", err) } - v.world.AddRule(r.convert(v.symbols)) + ruleTrustedOrigins := datalog.TrustedOriginsFromScopes(r.Scopes, authorityBlockTrustedOrigins, 0, v.publicKeyToBlockId) + + v.world.AddRule(0, ruleTrustedOrigins, r.convert(v.symbols)) + } + + for i, block := range v.biscuit.blocks { + blockTrustedOrigins := datalog.TrustedOriginsFromScopes(block.scopes, datalog.DefaultTrustedOrigin(), uint64(i+1), v.publicKeyToBlockId) + blockOrigin := datalog.MakeOrigin([]uint64{uint64(i + 1)}) + for _, fact := range block.facts { + f, err := fromDatalogFact(v.biscuit.symbols, fact) + if err != nil { + return fmt.Errorf("biscuit: verification failed: %s", err) + } + v.world.AddFact(blockOrigin, f.convert(v.symbols)) + } + + for _, rule := range block.rules { + if err := rule.ValidateVariables(); err != nil { + return fmt.Errorf("biscuit: verification failed: failed to verify block #%d: %s", i+1, err) + } + r, err := fromDatalogRule(v.biscuit.symbols, rule) + if err != nil { + return fmt.Errorf("biscuit: verification failed: %s", err) + } + ruleTrustedOrigins := datalog.TrustedOriginsFromScopes(r.Scopes, blockTrustedOrigins, uint64(i+1), v.publicKeyToBlockId) + v.world.AddRule(uint64(i+1), ruleTrustedOrigins, r.convert(v.symbols)) + } } if err := v.world.Run(v.symbols); err != nil { @@ -147,7 +192,7 @@ func (v *authorizer) Authorize() error { c := check.convert(v.symbols) successful := false for _, query := range c.Queries { - res := v.world.QueryRule(query, v.symbols) + res := v.world.QueryRule(math.MaxUint64, authorizerTrustedOrigins, query, v.symbols) if len(*res) != 0 { successful = true break @@ -170,7 +215,7 @@ func (v *authorizer) Authorize() error { successful := false for _, query := range c.Queries { - res := v.world.QueryRule(query, v.symbols) + res := v.world.QueryRule(0, authorityBlockTrustedOrigins, query, v.symbols) if len(*res) != 0 { successful = true break @@ -191,7 +236,7 @@ func (v *authorizer) Authorize() error { break } for _, query := range policy.Queries { - res := v.world.QueryRule(query.convert(v.symbols), v.symbols) + res := v.world.QueryRule(math.MaxUint64, authorizerTrustedOrigins, query.convert(v.symbols), v.symbols) if len(*res) != 0 { switch policy.Kind { case PolicyKindAllow: @@ -206,32 +251,8 @@ func (v *authorizer) Authorize() error { } } - // remove the rules from the vrifier and authority blocks - // so they are not affected by facts created by later blocks - v.world.ResetRules() - for i, block := range v.biscuit.blocks { - block_world := v.world.Clone() - - for _, fact := range *block.facts { - f, err := fromDatalogFact(v.biscuit.symbols, fact) - if err != nil { - return fmt.Errorf("biscuit: verification failed: %s", err) - } - block_world.AddFact(f.convert(v.symbols)) - } - - for _, rule := range block.rules { - r, err := fromDatalogRule(v.biscuit.symbols, rule) - if err != nil { - return fmt.Errorf("biscuit: verification failed: %s", err) - } - block_world.AddRule(r.convert(v.symbols)) - } - - if err := block_world.Run(v.symbols); err != nil { - return err - } + blockTrustedOrigins := datalog.TrustedOriginsFromScopes(block.scopes, datalog.DefaultTrustedOrigin(), uint64(i+1), v.publicKeyToBlockId) for j, check := range block.checks { ch, err := fromDatalogCheck(v.biscuit.symbols, check) @@ -242,7 +263,7 @@ func (v *authorizer) Authorize() error { successful := false for _, query := range c.Queries { - res := block_world.QueryRule(query, v.symbols) + res := v.world.QueryRule(uint64(i+1), blockTrustedOrigins, query, v.symbols) if len(*res) != 0 { successful = true @@ -256,9 +277,6 @@ func (v *authorizer) Authorize() error { errs = append(errs, fmt.Errorf("failed to verify block #%d check #%d: %s", i+1, j, debug.Check(c))) } } - - block_world.ResetRules() - v.block_worlds = append(v.block_worlds, block_world) } if len(errs) > 0 { @@ -284,18 +302,20 @@ func (v *authorizer) Query(rule Rule) (FactSet, error) { if err := v.world.Run(v.symbols); err != nil { return nil, err } - v.dirty = true - facts := v.world.QueryRule(rule.convert(v.symbols), v.symbols) + authorizerTrustedOrigins := datalog.AuthorizerTrustedOrigins(v.scopes, v.publicKeyToBlockId) + factSet := v.world.QueryRule(math.MaxUint64, authorizerTrustedOrigins, rule.convert(v.symbols), v.symbols) - result := make([]Fact, 0, len(*facts)) - for _, fact := range *facts { - f, err := fromDatalogFact(v.symbols, fact) - if err != nil { - return nil, err - } + result := make([]Fact, 0, len(*factSet)) + for _, facts := range *factSet { + for _, fact := range facts.Facts.Facts { + f, err := fromDatalogFact(v.symbols, fact) + if err != nil { + return nil, err + } - result = append(result, *f) + result = append(result, *f) + } } return result, nil @@ -324,150 +344,153 @@ func (v *authorizer) Reset() { v.dirty = false } -func (v *authorizer) LoadPolicies(authorizerPolicies []byte) error { - pbPolicies := &pb.AuthorizerPolicies{} - if err := proto.Unmarshal(authorizerPolicies, pbPolicies); err != nil { - return fmt.Errorf("verifier: failed to load policies: %w", err) - } - - switch pbPolicies.GetVersion() { - case 3: - return v.loadPoliciesV2(pbPolicies) - default: - return fmt.Errorf("verifier: unsupported policies version %d", pbPolicies.GetVersion()) - } -} - -func (v *authorizer) loadPoliciesV2(pbPolicies *pb.AuthorizerPolicies) error { - policySymbolTable := datalog.SymbolTable(pbPolicies.Symbols) - v.symbols = v.baseSymbols.Clone() - v.symbols.Extend(&policySymbolTable) - - for _, pbFact := range pbPolicies.Facts { - fact, err := protoFactToTokenFactV2(pbFact) - if err != nil { - return fmt.Errorf("verifier: load policies v1: failed to convert datalog fact: %w", err) - } - v.world.AddFact(*fact) - } - - for _, pbRule := range pbPolicies.Rules { - rule, err := protoRuleToTokenRuleV2(pbRule) - if err != nil { - return fmt.Errorf("verifier: load policies v1: failed to convert datalog rule: %w", err) - } - v.world.AddRule(*rule) - } - - v.checks = make([]Check, len(pbPolicies.Checks)) - for i, pbCheck := range pbPolicies.Checks { - dlCheck, err := protoCheckToTokenCheckV2(pbCheck) - if err != nil { - return fmt.Errorf("verifier: load policies v1: failed to convert datalog check: %w", err) - } - check, err := fromDatalogCheck(v.symbols, *dlCheck) - if err != nil { - return fmt.Errorf("verifier: load policies v1: failed to convert check: %w", err) - } - v.checks[i] = *check - } - - v.policies = make([]Policy, len(pbPolicies.Policies)) - for i, pbPolicy := range pbPolicies.Policies { - policy := Policy{} - switch *pbPolicy.Kind { - case pb.Policy_Allow: - policy.Kind = PolicyKindAllow - case pb.Policy_Deny: - policy.Kind = PolicyKindDeny - default: - return fmt.Errorf("verifier: load policies v1: unsupported proto policy kind %v", pbPolicy.Kind) - } - - policy.Queries = make([]Rule, len(pbPolicy.Queries)) - for j, pbRule := range pbPolicy.Queries { - dlRule, err := protoRuleToTokenRuleV2(pbRule) - if err != nil { - return fmt.Errorf("verifier: load policies v1: failed to convert datalog policy rule: %w", err) - } - - rule, err := fromDatalogRule(v.symbols, *dlRule) - if err != nil { - return fmt.Errorf("verifier: load policies v1: failed to convert policy rule: %w", err) - } - policy.Queries[j] = *rule - } - v.policies[i] = policy - } - - return nil -} - -func (v *authorizer) SerializePolicies() ([]byte, error) { - if v.dirty { - return nil, errors.New("verifier: can't serialize after world has been run") - } - - protoFacts := make([]*pb.FactV2, len(*v.world.Facts())) - for i, fact := range *v.world.Facts() { - protoFact, err := tokenFactToProtoFactV2(fact) - if err != nil { - return nil, fmt.Errorf("verifier: failed to convert fact: %w", err) - } - protoFacts[i] = protoFact - } - - protoRules := make([]*pb.RuleV2, len(v.world.Rules())) - for i, rule := range v.world.Rules() { - protoRule, err := tokenRuleToProtoRuleV2(rule) - if err != nil { - return nil, fmt.Errorf("verifier: failed to convert rule: %w", err) - } - protoRules[i] = protoRule - } - - protoChecks := make([]*pb.CheckV2, len(v.checks)) - for i, check := range v.checks { - protoCheck, err := tokenCheckToProtoCheckV2(check.convert(v.symbols)) - if err != nil { - return nil, fmt.Errorf("verifier: failed to convert check: %w", err) - } - protoChecks[i] = protoCheck - } - - protoPolicies := make([]*pb.Policy, len(v.policies)) - for i, policy := range v.policies { - protoPolicy := &pb.Policy{} - switch policy.Kind { - case PolicyKindAllow: - kind := pb.Policy_Allow - protoPolicy.Kind = &kind - case PolicyKindDeny: - kind := pb.Policy_Deny - protoPolicy.Kind = &kind - default: - return nil, fmt.Errorf("verifier: unsupported policy kind %v", policy.Kind) - } - - protoPolicy.Queries = make([]*pb.RuleV2, len(policy.Queries)) - for j, rule := range policy.Queries { - protoRule, err := tokenRuleToProtoRuleV2(rule.convert(v.symbols)) - if err != nil { - return nil, fmt.Errorf("verifier: failed to convert policy rule: %w", err) - } - protoPolicy.Queries[j] = protoRule - } - - protoPolicies[i] = protoPolicy - } - - version := MaxSchemaVersion - return proto.Marshal(&pb.AuthorizerPolicies{ - Symbols: *v.symbols.Clone(), - Version: proto.Uint32(version), - Facts: protoFacts, - Rules: protoRules, - Checks: protoChecks, - Policies: protoPolicies, - }) -} +// func (v *authorizer) LoadPolicies(authorizerPolicies []byte) error { +// pbPolicies := &pb.AuthorizerPolicies{} +// if err := proto.Unmarshal(authorizerPolicies, pbPolicies); err != nil { +// return fmt.Errorf("verifier: failed to load policies: %w", err) +// } + +// switch pbPolicies.GetVersion() { +// case 3: +// return v.loadPolicies(pbPolicies) +// default: +// return fmt.Errorf("verifier: unsupported policies version %d", pbPolicies.GetVersion()) +// } +// } + +// func (v *authorizer) loadPolicies(pbPolicies *pb.AuthorizerPolicies) error { +// policySymbolTable := datalog.SymbolTable{ +// Symbols: pbPolicies.Symbols, +// } +// v.symbols = v.baseSymbols.Clone() +// v.symbols.Extend(&policySymbolTable) + +// authorizerOrigin := datalog.AuthorizerOrigin() +// for _, pbFact := range pbPolicies.Facts { +// fact, err := protoFactToTokenFact(pbFact) +// if err != nil { +// return fmt.Errorf("verifier: load policies v1: failed to convert datalog fact: %w", err) +// } +// v.world.AddFact(authorizerOrigin, *fact) +// } + +// for _, pbRule := range pbPolicies.Rules { +// rule, err := protoRuleToTokenRule(pbRule) +// if err != nil { +// return fmt.Errorf("verifier: load policies v1: failed to convert datalog rule: %w", err) +// } +// v.world.AddRule(math.MaxUint64, *rule) +// } + +// v.checks = make([]Check, len(pbPolicies.Checks)) +// for i, pbCheck := range pbPolicies.Checks { +// dlCheck, err := protoCheckToTokenCheck(pbCheck) +// if err != nil { +// return fmt.Errorf("verifier: load policies v1: failed to convert datalog check: %w", err) +// } +// check, err := fromDatalogCheck(v.symbols, *dlCheck) +// if err != nil { +// return fmt.Errorf("verifier: load policies v1: failed to convert check: %w", err) +// } +// v.checks[i] = *check +// } + +// v.policies = make([]Policy, len(pbPolicies.Policies)) +// for i, pbPolicy := range pbPolicies.Policies { +// policy := Policy{} +// switch *pbPolicy.Kind { +// case pb.Policy_Allow: +// policy.Kind = PolicyKindAllow +// case pb.Policy_Deny: +// policy.Kind = PolicyKindDeny +// default: +// return fmt.Errorf("verifier: load policies v1: unsupported proto policy kind %v", pbPolicy.Kind) +// } + +// policy.Queries = make([]Rule, len(pbPolicy.Queries)) +// for j, pbRule := range pbPolicy.Queries { +// dlRule, err := protoRuleToTokenRule(pbRule) +// if err != nil { +// return fmt.Errorf("verifier: load policies v1: failed to convert datalog policy rule: %w", err) +// } + +// rule, err := fromDatalogRule(v.symbols, *dlRule) +// if err != nil { +// return fmt.Errorf("verifier: load policies v1: failed to convert policy rule: %w", err) +// } +// policy.Queries[j] = *rule +// } +// v.policies[i] = policy +// } + +// return nil +// } + +// func (v *authorizer) SerializePolicies() ([]byte, error) { +// if v.dirty { +// return nil, errors.New("verifier: can't serialize after world has been run") +// } + +// protoFacts := make([]*pb.Fact, len(*v.world.Facts())) +// for i, fact := range *v.world.Facts() { +// protoFact, err := tokenFactToProtoFact(fact) +// if err != nil { +// return nil, fmt.Errorf("verifier: failed to convert fact: %w", err) +// } +// protoFacts[i] = protoFact +// } + +// protoRules := make([]*pb.Rule, len(v.world.Rules())) +// for i, rule := range v.world.Rules() { +// protoRule, err := tokenRuleToProtoRule(rule) +// if err != nil { +// return nil, fmt.Errorf("verifier: failed to convert rule: %w", err) +// } +// protoRules[i] = protoRule +// } + +// protoChecks := make([]*pb.Check, len(v.checks)) +// for i, check := range v.checks { +// protoCheck, err := tokenCheckToProtoCheck(check.convert(v.symbols)) +// if err != nil { +// return nil, fmt.Errorf("verifier: failed to convert check: %w", err) +// } +// protoChecks[i] = protoCheck +// } + +// protoPolicies := make([]*pb.Policy, len(v.policies)) +// for i, policy := range v.policies { +// protoPolicy := &pb.Policy{} +// switch policy.Kind { +// case PolicyKindAllow: +// kind := pb.Policy_Allow +// protoPolicy.Kind = &kind +// case PolicyKindDeny: +// kind := pb.Policy_Deny +// protoPolicy.Kind = &kind +// default: +// return nil, fmt.Errorf("verifier: unsupported policy kind %v", policy.Kind) +// } + +// protoPolicy.Queries = make([]*pb.Rule, len(policy.Queries)) +// for j, rule := range policy.Queries { +// protoRule, err := tokenRuleToProtoRule(rule.convert(v.symbols)) +// if err != nil { +// return nil, fmt.Errorf("verifier: failed to convert policy rule: %w", err) +// } +// protoPolicy.Queries[j] = protoRule +// } + +// protoPolicies[i] = protoPolicy +// } + +// version := MaxSchemaVersion +// return proto.Marshal(&pb.AuthorizerPolicies{ +// Symbols: v.symbols.Clone().Symbols, +// Version: proto.Uint32(version), +// Facts: protoFacts, +// Rules: protoRules, +// Checks: protoChecks, +// Policies: protoPolicies, +// }) +// } diff --git a/authorizer_test.go b/authorizer_test.go index 6f89e330..db5d96d5 100644 --- a/authorizer_test.go +++ b/authorizer_test.go @@ -4,7 +4,6 @@ package biscuit import ( - "crypto/ed25519" "crypto/rand" "testing" @@ -13,7 +12,7 @@ import ( func TestVerifierDefaultPolicy(t *testing.T) { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot) err := builder.AddAuthorityFact(Fact{Predicate{ @@ -42,7 +41,7 @@ func TestVerifierDefaultPolicy(t *testing.T) { func TestVerifierPolicies(t *testing.T) { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot) err := builder.AddAuthorityRule(Rule{ @@ -104,7 +103,7 @@ func TestVerifierPolicies(t *testing.T) { func TestVerifierSerializeLoad(t *testing.T) { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot) b, err := builder.Build() @@ -150,16 +149,16 @@ func TestVerifierSerializeLoad(t *testing.T) { v1.AddFact(fact1) v1.AddFact(fact2) - v1.AddRule(rule1) + require.NoError(t, v1.AddRule(rule1)) v1.AddCheck(check1) v1.AddPolicy(policy) - s, err := v1.SerializePolicies() - require.NoError(t, err) + // s, err := v1.SerializePolicies() + // require.NoError(t, err) v2, err := b.Authorizer(publicRoot) require.NoError(t, err) - require.NoError(t, v2.LoadPolicies(s)) + // require.NoError(t, v2.LoadPolicies(s)) require.Equal(t, v1.(*authorizer).world.Facts(), v2.(*authorizer).world.Facts()) require.Equal(t, v1.(*authorizer).world.Rules(), v2.(*authorizer).world.Rules()) diff --git a/biscuit.go b/biscuit.go index 02bbb056..5b525e39 100644 --- a/biscuit.go +++ b/biscuit.go @@ -68,7 +68,7 @@ type biscuitOption interface { applyToBiscuit(*biscuitOptions) error } -func newBiscuit(root ed25519.PrivateKey, baseSymbols *datalog.SymbolTable, authority *Block, opts ...biscuitOption) (*Biscuit, error) { +func newBiscuit(root PrivateKey, baseSymbols *datalog.SymbolTable, authority *Block, opts ...biscuitOption) (*Biscuit, error) { options := biscuitOptions{ rng: rand.Reader, } @@ -86,7 +86,7 @@ func newBiscuit(root ed25519.PrivateKey, baseSymbols *datalog.SymbolTable, autho symbols.Extend(authority.symbols) - nextPublicKey, nextPrivateKey, _ := ed25519.GenerateKey(options.rng) + nextPublicKey, nextPrivateKey, _ := NewEd25519KeyPair(options.rng) protoAuthority, err := tokenBlockToProtoBlock(authority) if err != nil { @@ -101,12 +101,16 @@ func newBiscuit(root ed25519.PrivateKey, baseSymbols *datalog.SymbolTable, autho toSignAlgorithm := make([]byte, 4) binary.LittleEndian.PutUint32(toSignAlgorithm[0:], uint32(pb.PublicKey_Ed25519)) toSign := append(marshalledAuthority[:], toSignAlgorithm...) - toSign = append(toSign, nextPublicKey[:]...) + toSign = append(toSign, nextPublicKey.Serialize()...) + + signature, err := root.Sign(toSign) + if err != nil { + return nil, err + } - signature := ed25519.Sign(root, toSign) nextKey := &pb.PublicKey{ Algorithm: &algorithm, - Key: nextPublicKey, + Key: nextPublicKey.Serialize(), } signedBlock := &pb.SignedBlock{ @@ -117,7 +121,7 @@ func newBiscuit(root ed25519.PrivateKey, baseSymbols *datalog.SymbolTable, autho proof := &pb.Proof{ Content: &pb.Proof_NextSecret{ - NextSecret: nextPrivateKey.Seed(), + NextSecret: nextPrivateKey.Serialize(), }, } @@ -134,7 +138,7 @@ func newBiscuit(root ed25519.PrivateKey, baseSymbols *datalog.SymbolTable, autho }, nil } -func New(rng io.Reader, root ed25519.PrivateKey, baseSymbols *datalog.SymbolTable, authority *Block) (*Biscuit, error) { +func New(rng io.Reader, root PrivateKey, baseSymbols *datalog.SymbolTable, authority *Block) (*Biscuit, error) { var opts []biscuitOption if rng != nil { opts = []biscuitOption{WithRNG(rng)} @@ -180,7 +184,7 @@ func (b *Biscuit) Append(rng io.Reader, block *Block) (*Biscuit, error) { symbols := b.symbols.Clone() symbols.Extend(block.symbols) - nextPublicKey, nextPrivateKey, _ := ed25519.GenerateKey(rng) + nextPublicKey, nextPrivateKey, _ := NewEd25519KeyPair(rng) // serialize and sign the new block protoBlock, err := tokenBlockToProtoBlock(block) @@ -196,12 +200,12 @@ func (b *Biscuit) Append(rng io.Reader, block *Block) (*Biscuit, error) { toSignAlgorithm := make([]byte, 4) binary.LittleEndian.PutUint32(toSignAlgorithm[0:], uint32(pb.PublicKey_Ed25519)) toSign := append(marshalledBlock[:], toSignAlgorithm...) - toSign = append(toSign, nextPublicKey[:]...) + toSign = append(toSign, nextPublicKey.Serialize()...) signature := ed25519.Sign(privateKey, toSign) nextKey := &pb.PublicKey{ Algorithm: &algorithm, - Key: nextPublicKey, + Key: nextPublicKey.Serialize(), } signedBlock := &pb.SignedBlock{ @@ -212,7 +216,7 @@ func (b *Biscuit) Append(rng io.Reader, block *Block) (*Biscuit, error) { proof := &pb.Proof{ Content: &pb.Proof_NextSecret{ - NextSecret: nextPrivateKey.Seed(), + NextSecret: nextPrivateKey.Serialize(), }, } @@ -238,16 +242,19 @@ func (b *Biscuit) Seal(rng io.Reader) (*Biscuit, error) { return nil, errors.New("biscuit: token is already sealed") } - privateKey := b.container.Proof.GetNextSecret() - if privateKey == nil { + privateKeyData := b.container.Proof.GetNextSecret() + if privateKeyData == nil { return nil, errors.New("biscuit: token is already sealed") } - if len(privateKey) != 32 { + if len(privateKeyData) != 32 { return nil, ErrInvalidKeySize } - privateKey = ed25519.NewKeyFromSeed(privateKey) + privateKey, err := Ed25519PrivateKeyDeserialize(privateKeyData) + if err != nil { + return nil, err + } // clone biscuit fields and append new block authority := new(Block) @@ -272,7 +279,10 @@ func (b *Biscuit) Seal(rng io.Reader) (*Biscuit, error) { toSign = append(toSign, lastBlock.NextKey.Key[:]...) toSign = append(toSign, lastBlock.Signature[:]...) - signature := ed25519.Sign(privateKey, toSign) + signature, err := privateKey.Sign(toSign) + if err != nil { + return nil, err + } proof := &pb.Proof{ Content: &pb.Proof_FinalSignature{ @@ -302,14 +312,14 @@ type ( // corresponding public key, if any. If it doesn't recognize the ID or can't find the public // key, or no ID is supplied and there is no default public key available, it should return an // error satisfying errors.Is(err, ErrNoPublicKeyAvailable). - PublickKeyByIDProjection func(*uint32) (ed25519.PublicKey, error) + PublickKeyByIDProjection func(*uint32) (*PublicKey, error) ) // WithSingularRootPublicKey supplies one public key to use as the root key with which to verify the // signatures on a biscuit's blocks. -func WithSingularRootPublicKey(key ed25519.PublicKey) PublickKeyByIDProjection { - return func(*uint32) (ed25519.PublicKey, error) { - return key, nil +func WithSingularRootPublicKey(key PublicKey) PublickKeyByIDProjection { + return func(*uint32) (*PublicKey, error) { + return &key, nil } } @@ -319,24 +329,26 @@ func WithSingularRootPublicKey(key ed25519.PublicKey) PublickKeyByIDProjection { // function selects the optional default key instead. If no public key is available—whether for the // biscuit's embedded key ID or a default key when no such ID is present—it returns // [ErrNoPublicKeyAvailable]. -func WithRootPublicKeys(keysByID map[uint32]ed25519.PublicKey, defaultKey *ed25519.PublicKey) PublickKeyByIDProjection { - return func(id *uint32) (ed25519.PublicKey, error) { +func WithRootPublicKeys(keysByID map[uint32]PublicKey, defaultKey PublicKey) PublickKeyByIDProjection { + return func(id *uint32) (*PublicKey, error) { if id == nil { if defaultKey != nil { - return *defaultKey, nil + return &defaultKey, nil } } else if key, ok := keysByID[*id]; ok { - return key, nil + if key == nil { + return nil, ErrNoPublicKeyAvailable + } + return &key, nil } return nil, ErrNoPublicKeyAvailable } } -func (b *Biscuit) authorizerFor(root ed25519.PublicKey, opts ...AuthorizerOption) (Authorizer, error) { - currentKey := root +func (b *Biscuit) authorizerFor(root PublicKey, opts ...AuthorizerOption) (Authorizer, error) { // for now we only support Ed25519 - if *b.container.Authority.NextKey.Algorithm != pb.PublicKey_Ed25519 { + if Algorithm(*b.container.Authority.NextKey.Algorithm) != root.Algorithm() { return nil, UnsupportedAlgorithm } @@ -346,13 +358,13 @@ func (b *Biscuit) authorizerFor(root ed25519.PublicKey, opts ...AuthorizerOption toVerify := append(b.container.Authority.Block[:], algorithm...) toVerify = append(toVerify, b.container.Authority.NextKey.Key[:]...) - if ok := ed25519.Verify(currentKey, toVerify, b.container.Authority.Signature); !ok { + if ok := root.Verify(toVerify, b.container.Authority.Signature); !ok { return nil, ErrInvalidSignature } - currentKey = b.container.Authority.NextKey.Key - if len(currentKey) != 32 { - return nil, ErrInvalidKeySize + currentKey, err := Ed25519PublicKeyDeserialize(b.container.Authority.NextKey.Key) + if err != nil { + return nil, err } for _, block := range b.container.Blocks { @@ -365,26 +377,54 @@ func (b *Biscuit) authorizerFor(root ed25519.PublicKey, opts ...AuthorizerOption toVerify := append(block.Block[:], algorithm...) toVerify = append(toVerify, block.NextKey.Key[:]...) - if ok := ed25519.Verify(currentKey, toVerify, block.Signature); !ok { + if ok := currentKey.Verify(toVerify, block.Signature); !ok { return nil, ErrInvalidSignature } - currentKey = block.NextKey.Key - if len(currentKey) != 32 { - return nil, ErrInvalidKeySize + if block.ExternalSignature != nil { + // an external signature is present, we need to verify it + if *block.ExternalSignature.PublicKey.Algorithm != pb.PublicKey_Ed25519 { + return nil, UnsupportedAlgorithm + } + externalKey, err := Ed25519PublicKeyDeserialize(block.ExternalSignature.PublicKey.Key) + if err != nil { + return nil, err + } + + // the public key that's part of the signed block is the public key used to sign + // the previous block + algorithm := make([]byte, 4) + binary.LittleEndian.PutUint32(algorithm[0:], uint32(externalKey.Algorithm())) + toVerify := append(block.Block[:], algorithm...) + toVerify = append(toVerify, currentKey.Serialize()...) + + if ok := externalKey.Verify(toVerify, block.ExternalSignature.Signature); !ok { + return nil, ErrInvalidSignature + } + } + + currentKey, err = Ed25519PublicKeyDeserialize(block.NextKey.Key) + if err != nil { + return nil, err } } switch { case b.container.Proof.GetNextSecret() != nil: { - privateKey := b.container.Proof.GetNextSecret() - if privateKey == nil { + privateKeyData := b.container.Proof.GetNextSecret() + if privateKeyData == nil { return nil, errors.New("biscuit: sealed token verification not implemented") } - publicKey := ed25519.NewKeyFromSeed(privateKey).Public() - if !bytes.Equal(currentKey, publicKey.(ed25519.PublicKey)) { + privateKey, err := Ed25519PrivateKeyDeserialize(privateKeyData) + if err != nil { + return nil, err + } + + publicKey := privateKey.PublicKey() + + if !bytes.Equal(currentKey.Serialize(), publicKey.Serialize()) { return nil, errors.New("biscuit: invalid last signature") } } @@ -404,7 +444,7 @@ func (b *Biscuit) authorizerFor(root ed25519.PublicKey, opts ...AuthorizerOption toVerify = append(toVerify, lastBlock.NextKey.Key[:]...) toVerify = append(toVerify, lastBlock.Signature[:]...) - if ok := ed25519.Verify(currentKey, toVerify, signature); !ok { + if ok := currentKey.Verify(toVerify, signature); !ok { return nil, errors.New("biscuit: invalid last signature") } } @@ -427,10 +467,8 @@ func (b *Biscuit) AuthorizerFor(keySource PublickKeyByIDProjection, opts ...Auth if err != nil { return nil, fmt.Errorf("choosing root public key: %w", err) } - if len(rootPublicKey) == 0 { - return nil, ErrNoPublicKeyAvailable - } - return b.authorizerFor(rootPublicKey, opts...) + + return b.authorizerFor(*rootPublicKey, opts...) } // TODO: Add "Deprecated" note to the "(*Biscuit).Authorizer" method, recommending use of @@ -439,7 +477,7 @@ func (b *Biscuit) AuthorizerFor(keySource PublickKeyByIDProjection, opts ...Auth // Authorizer checks the signature and creates an [Authorizer]. The Authorizer can then test the // authorizaion policies and accept or refuse the request. -func (b *Biscuit) Authorizer(root ed25519.PublicKey, opts ...AuthorizerOption) (Authorizer, error) { +func (b *Biscuit) Authorizer(root PublicKey, opts ...AuthorizerOption) (Authorizer, error) { return b.authorizerFor(root) } @@ -466,30 +504,30 @@ func (b *Biscuit) Serialize() ([]byte, error) { var ErrFactNotFound = errors.New("biscuit: fact not found") -// GetBlockID returns the first block index containing a fact -// starting from the authority block and then each block in the order they were added. -// ErrFactNotFound is returned when no block contains the fact. -func (b *Biscuit) GetBlockID(fact Fact) (int, error) { - // don't store symbols from searched fact in the verifier table - symbols := b.symbols.Clone() - datalogFact := fact.Predicate.convert(symbols) - - for _, f := range *b.authority.facts { - if f.Equal(datalogFact) { - return 0, nil - } - } - - for i, b := range b.blocks { - for _, f := range *b.facts { - if f.Equal(datalogFact) { - return i + 1, nil - } - } - } - - return 0, ErrFactNotFound -} +// // GetBlockID returns the first block index containing a fact +// // starting from the authority block and then each block in the order they were added. +// // ErrFactNotFound is returned when no block contains the fact. +// func (b *Biscuit) GetBlockID(fact Fact) (int, error) { +// // don't store symbols from searched fact in the verifier table +// symbols := b.symbols.Clone() +// datalogFact := fact.Predicate.convert(symbols) + +// for _, f := range *b.authority.facts { +// if f.Equal(datalogFact) { +// return 0, nil +// } +// } + +// for i, b := range b.blocks { +// for _, f := range *b.facts { +// if f.Equal(datalogFact) { +// return i + 1, nil +// } +// } +// } + +// return 0, ErrFactNotFound +// } /* // SHA256Sum returns a hash of `count` biscuit blocks + the authority block @@ -571,33 +609,35 @@ func (b *Biscuit) checkRootKey(root ed25519.PublicKey) error { return nil }*/ -func (b *Biscuit) generateWorld(symbols *datalog.SymbolTable) (*datalog.World, error) { - world := datalog.NewWorld() +// func (b *Biscuit) generateWorld(symbols *datalog.SymbolTable) (*datalog.World, error) { +// world := datalog.NewWorld() - for _, fact := range *b.authority.facts { - world.AddFact(fact) - } +// authorityOrigin := datalog.AuthorityOrigin() +// for _, fact := range b.authority.facts { +// world.AddFact(authorityOrigin, fact) +// } - for _, rule := range b.authority.rules { - world.AddRule(rule) - } +// for _, rule := range b.authority.rules { +// world.AddRule(0, rule) +// } - for _, block := range b.blocks { - for _, fact := range *block.facts { - world.AddFact(fact) - } +// for index, block := range b.blocks { +// blockOrigin := datalog.MakeOrigin([]uint64{uint64(index + 1)}) +// for _, fact := range block.facts { +// world.AddFact(blockOrigin, fact) +// } - for _, rule := range block.rules { - world.AddRule(rule) - } - } +// for _, rule := range block.rules { +// world.AddRule(datalog.SingleOrigin(index+1), rule) +// } +// } - if err := world.Run(symbols); err != nil { - return nil, err - } +// if err := world.Run(symbols); err != nil { +// return nil, err +// } - return world, nil -} +// return world, nil +// } func (b *Biscuit) RevocationIds() [][]byte { result := make([][]byte, 0, len(b.blocks)+1) diff --git a/biscuit_test.go b/biscuit_test.go index 4d96c201..f106cdc8 100644 --- a/biscuit_test.go +++ b/biscuit_test.go @@ -4,7 +4,6 @@ package biscuit import ( - "crypto/ed25519" "crypto/rand" "fmt" "testing" @@ -17,7 +16,7 @@ func TestBiscuit(t *testing.T) { rng := rand.Reader const rootKeyID = 123 const contextText = "current_context" - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder( privateRoot, @@ -128,7 +127,7 @@ func TestBiscuit(t *testing.T) { func TestSealedBiscuit(t *testing.T) { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot) @@ -185,7 +184,7 @@ func TestSealedBiscuit(t *testing.T) { func TestBiscuitRules(t *testing.T) { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot) @@ -261,7 +260,7 @@ func TestBiscuitRules(t *testing.T) { verifyOwner(t, *b2, publicRoot, map[string]bool{"alice": true, "bob": false, "eve": false}) } -func verifyOwner(t *testing.T, b Biscuit, publicRoot ed25519.PublicKey, owners map[string]bool) { +func verifyOwner(t *testing.T, b Biscuit, publicRoot PublicKey, owners map[string]bool) { for user, valid := range owners { v, err := b.AuthorizerFor(WithSingularRootPublicKey(publicRoot)) require.NoError(t, err) @@ -292,111 +291,113 @@ func verifyOwner(t *testing.T, b Biscuit, publicRoot ed25519.PublicKey, owners m func TestCheckRootKey(t *testing.T) { rng := rand.Reader const rootKeyID = 123 - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot, WithRootKeyID(rootKeyID)) b, err := builder.Build() require.NoError(t, err) - _, err = b.AuthorizerFor(WithRootPublicKeys(map[uint32]ed25519.PublicKey{ + _, err = b.AuthorizerFor(WithRootPublicKeys(map[uint32]PublicKey{ rootKeyID: publicRoot, }, nil)) require.NoError(t, err) - _, err = b.AuthorizerFor(WithRootPublicKeys(map[uint32]ed25519.PublicKey{ + _, err = b.AuthorizerFor(WithRootPublicKeys(map[uint32]PublicKey{ rootKeyID + 1: publicRoot, }, nil)) require.ErrorIs(t, err, ErrNoPublicKeyAvailable) - _, err = b.AuthorizerFor(WithRootPublicKeys(map[uint32]ed25519.PublicKey{ + _, err = b.AuthorizerFor(WithRootPublicKeys(map[uint32]PublicKey{ rootKeyID: nil, }, nil)) require.ErrorIs(t, err, ErrNoPublicKeyAvailable) - publicNotRoot, _, _ := ed25519.GenerateKey(rng) + publicNotRoot, _, _ := NewEd25519KeyPair(rng) _, err = b.AuthorizerFor(WithSingularRootPublicKey(publicNotRoot)) require.Equal(t, ErrInvalidSignature, err) } -func TestGenerateWorld(t *testing.T) { - rng := rand.Reader - _, privateRoot, _ := ed25519.GenerateKey(rng) - - build := NewBuilder(privateRoot) - - authorityFact1 := Fact{Predicate: Predicate{Name: "fact1", IDs: []Term{String("file1")}}} - authorityFact2 := Fact{Predicate: Predicate{Name: "fact2", IDs: []Term{String("file2")}}} - - authorityRule1 := Rule{ - Head: Predicate{Name: "right", IDs: []Term{Variable("1"), String("read")}}, - Body: []Predicate{ - {Name: "resource", IDs: []Term{Variable("1")}}, - {Name: "owner", IDs: []Term{Variable("0"), Variable("1")}}, - }, - } - authorityRule2 := Rule{ - Head: Predicate{Name: "right", IDs: []Term{Variable("1"), String("write")}}, - Body: []Predicate{ - {Name: "resource", IDs: []Term{Variable("1")}}, - {Name: "owner", IDs: []Term{Variable("0"), Variable("1")}}, - }, - } - - build.AddAuthorityFact(authorityFact1) - build.AddAuthorityFact(authorityFact2) - build.AddAuthorityRule(authorityRule1) - build.AddAuthorityRule(authorityRule2) - - b, err := build.Build() - require.NoError(t, err) - - StringTable := (build.(*builderOptions)).symbols - world, err := b.generateWorld(defaultSymbolTable.Clone()) - require.NoError(t, err) - - expectedWorld := datalog.NewWorld() - expectedWorld.AddFact(authorityFact1.convert(StringTable)) - expectedWorld.AddFact(authorityFact2.convert(StringTable)) - expectedWorld.AddRule(authorityRule1.convert(StringTable)) - expectedWorld.AddRule(authorityRule2.convert(StringTable)) - require.Equal(t, expectedWorld, world) - - blockBuild := b.CreateBlock() - blockRule := Rule{ - Head: Predicate{Name: "blockRule", IDs: []Term{Variable("1")}}, - Body: []Predicate{ - {Name: "resource", IDs: []Term{Variable("1")}}, - {Name: "owner", IDs: []Term{String("alice"), Variable("1")}}, - }, - } - blockBuild.AddRule(blockRule) - - blockFact := Fact{Predicate{Name: "resource", IDs: []Term{String("file1")}}} - blockBuild.AddFact(blockFact) - - b2, err := b.Append(rng, blockBuild.Build()) - require.NoError(t, err) - - allStrings := append(*StringTable, *(blockBuild.(*blockBuilder)).symbols...) - world, err = b2.generateWorld(&allStrings) - require.NoError(t, err) - - expectedWorld = datalog.NewWorld() - expectedWorld.AddFact(authorityFact1.convert(&allStrings)) - expectedWorld.AddFact(authorityFact2.convert(&allStrings)) - expectedWorld.AddFact(blockFact.convert(&allStrings)) - expectedWorld.AddRule(authorityRule1.convert(&allStrings)) - expectedWorld.AddRule(authorityRule2.convert(&allStrings)) - expectedWorld.AddRule( - blockRule.convert(&allStrings), - ) - require.Equal(t, expectedWorld, world) -} +// func TestGenerateWorld(t *testing.T) { +// rng := rand.Reader +// _, privateRoot, _ := NewEd25519KeyPair(rng) + +// build := NewBuilder(privateRoot) + +// authorityFact1 := Fact{Predicate: Predicate{Name: "fact1", IDs: []Term{String("file1")}}} +// authorityFact2 := Fact{Predicate: Predicate{Name: "fact2", IDs: []Term{String("file2")}}} + +// authorityRule1 := Rule{ +// Head: Predicate{Name: "right", IDs: []Term{Variable("1"), String("read")}}, +// Body: []Predicate{ +// {Name: "resource", IDs: []Term{Variable("1")}}, +// {Name: "owner", IDs: []Term{Variable("0"), Variable("1")}}, +// }, +// } +// authorityRule2 := Rule{ +// Head: Predicate{Name: "right", IDs: []Term{Variable("1"), String("write")}}, +// Body: []Predicate{ +// {Name: "resource", IDs: []Term{Variable("1")}}, +// {Name: "owner", IDs: []Term{Variable("0"), Variable("1")}}, +// }, +// } + +// build.AddAuthorityFact(authorityFact1) +// build.AddAuthorityFact(authorityFact2) +// build.AddAuthorityRule(authorityRule1) +// build.AddAuthorityRule(authorityRule2) + +// b, err := build.Build() +// require.NoError(t, err) + +// StringTable := (build.(*builderOptions)).symbols +// world, err := b.generateWorld(defaultSymbolTable.Clone()) +// require.NoError(t, err) + +// authorityOrigin := datalog.AuthorityOrigin() +// trustedOrigin := datalog.DefaultTrustedOrigin() +// expectedWorld := datalog.NewWorld() +// expectedWorld.AddFact(authorityOrigin, authorityFact1.convert(StringTable)) +// expectedWorld.AddFact(authorityOrigin, authorityFact2.convert(StringTable)) +// expectedWorld.AddRule(authorityOrigin, trustedOrigin, authorityRule1.convert(StringTable)) +// expectedWorld.AddRule(authorityOrigin, trustedOrigin, authorityRule2.convert(StringTable)) +// require.Equal(t, expectedWorld, world) + +// blockBuild := b.CreateBlock() +// blockRule := Rule{ +// Head: Predicate{Name: "blockRule", IDs: []Term{Variable("1")}}, +// Body: []Predicate{ +// {Name: "resource", IDs: []Term{Variable("1")}}, +// {Name: "owner", IDs: []Term{String("alice"), Variable("1")}}, +// }, +// } +// blockBuild.AddRule(blockRule) + +// blockFact := Fact{Predicate{Name: "resource", IDs: []Term{String("file1")}}} +// blockBuild.AddFact(blockFact) + +// b2, err := b.Append(rng, blockBuild.Build()) +// require.NoError(t, err) + +// blockSymbols := (blockBuild.(*blockBuilder)).symbols +// allStrings := StringTable.Clone() +// allStrings.Extend(blockSymbols) +// world, err = b2.generateWorld(allStrings) +// require.NoError(t, err) + +// expectedWorld = datalog.NewWorld() +// expectedWorld.AddFact(authorityOrigin, authorityFact1.convert(allStrings)) +// expectedWorld.AddFact(authorityOrigin, authorityFact2.convert(allStrings)) +// expectedWorld.AddFact(datalog.MakeOrigin([]uint64{1}), blockFact.convert(allStrings)) +// expectedWorld.AddRule(authorityOrigin, trustedOrigin, authorityRule1.convert(allStrings)) +// expectedWorld.AddRule(authorityOrigin, trustedOrigin, authorityRule2.convert(allStrings)) +// expectedWorld.AddRule(datalog.MakeOrigin([]uint64{1}), trustedOrigin, blockRule.convert(allStrings)) +// require.Equal(t, expectedWorld, world) +// } func TestAppendErrors(t *testing.T) { rng := rand.Reader - _, privateRoot, _ := ed25519.GenerateKey(rng) + _, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot) builder.AddAuthorityFact(Fact{ Predicate: Predicate{Name: "newfact", IDs: []Term{String("/a/file1"), String("read")}}, @@ -407,7 +408,7 @@ func TestAppendErrors(t *testing.T) { require.NoError(t, err) _, err = b.Append(rng, &Block{ - symbols: &datalog.SymbolTable{"newfact"}, + symbols: &datalog.SymbolTable{Symbols: []string{"newfact"}}, }) require.Equal(t, ErrSymbolTableOverlap, err) }) @@ -418,7 +419,7 @@ func TestAppendErrors(t *testing.T) { _, err = b.Append(rng, &Block{ symbols: &datalog.SymbolTable{}, - facts: &datalog.FactSet{}, + facts: []datalog.Fact{}, }) require.NoError(t, err) @@ -434,9 +435,9 @@ func TestNewErrors(t *testing.T) { rng := rand.Reader t.Run("authority block Strings overlap", func(t *testing.T) { - _, privateRoot, _ := ed25519.GenerateKey(rng) - _, err := New(rng, privateRoot, &datalog.SymbolTable{"String1", "String2"}, &Block{ - symbols: &datalog.SymbolTable{"String1"}, + _, privateRoot, _ := NewEd25519KeyPair(rng) + _, err := New(rng, privateRoot, &datalog.SymbolTable{Symbols: []string{"String1", "String2"}}, &Block{ + symbols: &datalog.SymbolTable{Symbols: []string{"String1"}}, }) require.Equal(t, ErrSymbolTableOverlap, err) }) @@ -444,7 +445,7 @@ func TestNewErrors(t *testing.T) { func TestBiscuitVerifyErrors(t *testing.T) { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot) b, err := builder.Build() @@ -453,7 +454,7 @@ func TestBiscuitVerifyErrors(t *testing.T) { _, err = b.AuthorizerFor(WithSingularRootPublicKey(publicRoot)) require.NoError(t, err) - publicTest, _, _ := ed25519.GenerateKey(rng) + publicTest, _, _ := NewEd25519KeyPair(rng) _, err = b.AuthorizerFor(WithSingularRootPublicKey(publicTest)) require.Error(t, err) } @@ -506,80 +507,80 @@ p } */ -func TestGetBlockID(t *testing.T) { - rng := rand.Reader - _, privateRoot, _ := ed25519.GenerateKey(rng) - builder := NewBuilder(privateRoot) - - // add 3 facts authority_0_fact_{0,1,2} in authority block - for i := 0; i < 3; i++ { - require.NoError(t, builder.AddAuthorityFact(Fact{Predicate: Predicate{ - Name: fmt.Sprintf("authority_0_fact_%d", i), - IDs: []Term{Integer(i)}, - }})) - } - - b, err := builder.Build() - require.NoError(t, err) - // add 2 extra blocks each containing 3 facts block_{0,1}_fact_{0,1,2} - for i := 0; i < 2; i++ { - blockBuilder := b.CreateBlock() - for j := 0; j < 3; j++ { - blockBuilder.AddFact(Fact{Predicate: Predicate{ - Name: fmt.Sprintf("block_%d_fact_%d", i, j), - IDs: []Term{String("block"), Integer(i), Integer(j)}, - }}) - } - b, err = b.Append(rng, blockBuilder.Build()) - require.NoError(t, err) - } - - idx, err := b.GetBlockID(Fact{Predicate{ - Name: "authority_0_fact_0", - IDs: []Term{Integer(0)}, - }}) - require.NoError(t, err) - require.Equal(t, 0, idx) - idx, err = b.GetBlockID(Fact{Predicate{ - Name: "authority_0_fact_2", - IDs: []Term{Integer(2)}, - }}) - require.NoError(t, err) - require.Equal(t, 0, idx) - - idx, err = b.GetBlockID(Fact{Predicate{ - Name: "block_0_fact_2", - IDs: []Term{String("block"), Integer(0), Integer(2)}, - }}) - require.NoError(t, err) - require.Equal(t, 1, idx) - idx, err = b.GetBlockID(Fact{Predicate{ - Name: "block_1_fact_1", - IDs: []Term{String("block"), Integer(1), Integer(1)}, - }}) - require.NoError(t, err) - require.Equal(t, 2, idx) - - _, err = b.GetBlockID(Fact{Predicate{ - Name: "block_1_fact_3", - IDs: []Term{String("block"), Integer(1), Integer(3)}, - }}) - require.Equal(t, ErrFactNotFound, err) - _, err = b.GetBlockID(Fact{Predicate{ - Name: "block_2_fact_1", - IDs: []Term{String("block"), Integer(2), Integer(1)}, - }}) - require.Equal(t, ErrFactNotFound, err) - _, err = b.GetBlockID(Fact{Predicate{ - Name: "block_1_fact_1", - IDs: []Term{Integer(1), Integer(1)}, - }}) - require.Equal(t, ErrFactNotFound, err) -} +// func TestGetBlockID(t *testing.T) { +// rng := rand.Reader +// _, privateRoot, _ := NewEd25519KeyPair(rng) +// builder := NewBuilder(privateRoot) + +// // add 3 facts authority_0_fact_{0,1,2} in authority block +// for i := 0; i < 3; i++ { +// require.NoError(t, builder.AddAuthorityFact(Fact{Predicate: Predicate{ +// Name: fmt.Sprintf("authority_0_fact_%d", i), +// IDs: []Term{Integer(i)}, +// }})) +// } + +// b, err := builder.Build() +// require.NoError(t, err) +// // add 2 extra blocks each containing 3 facts block_{0,1}_fact_{0,1,2} +// for i := 0; i < 2; i++ { +// blockBuilder := b.CreateBlock() +// for j := 0; j < 3; j++ { +// blockBuilder.AddFact(Fact{Predicate: Predicate{ +// Name: fmt.Sprintf("block_%d_fact_%d", i, j), +// IDs: []Term{String("block"), Integer(i), Integer(j)}, +// }}) +// } +// b, err = b.Append(rng, blockBuilder.Build()) +// require.NoError(t, err) +// } + +// idx, err := b.GetBlockID(Fact{Predicate{ +// Name: "authority_0_fact_0", +// IDs: []Term{Integer(0)}, +// }}) +// require.NoError(t, err) +// require.Equal(t, 0, idx) +// idx, err = b.GetBlockID(Fact{Predicate{ +// Name: "authority_0_fact_2", +// IDs: []Term{Integer(2)}, +// }}) +// require.NoError(t, err) +// require.Equal(t, 0, idx) + +// idx, err = b.GetBlockID(Fact{Predicate{ +// Name: "block_0_fact_2", +// IDs: []Term{String("block"), Integer(0), Integer(2)}, +// }}) +// require.NoError(t, err) +// require.Equal(t, 1, idx) +// idx, err = b.GetBlockID(Fact{Predicate{ +// Name: "block_1_fact_1", +// IDs: []Term{String("block"), Integer(1), Integer(1)}, +// }}) +// require.NoError(t, err) +// require.Equal(t, 2, idx) + +// _, err = b.GetBlockID(Fact{Predicate{ +// Name: "block_1_fact_3", +// IDs: []Term{String("block"), Integer(1), Integer(3)}, +// }}) +// require.Equal(t, ErrFactNotFound, err) +// _, err = b.GetBlockID(Fact{Predicate{ +// Name: "block_2_fact_1", +// IDs: []Term{String("block"), Integer(2), Integer(1)}, +// }}) +// require.Equal(t, ErrFactNotFound, err) +// _, err = b.GetBlockID(Fact{Predicate{ +// Name: "block_1_fact_1", +// IDs: []Term{Integer(1), Integer(1)}, +// }}) +// require.Equal(t, ErrFactNotFound, err) +// } func TestInvalidRuleGeneration(t *testing.T) { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := NewEd25519KeyPair(rng) builder := NewBuilder(privateRoot) builder.AddAuthorityCheck(Check{Queries: []Rule{ { diff --git a/builder.go b/builder.go index 53327ce4..196d0182 100644 --- a/builder.go +++ b/builder.go @@ -4,8 +4,8 @@ package biscuit import ( - "crypto/ed25519" "errors" + "fmt" "io" "github.com/biscuit-auth/biscuit-go/v2/datalog" @@ -31,12 +31,12 @@ type Builder interface { type builderOptions struct { rng io.Reader - rootKey ed25519.PrivateKey + rootKey PrivateKey rootKeyID *uint32 symbolsStart int symbols *datalog.SymbolTable - facts *datalog.FactSet + facts []datalog.Fact rules []datalog.Rule checks []datalog.Check context string @@ -60,12 +60,11 @@ func WithSymbols(symbols *datalog.SymbolTable) builderOption { return symbolsOption{symbols} } -func NewBuilder(root ed25519.PrivateKey, opts ...builderOption) Builder { +func NewBuilder(root PrivateKey, opts ...builderOption) Builder { b := &builderOptions{ rootKey: root, symbols: defaultSymbolTable.Clone(), symbolsStart: defaultSymbolTable.Len(), - facts: new(datalog.FactSet), } for _, o := range opts { @@ -99,9 +98,7 @@ func (b *builderOptions) AddBlock(block ParsedBlock) error { func (b *builderOptions) AddAuthorityFact(fact Fact) error { dlFact := fact.convert(b.symbols) - if !b.facts.Insert(dlFact) { - return ErrDuplicateFact - } + b.facts = append(b.facts, dlFact) return nil } @@ -212,6 +209,79 @@ func (u *Unmarshaler) Unmarshal(serialized []byte) (*Biscuit, error) { }, nil } +func UnmarshalSerialized(serialized []byte) (*SerializedBiscuit, error) { + container := new(pb.Biscuit) + if err := proto.Unmarshal(serialized, container); err != nil { + return nil, err + } + + authority := new(CryptoBlock) + authority.Data = container.Authority.Block + nextKey, err := protoPublicKeyToTokenPublicKey(container.Authority.NextKey) + if err != nil { + return nil, err + } + authority.NextKey = nextKey + authority.Signature = container.Authority.Signature + // the authority block cannot have an external signature + // authority.Version = container.Authority.Version + + blocks := make([]CryptoBlock, len(container.Blocks)) + for i, sb := range container.Blocks { + block := new(CryptoBlock) + block.Data = sb.Block + nextKey, err := protoPublicKeyToTokenPublicKey(sb.NextKey) + if err != nil { + return nil, err + } + block.NextKey = nextKey + block.Signature = sb.Signature + if sb.ExternalSignature != nil { + externalSignature := new(ExternalSignature) + publicKey, err := protoPublicKeyToTokenPublicKey(sb.ExternalSignature.PublicKey) + if err != nil { + return nil, err + } + externalSignature.PublicKey = publicKey + externalSignature.Signature = sb.ExternalSignature.Signature + + block.ExternalSignature = externalSignature + } + //authority.Version = container.Authority.Version + + blocks[i] = *block + } + + var proofAlgorithm Algorithm + if len(blocks) == 0 { + proofAlgorithm = authority.NextKey.Algorithm() + } else { + proofAlgorithm = blocks[len(blocks)-1].NextKey.Algorithm() + } + + var proof TokenNext + if container.Proof.GetNextSecret() != nil { + + switch proofAlgorithm { + case AlgorithmEd25519: + privateKey := &Ed25519PrivateKey{Key: container.Proof.GetNextSecret()} + proof = &SecretTokenNext{Key: privateKey} + default: + return nil, fmt.Errorf("biscuit: unsupported public key algorithm: %v", proofAlgorithm) + } + } else if container.Proof.GetFinalSignature() != nil { + proof = &SealTokenNext{Signature: container.Proof.GetFinalSignature()} + } else { + return nil, fmt.Errorf("biscuit: invalid proof") + } + + return &SerializedBiscuit{ + Authority: *authority, + Blocks: blocks, + Proof: proof, + }, nil +} + type BlockBuilder interface { AddBlock(block ParsedBlock) error AddFact(fact Fact) error @@ -224,7 +294,7 @@ type BlockBuilder interface { type blockBuilder struct { symbolsStart int symbols *datalog.SymbolTable - facts *datalog.FactSet + facts []datalog.Fact rules []datalog.Rule checks []datalog.Check context string @@ -236,7 +306,6 @@ func NewBlockBuilder(baseSymbols *datalog.SymbolTable) BlockBuilder { return &blockBuilder{ symbolsStart: baseSymbols.Len(), symbols: baseSymbols, - facts: new(datalog.FactSet), } } @@ -265,9 +334,7 @@ func (b *blockBuilder) AddBlock(block ParsedBlock) error { func (b *blockBuilder) AddFact(fact Fact) error { dlFact := fact.convert(b.symbols) - if !b.facts.Insert(dlFact) { - return ErrDuplicateFact - } + b.facts = append(b.facts, dlFact) return nil } @@ -293,8 +360,8 @@ func (b *blockBuilder) SetContext(context string) { func (b *blockBuilder) Build() *Block { b.symbols = b.symbols.SplitOff(b.symbolsStart) - facts := make(datalog.FactSet, len(*b.facts)) - copy(facts, *b.facts) + facts := make([]datalog.Fact, len(b.facts)) + copy(facts, b.facts) rules := make([]datalog.Rule, len(b.rules)) copy(rules, b.rules) @@ -304,7 +371,7 @@ func (b *blockBuilder) Build() *Block { return &Block{ symbols: b.symbols.Clone(), - facts: &facts, + facts: facts, rules: rules, checks: checks, context: b.context, diff --git a/converters.go b/converters.go index f8a9abdb..62866df1 100644 --- a/converters.go +++ b/converters.go @@ -13,17 +13,17 @@ import ( func tokenBlockToProtoBlock(input *Block) (*pb.Block, error) { out := &pb.Block{ - Symbols: *input.symbols, + Symbols: input.symbols.Symbols, Context: proto.String(input.context), Version: proto.Uint32(input.version), } facts := input.facts if facts != nil { - out.FactsV2 = make([]*pb.FactV2, len(*facts)) + out.Facts = make([]*pb.Fact, len(facts)) var err error - for i, fact := range *facts { - out.FactsV2[i], err = tokenFactToProtoFactV2(fact) + for i, fact := range facts { + out.Facts[i], err = tokenFactToProtoFact(fact) if err != nil { return nil, err } @@ -32,25 +32,25 @@ func tokenBlockToProtoBlock(input *Block) (*pb.Block, error) { rules := input.rules if rules != nil { - out.RulesV2 = make([]*pb.RuleV2, len(rules)) + out.Rules = make([]*pb.Rule, len(rules)) for i, rule := range rules { - r, err := tokenRuleToProtoRuleV2(rule) + r, err := tokenRuleToProtoRule(rule) if err != nil { return nil, err } - out.RulesV2[i] = r + out.Rules[i] = r } } checks := input.checks if checks != nil { - out.ChecksV2 = make([]*pb.CheckV2, len(checks)) + out.Checks = make([]*pb.Check, len(checks)) for i, check := range checks { - c, err := tokenCheckToProtoCheckV2(check) + c, err := tokenCheckToProtoCheck(check) if err != nil { return nil, err } - out.ChecksV2[i] = c + out.Checks[i] = c } } @@ -58,63 +58,68 @@ func tokenBlockToProtoBlock(input *Block) (*pb.Block, error) { } func protoBlockToTokenBlock(input *pb.Block) (*Block, error) { - symbols := datalog.SymbolTable(input.Symbols) + symbols := datalog.SymbolTable{Symbols: input.Symbols} - var facts datalog.FactSet + var facts []datalog.Fact var rules []datalog.Rule var checks []datalog.Check - if input.GetVersion() < MinSchemaVersion { + var version uint32 = input.GetVersion() + + if version < MinSchemaVersion { return nil, fmt.Errorf( "biscuit: failed to convert proto block to token block: block version: %d < library version %d", - input.GetVersion(), + version, MinSchemaVersion, ) } - if input.GetVersion() > MaxSchemaVersion { + if version > MaxSchemaVersion { return nil, fmt.Errorf( "biscuit: failed to convert proto block to token block: block version: %d > library version %d", - input.GetVersion(), + version, MaxSchemaVersion, ) } - switch input.GetVersion() { - case 3: - facts = make(datalog.FactSet, len(input.FactsV2)) - rules = make([]datalog.Rule, len(input.RulesV2)) - checks = make([]datalog.Check, len(input.ChecksV2)) + facts = make([]datalog.Fact, len(input.Facts)) + rules = make([]datalog.Rule, len(input.Rules)) + checks = make([]datalog.Check, len(input.Checks)) - for i, pbFact := range input.FactsV2 { - f, err := protoFactToTokenFactV2(pbFact) - if err != nil { - return nil, err - } - facts[i] = *f + for i, pbFact := range input.Facts { + f, err := protoFactToTokenFact(pbFact) + if err != nil { + return nil, err } + facts[i] = *f + } - for i, pbRule := range input.RulesV2 { - r, err := protoRuleToTokenRuleV2(pbRule) - if err != nil { - return nil, err - } - rules[i] = *r + for i, pbRule := range input.Rules { + r, err := protoRuleToTokenRule(pbRule) + if err != nil { + return nil, err } + rules[i] = *r + } - for i, pbCheck := range input.ChecksV2 { - c, err := protoCheckToTokenCheckV2(pbCheck) - if err != nil { - return nil, err - } - checks[i] = *c + for i, pbCheck := range input.Checks { + if version < Datalog31 && pbCheck.Kind != nil { + return nil, fmt.Errorf("deserialization error: check kinds are only supported on datalog v3.1+ blocks") + } + + if version < Datalog33 && pbCheck.Kind != nil && *pbCheck.Kind == pb.Check_Reject { + return nil, fmt.Errorf("deserialization error: reject if checks are only supported on datalog v3.3+ blocks") + } + + c, err := protoCheckToTokenCheck(pbCheck) + if err != nil { + return nil, err } - default: - return nil, fmt.Errorf("biscuit: failed to convert proto block to token block: unsupported version: %d", input.GetVersion()) + checks[i] = *c } return &Block{ symbols: &symbols, - facts: &facts, + facts: facts, rules: rules, checks: checks, context: input.GetContext(), diff --git a/converters_v2.go b/converters_v2.go index 431b5ed7..e0a84be8 100644 --- a/converters_v2.go +++ b/converters_v2.go @@ -12,19 +12,19 @@ import ( "github.com/biscuit-auth/biscuit-go/v2/pb" ) -func tokenFactToProtoFactV2(input datalog.Fact) (*pb.FactV2, error) { - pred, err := tokenPredicateToProtoPredicateV2(input.Predicate) +func tokenFactToProtoFact(input datalog.Fact) (*pb.Fact, error) { + pred, err := tokenPredicateToProtoPredicate(input.Predicate) if err != nil { return nil, err } - return &pb.FactV2{ + return &pb.Fact{ Predicate: pred, }, nil } -func protoFactToTokenFactV2(input *pb.FactV2) (*datalog.Fact, error) { - pred, err := protoPredicateToTokenPredicateV2(input.Predicate) +func protoFactToTokenFact(input *pb.Fact) (*datalog.Fact, error) { + pred, err := protoPredicateToTokenPredicate(input.Predicate) if err != nil { return nil, err } @@ -33,27 +33,27 @@ func protoFactToTokenFactV2(input *pb.FactV2) (*datalog.Fact, error) { }, nil } -func tokenPredicateToProtoPredicateV2(input datalog.Predicate) (*pb.PredicateV2, error) { - pbTerms := make([]*pb.TermV2, len(input.Terms)) +func tokenPredicateToProtoPredicate(input datalog.Predicate) (*pb.Predicate, error) { + pbTerms := make([]*pb.Term, len(input.Terms)) var err error for i, id := range input.Terms { - pbTerms[i], err = tokenIDToProtoIDV2(id) + pbTerms[i], err = tokenTermToProtoTerm(id) if err != nil { return nil, err } } nameSymbol := uint64(input.Name) - return &pb.PredicateV2{ + return &pb.Predicate{ Name: &nameSymbol, Terms: pbTerms, }, nil } -func protoPredicateToTokenPredicateV2(input *pb.PredicateV2) (*datalog.Predicate, error) { +func protoPredicateToTokenPredicate(input *pb.Predicate) (*datalog.Predicate, error) { Terms := make([]datalog.Term, len(input.Terms)) for i, id := range input.Terms { - dlid, err := protoIDToTokenIDV2(id) + dlid, err := protoTermToTokenTerm(id) if err != nil { return nil, err } @@ -68,66 +68,65 @@ func protoPredicateToTokenPredicateV2(input *pb.PredicateV2) (*datalog.Predicate }, nil } -func tokenIDToProtoIDV2(input datalog.Term) (*pb.TermV2, error) { - var pbId *pb.TermV2 +func tokenTermToProtoTerm(input datalog.Term) (*pb.Term, error) { + var pbId *pb.Term switch input.Type() { case datalog.TermTypeString: - pbId = &pb.TermV2{ - Content: &pb.TermV2_String_{String_: uint64(input.(datalog.String))}, + pbId = &pb.Term{ + Content: &pb.Term_String_{String_: uint64(input.(datalog.String))}, } case datalog.TermTypeDate: - pbId = &pb.TermV2{ - Content: &pb.TermV2_Date{Date: uint64(input.(datalog.Date))}, + pbId = &pb.Term{ + Content: &pb.Term_Date{Date: uint64(input.(datalog.Date))}, } case datalog.TermTypeInteger: - pbId = &pb.TermV2{ - Content: &pb.TermV2_Integer{Integer: int64(input.(datalog.Integer))}, + pbId = &pb.Term{ + Content: &pb.Term_Integer{Integer: int64(input.(datalog.Integer))}, } case datalog.TermTypeVariable: - pbId = &pb.TermV2{ - Content: &pb.TermV2_Variable{Variable: uint32(input.(datalog.Variable))}, + pbId = &pb.Term{ + Content: &pb.Term_Variable{Variable: uint32(input.(datalog.Variable))}, } case datalog.TermTypeBytes: - pbId = &pb.TermV2{ - Content: &pb.TermV2_Bytes{Bytes: input.(datalog.Bytes)}, + pbId = &pb.Term{ + Content: &pb.Term_Bytes{Bytes: input.(datalog.Bytes)}, } case datalog.TermTypeBool: - pbId = &pb.TermV2{ - Content: &pb.TermV2_Bool{Bool: bool(input.(datalog.Bool))}, + pbId = &pb.Term{ + Content: &pb.Term_Bool{Bool: bool(input.(datalog.Bool))}, } case datalog.TermTypeSet: - datalogSet := input.(datalog.Set) - if len(datalogSet) == 0 { - return nil, errors.New("biscuit: failed to convert token ID to proto ID: set cannot be empty") - } - - expectedEltType := datalogSet[0].Type() - switch expectedEltType { - case datalog.TermTypeVariable: - return nil, errors.New("biscuit: failed to convert token ID to proto ID: set cannot contains variable") - case datalog.TermTypeSet: - return nil, errors.New("biscuit: failed to convert token ID to proto ID: set cannot contains other sets") - } - - protoSet := make([]*pb.TermV2, 0, len(datalogSet)) - for _, datalogElt := range datalogSet { - if datalogElt.Type() != expectedEltType { - return nil, fmt.Errorf( - "biscuit: failed to convert token ID to proto ID: set elements must have the same type (got %x, want %x)", - datalogElt.Type(), - expectedEltType, - ) + datalogSet := input.(datalog.TermSet) + protoSet := make([]*pb.Term, 0, len(datalogSet)) + + if len(datalogSet) > 0 { + expectedEltType := datalogSet[0].Type() + switch expectedEltType { + case datalog.TermTypeVariable: + return nil, errors.New("biscuit: failed to convert token ID to proto ID: set cannot contains variable") + case datalog.TermTypeSet: + return nil, errors.New("biscuit: failed to convert token ID to proto ID: set cannot contains other sets") } - protoElt, err := tokenIDToProtoIDV2(datalogElt) - if err != nil { - return nil, err + for _, datalogElt := range datalogSet { + if datalogElt.Type() != expectedEltType { + return nil, fmt.Errorf( + "biscuit: failed to convert token ID to proto ID: set elements must have the same type (got %x, want %x)", + datalogElt.Type(), + expectedEltType, + ) + } + + protoElt, err := tokenTermToProtoTerm(datalogElt) + if err != nil { + return nil, err + } + + protoSet = append(protoSet, protoElt) } - - protoSet = append(protoSet, protoElt) } - pbId = &pb.TermV2{ - Content: &pb.TermV2_Set{ + pbId = &pb.Term{ + Content: &pb.Term_Set{ Set: &pb.TermSet{ Set: protoSet, }, @@ -139,50 +138,49 @@ func tokenIDToProtoIDV2(input datalog.Term) (*pb.TermV2, error) { return pbId, nil } -func protoIDToTokenIDV2(input *pb.TermV2) (*datalog.Term, error) { +func protoTermToTokenTerm(input *pb.Term) (*datalog.Term, error) { var id datalog.Term switch input.Content.(type) { - case *pb.TermV2_String_: + case *pb.Term_String_: id = datalog.String(input.GetString_()) - case *pb.TermV2_Date: + case *pb.Term_Date: id = datalog.Date(input.GetDate()) - case *pb.TermV2_Integer: + case *pb.Term_Integer: id = datalog.Integer(input.GetInteger()) - case *pb.TermV2_Variable: + case *pb.Term_Variable: id = datalog.Variable(input.GetVariable()) - case *pb.TermV2_Bytes: + case *pb.Term_Bytes: id = datalog.Bytes(input.GetBytes()) - case *pb.TermV2_Bool: + case *pb.Term_Bool: id = datalog.Bool(input.GetBool()) - case *pb.TermV2_Set: + case *pb.Term_Set: elts := input.GetSet().Set - if len(elts) == 0 { - return nil, errors.New("biscuit: failed to convert proto ID to token ID: set cannot be empty") - } - - expectedEltType := reflect.TypeOf(elts[0].GetContent()) - switch expectedEltType { - case reflect.TypeOf(&pb.TermV2_Variable{}): - return nil, errors.New("biscuit: failed to convert proto ID to token ID: set cannot contains variable") - case reflect.TypeOf(&pb.TermV2_Set{}): - return nil, errors.New("biscuit: failed to convert proto ID to token ID: set cannot contains other sets") - } - - datalogSet := make(datalog.Set, 0, len(elts)) - for _, protoElt := range elts { - if eltType := reflect.TypeOf(protoElt.GetContent()); eltType != expectedEltType { - return nil, fmt.Errorf( - "biscuit: failed to convert proto ID to token ID: set elements must have the same type (got %x, want %x)", - eltType, - expectedEltType, - ) + datalogSet := make(datalog.TermSet, 0, len(elts)) + + if len(elts) > 0 { + expectedEltType := reflect.TypeOf(elts[0].GetContent()) + switch expectedEltType { + case reflect.TypeOf(&pb.Term_Variable{}): + return nil, errors.New("biscuit: failed to convert proto ID to token ID: set cannot contains variable") + case reflect.TypeOf(&pb.Term_Set{}): + return nil, errors.New("biscuit: failed to convert proto ID to token ID: set cannot contains other sets") } - datalogElt, err := protoIDToTokenIDV2(protoElt) - if err != nil { - return nil, err + for _, protoElt := range elts { + if eltType := reflect.TypeOf(protoElt.GetContent()); eltType != expectedEltType { + return nil, fmt.Errorf( + "biscuit: failed to convert proto ID to token ID: set elements must have the same type (got %x, want %x)", + eltType, + expectedEltType, + ) + } + + datalogElt, err := protoTermToTokenTerm(protoElt) + if err != nil { + return nil, err + } + datalogSet = append(datalogSet, *datalogElt) } - datalogSet = append(datalogSet, *datalogElt) } id = datalogSet default: @@ -192,41 +190,41 @@ func protoIDToTokenIDV2(input *pb.TermV2) (*datalog.Term, error) { return &id, nil } -func tokenRuleToProtoRuleV2(input datalog.Rule) (*pb.RuleV2, error) { - pbBody := make([]*pb.PredicateV2, len(input.Body)) +func tokenRuleToProtoRule(input datalog.Rule) (*pb.Rule, error) { + pbBody := make([]*pb.Predicate, len(input.Body)) for i, p := range input.Body { - pred, err := tokenPredicateToProtoPredicateV2(p) + pred, err := tokenPredicateToProtoPredicate(p) if err != nil { return nil, err } pbBody[i] = pred } - pbExpressions := make([]*pb.ExpressionV2, len(input.Expressions)) + pbExpressions := make([]*pb.Expression, len(input.Expressions)) for i, e := range input.Expressions { - expr, err := tokenExpressionToProtoExpressionV2(e) + expr, err := tokenExpressionToProtoExpression(e) if err != nil { return nil, err } pbExpressions[i] = expr } - pbHead, err := tokenPredicateToProtoPredicateV2(input.Head) + pbHead, err := tokenPredicateToProtoPredicate(input.Head) if err != nil { return nil, err } - return &pb.RuleV2{ + return &pb.Rule{ Head: pbHead, Body: pbBody, Expressions: pbExpressions, }, nil } -func protoRuleToTokenRuleV2(input *pb.RuleV2) (*datalog.Rule, error) { +func protoRuleToTokenRule(input *pb.Rule) (*datalog.Rule, error) { body := make([]datalog.Predicate, len(input.Body)) for i, pb := range input.Body { - b, err := protoPredicateToTokenPredicateV2(pb) + b, err := protoPredicateToTokenPredicate(pb) if err != nil { return nil, err } @@ -235,14 +233,14 @@ func protoRuleToTokenRuleV2(input *pb.RuleV2) (*datalog.Rule, error) { expressions := make([]datalog.Expression, len(input.Expressions)) for i, pbExpression := range input.Expressions { - e, err := protoExpressionToTokenExpressionV2(pbExpression) + e, err := protoExpressionToTokenExpression(pbExpression) if err != nil { return nil, err } expressions[i] = e } - head, err := protoPredicateToTokenPredicateV2(input.Head) + head, err := protoPredicateToTokenPredicate(input.Head) if err != nil { return nil, err } @@ -253,15 +251,15 @@ func protoRuleToTokenRuleV2(input *pb.RuleV2) (*datalog.Rule, error) { }, nil } -func tokenExpressionToProtoExpressionV2(input datalog.Expression) (*pb.ExpressionV2, error) { - pbExpr := &pb.ExpressionV2{ +func tokenExpressionToProtoExpression(input datalog.Expression) (*pb.Expression, error) { + pbExpr := &pb.Expression{ Ops: make([]*pb.Op, len(input)), } for i, op := range input { switch op.Type() { case datalog.OpTypeValue: - pbID, err := tokenIDToProtoIDV2(op.(datalog.Value).ID) + pbID, err := tokenTermToProtoTerm(op.(datalog.Value).ID) if err != nil { return nil, err } @@ -285,12 +283,12 @@ func tokenExpressionToProtoExpressionV2(input datalog.Expression) (*pb.Expressio return pbExpr, nil } -func protoExpressionToTokenExpressionV2(input *pb.ExpressionV2) (datalog.Expression, error) { +func protoExpressionToTokenExpression(input *pb.Expression) (datalog.Expression, error) { expr := make(datalog.Expression, len(input.Ops)) for i, op := range input.Ops { switch op.Content.(type) { case *pb.Op_Value: - id, err := protoIDToTokenIDV2(op.GetValue()) + id, err := protoTermToTokenTerm(op.GetValue()) if err != nil { return nil, err } @@ -356,7 +354,13 @@ func tokenExprBinaryToProtoExprBinary(op datalog.BinaryOp) (*pb.OpBinary, error) case datalog.BinaryGreaterOrEqual: pbBinaryKind = pb.OpBinary_GreaterOrEqual case datalog.BinaryEqual: + pbBinaryKind = pb.OpBinary_HeterogeneousEqual + case datalog.BinaryNotEqual: + pbBinaryKind = pb.OpBinary_HeterogeneousNotEqual + case datalog.BinaryStrictEqual: pbBinaryKind = pb.OpBinary_Equal + case datalog.BinaryStrictNotEqual: + pbBinaryKind = pb.OpBinary_NotEqual case datalog.BinaryContains: pbBinaryKind = pb.OpBinary_Contains case datalog.BinaryPrefix: @@ -399,7 +403,13 @@ func protoExprBinaryToTokenExprBinary(op *pb.OpBinary) (datalog.BinaryOpFunc, er case pb.OpBinary_GreaterOrEqual: binaryOp = datalog.GreaterOrEqual{} case pb.OpBinary_Equal: + binaryOp = datalog.StrictEqual{} + case pb.OpBinary_NotEqual: + binaryOp = datalog.StrictNotEqual{} + case pb.OpBinary_HeterogeneousEqual: binaryOp = datalog.Equal{} + case pb.OpBinary_HeterogeneousNotEqual: + binaryOp = datalog.NotEqual{} case pb.OpBinary_Contains: binaryOp = datalog.Contains{} case pb.OpBinary_Prefix: @@ -430,32 +440,84 @@ func protoExprBinaryToTokenExprBinary(op *pb.OpBinary) (datalog.BinaryOpFunc, er return binaryOp, nil } -func tokenCheckToProtoCheckV2(input datalog.Check) (*pb.CheckV2, error) { - pbQueries := make([]*pb.RuleV2, len(input.Queries)) +func tokenCheckToProtoCheck(input datalog.Check) (*pb.Check, error) { + pbQueries := make([]*pb.Rule, len(input.Queries)) for i, query := range input.Queries { - q, err := tokenRuleToProtoRuleV2(query) + q, err := tokenRuleToProtoRule(query) if err != nil { return nil, err } pbQueries[i] = q } - return &pb.CheckV2{ + var kind pb.Check_Kind + switch input.Kind { + case datalog.CheckKindOne: + kind = pb.Check_One + case datalog.CheckKindAll: + kind = pb.Check_All + case datalog.CheckKindReject: + kind = pb.Check_Reject + default: + return nil, fmt.Errorf("deserialization error: invalid check kind: %v", input.Kind) + } + + return &pb.Check{ Queries: pbQueries, + Kind: &kind, }, nil } -func protoCheckToTokenCheckV2(input *pb.CheckV2) (*datalog.Check, error) { +func protoCheckToTokenCheck(input *pb.Check) (*datalog.Check, error) { queries := make([]datalog.Rule, len(input.Queries)) for i, query := range input.Queries { - q, err := protoRuleToTokenRuleV2(query) + q, err := protoRuleToTokenRule(query) if err != nil { return nil, err } queries[i] = *q } + var kind datalog.CheckKind + if input.Kind == nil { + kind = datalog.CheckKindOne + } else { + switch *input.Kind { + case pb.Check_One: + kind = datalog.CheckKindOne + case pb.Check_All: + kind = datalog.CheckKindAll + case pb.Check_Reject: + kind = datalog.CheckKindReject + default: + return nil, fmt.Errorf("deserialization error: invalid check kind: %v", input.Kind) + } + } + return &datalog.Check{ Queries: queries, + Kind: kind, }, nil } + +func protoPublicKeyToTokenPublicKey(input *pb.PublicKey) (PublicKey, error) { + switch *input.Algorithm { + case pb.PublicKey_Ed25519: + if len(input.Key) != 32 { + return nil, ErrInvalidKeySize + } + return Ed25519PublicKeyDeserialize(input.Key) + default: + return nil, fmt.Errorf("biscuit: unsupported public key algorithm: %v", input.Algorithm) + } +} + +func tokenPublicKeyToProtoPublicKey(input PublicKey) (*pb.PublicKey, error) { + switch input.Algorithm() { + case AlgorithmEd25519: + algorithm := pb.PublicKey_Ed25519 + return &pb.PublicKey{Algorithm: &algorithm, Key: input.Serialize()}, nil + default: + return nil, fmt.Errorf("biscuit: unsupported public key algorithm: %v", input.Algorithm()) + } +} diff --git a/converters_v2_test.go b/converters_v2_test.go index 7c01633e..a2d8c275 100644 --- a/converters_v2_test.go +++ b/converters_v2_test.go @@ -14,14 +14,14 @@ import ( "google.golang.org/protobuf/proto" ) -func TestExpressionConvertV2(t *testing.T) { +func TestExpressionConvert(t *testing.T) { now := time.Now() syms := &datalog.SymbolTable{} testCases := []struct { Desc string Input datalog.Expression - Expected *pb.ExpressionV2 + Expected *pb.Expression }{ { Desc: "date comparison after", @@ -30,10 +30,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Date(now.Unix())}, datalog.BinaryOp{BinaryOpFunc: datalog.GreaterOrEqual{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 1}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Date{Date: uint64(now.Unix())}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 1}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Date{Date: uint64(now.Unix())}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_GreaterOrEqual.Enum()}}}, }, }, @@ -45,10 +45,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Date(123456789)}, datalog.BinaryOp{BinaryOpFunc: datalog.LessOrEqual{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 2}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Date{Date: uint64(123456789)}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 2}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Date{Date: uint64(123456789)}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_LessOrEqual.Enum()}}}, }, }, @@ -60,10 +60,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(42)}, datalog.BinaryOp{BinaryOpFunc: datalog.Equal{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 3}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 42}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 3}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 42}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Equal.Enum()}}}, }, }, @@ -75,10 +75,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(-42)}, datalog.BinaryOp{BinaryOpFunc: datalog.GreaterThan{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 4}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: -42}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 4}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: -42}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_GreaterThan.Enum()}}}, }, }, @@ -90,10 +90,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(43)}, datalog.BinaryOp{BinaryOpFunc: datalog.GreaterOrEqual{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 5}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 43}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 5}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 43}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_GreaterOrEqual.Enum()}}}, }, }, @@ -105,10 +105,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(0)}, datalog.BinaryOp{BinaryOpFunc: datalog.LessThan{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 6}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 0}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 6}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 0}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_LessThan.Enum()}}}, }, }, @@ -120,10 +120,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(math.MaxInt64)}, datalog.BinaryOp{BinaryOpFunc: datalog.LessOrEqual{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 7}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: math.MaxInt64}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 7}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: math.MaxInt64}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_LessOrEqual.Enum()}}}, }, }, @@ -131,18 +131,18 @@ func TestExpressionConvertV2(t *testing.T) { { Desc: "int comparison in", Input: datalog.Expression{ - datalog.Value{ID: datalog.Set{datalog.Integer(1), datalog.Integer(2), datalog.Integer(3)}}, + datalog.Value{ID: datalog.TermSet{datalog.Integer(1), datalog.Integer(2), datalog.Integer(3)}}, datalog.Value{ID: datalog.Variable(8)}, datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_Integer{Integer: 1}}, - {Content: &pb.TermV2_Integer{Integer: 2}}, - {Content: &pb.TermV2_Integer{Integer: 3}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_Integer{Integer: 1}}, + {Content: &pb.Term_Integer{Integer: 2}}, + {Content: &pb.Term_Integer{Integer: 3}}, }}}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 8}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 8}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Contains.Enum()}}}, }, }, @@ -150,19 +150,19 @@ func TestExpressionConvertV2(t *testing.T) { { Desc: "int comparison not in", Input: datalog.Expression{ - datalog.Value{ID: datalog.Set{datalog.Integer(1), datalog.Integer(2), datalog.Integer(3)}}, + datalog.Value{ID: datalog.TermSet{datalog.Integer(1), datalog.Integer(2), datalog.Integer(3)}}, datalog.Value{ID: datalog.Variable(9)}, datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}}, datalog.UnaryOp{UnaryOpFunc: datalog.Negate{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_Integer{Integer: 1}}, - {Content: &pb.TermV2_Integer{Integer: 2}}, - {Content: &pb.TermV2_Integer{Integer: 3}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_Integer{Integer: 1}}, + {Content: &pb.Term_Integer{Integer: 2}}, + {Content: &pb.Term_Integer{Integer: 3}}, }}}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 9}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 9}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Contains.Enum()}}}, {Content: &pb.Op_Unary{Unary: &pb.OpUnary{Kind: pb.OpUnary_Negate.Enum()}}}, }, @@ -176,10 +176,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: syms.Insert("abcd")}, datalog.BinaryOp{BinaryOpFunc: datalog.Equal{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 10}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_String_{String_: syms.Index("abcd")}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 10}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_String_{String_: syms.Index("abcd")}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Equal.Enum()}}}, }, }, @@ -191,10 +191,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: syms.Insert("abcd")}, datalog.BinaryOp{BinaryOpFunc: datalog.Prefix{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 11}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_String_{String_: syms.Index("abcd")}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 11}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_String_{String_: syms.Index("abcd")}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Prefix.Enum()}}}, }, }, @@ -206,10 +206,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: syms.Insert("abcd")}, datalog.BinaryOp{BinaryOpFunc: datalog.Suffix{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 12}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_String_{String_: syms.Index("abcd")}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 12}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_String_{String_: syms.Index("abcd")}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Suffix.Enum()}}}, }, }, @@ -217,18 +217,18 @@ func TestExpressionConvertV2(t *testing.T) { { Desc: "string comparison in", Input: datalog.Expression{ - datalog.Value{ID: datalog.Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}}, + datalog.Value{ID: datalog.TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}}, datalog.Value{ID: datalog.Variable(13)}, datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: syms.Index("a")}}, - {Content: &pb.TermV2_String_{String_: syms.Index("b")}}, - {Content: &pb.TermV2_String_{String_: syms.Index("c")}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_String_{String_: syms.Index("a")}}, + {Content: &pb.Term_String_{String_: syms.Index("b")}}, + {Content: &pb.Term_String_{String_: syms.Index("c")}}, }}}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 13}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 13}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Contains.Enum()}}}, }, }, @@ -236,19 +236,19 @@ func TestExpressionConvertV2(t *testing.T) { { Desc: "string comparison not in", Input: datalog.Expression{ - datalog.Value{ID: datalog.Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}}, + datalog.Value{ID: datalog.TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}}, datalog.Value{ID: datalog.Variable(14)}, datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}}, datalog.UnaryOp{UnaryOpFunc: datalog.Negate{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: syms.Index("a")}}, - {Content: &pb.TermV2_String_{String_: syms.Index("b")}}, - {Content: &pb.TermV2_String_{String_: syms.Index("c")}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_String_{String_: syms.Index("a")}}, + {Content: &pb.Term_String_{String_: syms.Index("b")}}, + {Content: &pb.Term_String_{String_: syms.Index("c")}}, }}}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 14}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 14}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Contains.Enum()}}}, {Content: &pb.Op_Unary{Unary: &pb.OpUnary{Kind: pb.OpUnary_Negate.Enum()}}}, }, @@ -261,10 +261,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: syms.Insert("abcd")}, datalog.BinaryOp{BinaryOpFunc: datalog.Regex{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 15}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_String_{String_: syms.Index("abcd")}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 15}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_String_{String_: syms.Index("abcd")}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Regex.Enum()}}}, }, }, @@ -276,10 +276,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Bytes("abcd")}, datalog.BinaryOp{BinaryOpFunc: datalog.Equal{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 16}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Bytes{Bytes: []byte("abcd")}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 16}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Bytes{Bytes: []byte("abcd")}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Equal.Enum()}}}, }, }, @@ -287,18 +287,18 @@ func TestExpressionConvertV2(t *testing.T) { { Desc: "bytes in", Input: datalog.Expression{ - datalog.Value{ID: datalog.Set{datalog.Bytes("a"), datalog.Bytes("b"), datalog.Bytes("c")}}, + datalog.Value{ID: datalog.TermSet{datalog.Bytes("a"), datalog.Bytes("b"), datalog.Bytes("c")}}, datalog.Value{ID: datalog.Variable(17)}, datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_Bytes{Bytes: []byte("a")}}, - {Content: &pb.TermV2_Bytes{Bytes: []byte("b")}}, - {Content: &pb.TermV2_Bytes{Bytes: []byte("c")}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_Bytes{Bytes: []byte("a")}}, + {Content: &pb.Term_Bytes{Bytes: []byte("b")}}, + {Content: &pb.Term_Bytes{Bytes: []byte("c")}}, }}}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 17}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 17}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Contains.Enum()}}}, }, }, @@ -306,19 +306,19 @@ func TestExpressionConvertV2(t *testing.T) { { Desc: "bytes not in", Input: datalog.Expression{ - datalog.Value{ID: datalog.Set{datalog.Bytes("a"), datalog.Bytes("b"), datalog.Bytes("c")}}, + datalog.Value{ID: datalog.TermSet{datalog.Bytes("a"), datalog.Bytes("b"), datalog.Bytes("c")}}, datalog.Value{ID: datalog.Variable(18)}, datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}}, datalog.UnaryOp{UnaryOpFunc: datalog.Negate{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_Bytes{Bytes: []byte("a")}}, - {Content: &pb.TermV2_Bytes{Bytes: []byte("b")}}, - {Content: &pb.TermV2_Bytes{Bytes: []byte("c")}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_Bytes{Bytes: []byte("a")}}, + {Content: &pb.Term_Bytes{Bytes: []byte("b")}}, + {Content: &pb.Term_Bytes{Bytes: []byte("c")}}, }}}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 18}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 18}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Contains.Enum()}}}, {Content: &pb.Op_Unary{Unary: &pb.OpUnary{Kind: pb.OpUnary_Negate.Enum()}}}, }, @@ -327,18 +327,18 @@ func TestExpressionConvertV2(t *testing.T) { { Desc: "symbols in", Input: datalog.Expression{ - datalog.Value{ID: datalog.Set{datalog.String(1), datalog.String(2), datalog.String(3)}}, + datalog.Value{ID: datalog.TermSet{datalog.String(1), datalog.String(2), datalog.String(3)}}, datalog.Value{ID: datalog.Variable(19)}, datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: 1}}, - {Content: &pb.TermV2_String_{String_: 2}}, - {Content: &pb.TermV2_String_{String_: 3}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_String_{String_: 1}}, + {Content: &pb.Term_String_{String_: 2}}, + {Content: &pb.Term_String_{String_: 3}}, }}}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 19}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 19}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Contains.Enum()}}}, }, }, @@ -346,19 +346,19 @@ func TestExpressionConvertV2(t *testing.T) { { Desc: "symbols not in", Input: datalog.Expression{ - datalog.Value{ID: datalog.Set{datalog.String(1), datalog.String(2), datalog.String(3)}}, + datalog.Value{ID: datalog.TermSet{datalog.String(1), datalog.String(2), datalog.String(3)}}, datalog.Value{ID: datalog.Variable(20)}, datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}}, datalog.UnaryOp{UnaryOpFunc: datalog.Negate{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: 1}}, - {Content: &pb.TermV2_String_{String_: 2}}, - {Content: &pb.TermV2_String_{String_: 3}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_String_{String_: 1}}, + {Content: &pb.Term_String_{String_: 2}}, + {Content: &pb.Term_String_{String_: 3}}, }}}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 20}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 20}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Contains.Enum()}}}, {Content: &pb.Op_Unary{Unary: &pb.OpUnary{Kind: pb.OpUnary_Negate.Enum()}}}, }, @@ -371,10 +371,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(42)}, datalog.BinaryOp{BinaryOpFunc: datalog.Add{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 21}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 42}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 21}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 42}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Add.Enum()}}}, }, }, @@ -386,10 +386,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(42)}, datalog.BinaryOp{BinaryOpFunc: datalog.Sub{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 22}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 42}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 22}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 42}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Sub.Enum()}}}, }, }, @@ -401,10 +401,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(42)}, datalog.BinaryOp{BinaryOpFunc: datalog.Mul{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 23}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 42}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 23}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 42}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Mul.Enum()}}}, }, }, @@ -416,10 +416,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Integer(42)}, datalog.BinaryOp{BinaryOpFunc: datalog.Div{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 24}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 42}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 24}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 42}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Div.Enum()}}}, }, }, @@ -431,10 +431,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Bool(true)}, datalog.BinaryOp{BinaryOpFunc: datalog.And{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 25}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Bool{Bool: true}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 25}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Bool{Bool: true}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_And.Enum()}}}, }, }, @@ -446,10 +446,10 @@ func TestExpressionConvertV2(t *testing.T) { datalog.Value{ID: datalog.Bool(true)}, datalog.BinaryOp{BinaryOpFunc: datalog.Or{}}, }, - Expected: &pb.ExpressionV2{ + Expected: &pb.Expression{ Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 26}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Bool{Bool: true}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 26}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Bool{Bool: true}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Or.Enum()}}}, }, }, @@ -458,19 +458,19 @@ func TestExpressionConvertV2(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.Desc, func(t *testing.T) { - out, err := tokenExpressionToProtoExpressionV2(testCase.Input) + out, err := tokenExpressionToProtoExpression(testCase.Input) require.NoError(t, err) require.Equal(t, testCase.Expected, out) - dlout, err := protoExpressionToTokenExpressionV2(out) + dlout, err := protoExpressionToTokenExpression(out) require.NoError(t, err) require.Equal(t, testCase.Input, dlout) }) } } -func TestRuleConvertV2(t *testing.T) { +func TestRuleConvert(t *testing.T) { now := time.Now() syms := &datalog.SymbolTable{} @@ -505,49 +505,49 @@ func TestRuleConvertV2(t *testing.T) { name1 := uint64(42) name2 := uint64(43) name3 := uint64(44) - expectedPbRule := &pb.RuleV2{ - Head: &pb.PredicateV2{Name: &name1, Terms: []*pb.TermV2{ - {Content: &pb.TermV2_Integer{Integer: 1}}, - {Content: &pb.TermV2_String_{String_: syms.Index("id_1")}}, + expectedPbRule := &pb.Rule{ + Head: &pb.Predicate{Name: &name1, Terms: []*pb.Term{ + {Content: &pb.Term_Integer{Integer: 1}}, + {Content: &pb.Term_String_{String_: syms.Index("id_1")}}, }}, - Body: []*pb.PredicateV2{ + Body: []*pb.Predicate{ { Name: &name2, - Terms: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: 2}}, - {Content: &pb.TermV2_Date{Date: uint64(now.Unix())}}, + Terms: []*pb.Term{ + {Content: &pb.Term_String_{String_: 2}}, + {Content: &pb.Term_Date{Date: uint64(now.Unix())}}, }, }, { Name: &name3, - Terms: []*pb.TermV2{ - {Content: &pb.TermV2_Bytes{Bytes: []byte("abcd")}}, + Terms: []*pb.Term{ + {Content: &pb.Term_Bytes{Bytes: []byte("abcd")}}, }, }, }, - Expressions: []*pb.ExpressionV2{ + Expressions: []*pb.Expression{ {Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 9}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 42}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 9}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 42}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Equal.Enum()}}}, }}, {Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: 99}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_String_{String_: syms.Index("abcd")}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: 99}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_String_{String_: syms.Index("abcd")}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Prefix.Enum()}}}, }}, }, } - pbRule, err := tokenRuleToProtoRuleV2(*in) + pbRule, err := tokenRuleToProtoRule(*in) require.NoError(t, err) require.Equal(t, expectedPbRule, pbRule) - out, err := protoRuleToTokenRuleV2(pbRule) + out, err := protoRuleToTokenRule(pbRule) require.NoError(t, err) require.Equal(t, in, out) } -func TestFactConvertV2(t *testing.T) { +func TestFactConvert(t *testing.T) { now := time.Now() syms := &datalog.SymbolTable{} @@ -561,7 +561,7 @@ func TestFactConvertV2(t *testing.T) { syms.Insert("abcd"), datalog.Date(now.Unix()), datalog.Bool(true), - datalog.Set{ + datalog.TermSet{ syms.Insert("abc"), syms.Insert("def"), }, @@ -569,28 +569,28 @@ func TestFactConvertV2(t *testing.T) { }} name1 := uint64(42) - expectedPbFact := &pb.FactV2{Predicate: &pb.PredicateV2{ + expectedPbFact := &pb.Fact{Predicate: &pb.Predicate{ Name: &name1, - Terms: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: 1}}, - {Content: &pb.TermV2_Integer{Integer: 2}}, - {Content: &pb.TermV2_Variable{Variable: 3}}, - {Content: &pb.TermV2_Bytes{Bytes: []byte("bytes")}}, - {Content: &pb.TermV2_String_{String_: syms.Index("abcd")}}, - {Content: &pb.TermV2_Date{Date: uint64(now.Unix())}}, - {Content: &pb.TermV2_Bool{Bool: true}}, - {Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: syms.Index("abc")}}, - {Content: &pb.TermV2_String_{String_: syms.Index("def")}}, + Terms: []*pb.Term{ + {Content: &pb.Term_String_{String_: 1}}, + {Content: &pb.Term_Integer{Integer: 2}}, + {Content: &pb.Term_Variable{Variable: 3}}, + {Content: &pb.Term_Bytes{Bytes: []byte("bytes")}}, + {Content: &pb.Term_String_{String_: syms.Index("abcd")}}, + {Content: &pb.Term_Date{Date: uint64(now.Unix())}}, + {Content: &pb.Term_Bool{Bool: true}}, + {Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_String_{String_: syms.Index("abc")}}, + {Content: &pb.Term_String_{String_: syms.Index("def")}}, }}}}, }, }} - pbFact, err := tokenFactToProtoFactV2(*in) + pbFact, err := tokenFactToProtoFact(*in) require.NoError(t, err) require.Equal(t, expectedPbFact, pbFact) - out, err := protoFactToTokenFactV2(pbFact) + out, err := protoFactToTokenFact(pbFact) require.NoError(t, err) require.Equal(t, in, out) } @@ -600,30 +600,30 @@ func TestConvertInvalTermsets(t *testing.T) { tokenTestCases := []struct { desc string - in datalog.Set + in datalog.TermSet }{ { desc: "empty set", - in: datalog.Set{}, + in: datalog.TermSet{}, }, { desc: "mixed element types", - in: datalog.Set{ + in: datalog.TermSet{ syms.Insert("abc"), datalog.Integer(1), }, }, { desc: "set with variables", - in: datalog.Set{ + in: datalog.TermSet{ datalog.Variable(0), datalog.Variable(1), }, }, { desc: "set with sub sets", - in: datalog.Set{ - datalog.Set{ + in: datalog.TermSet{ + datalog.TermSet{ syms.Insert("abc"), syms.Insert("def"), }, @@ -633,37 +633,37 @@ func TestConvertInvalTermsets(t *testing.T) { protoTestCases := []struct { desc string - in *pb.TermV2 + in *pb.Term }{ { desc: "empty set", - in: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{ - Set: []*pb.TermV2{}, + in: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{ + Set: []*pb.Term{}, }}}, }, { desc: "mixed element types", - in: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{ - Set: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: syms.Index("abc")}}, - {Content: &pb.TermV2_Integer{Integer: 0}}, + in: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{ + Set: []*pb.Term{ + {Content: &pb.Term_String_{String_: syms.Index("abc")}}, + {Content: &pb.Term_Integer{Integer: 0}}, }, }}}, }, { desc: "set with variables", - in: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{ - Set: []*pb.TermV2{ - {Content: &pb.TermV2_Variable{Variable: 1}}, + in: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{ + Set: []*pb.Term{ + {Content: &pb.Term_Variable{Variable: 1}}, }, }}}, }, { desc: "set with sub sets", - in: &pb.TermV2{Content: &pb.TermV2_Set{Set: &pb.TermSet{ - Set: []*pb.TermV2{ - {Content: &pb.TermV2_Set{Set: &pb.TermSet{Set: []*pb.TermV2{ - {Content: &pb.TermV2_String_{String_: syms.Index("abc")}}, + in: &pb.Term{Content: &pb.Term_Set{Set: &pb.TermSet{ + Set: []*pb.Term{ + {Content: &pb.Term_Set{Set: &pb.TermSet{Set: []*pb.Term{ + {Content: &pb.Term_String_{String_: syms.Index("abc")}}, }}}}, }, }}}, @@ -672,20 +672,20 @@ func TestConvertInvalTermsets(t *testing.T) { for _, tc := range tokenTestCases { t.Run(tc.desc, func(t *testing.T) { - _, err := tokenIDToProtoIDV2(tc.in) + _, err := tokenTermToProtoTerm(tc.in) require.Error(t, err) }) } for _, tc := range protoTestCases { t.Run(tc.desc, func(t *testing.T) { - _, err := protoIDToTokenIDV2(tc.in) + _, err := protoTermToTokenTerm(tc.in) require.Error(t, err) }) } } -func TestBlockConvertV2(t *testing.T) { +func TestBlockConvert(t *testing.T) { syms := &datalog.SymbolTable{} predicate := datalog.Predicate{ @@ -694,9 +694,9 @@ func TestBlockConvertV2(t *testing.T) { } name1 := uint64(12) - pbPredicate := &pb.PredicateV2{ + pbPredicate := &pb.Predicate{ Name: &name1, - Terms: []*pb.TermV2{{Content: &pb.TermV2_String_{String_: syms.Index("abcd")}}}, + Terms: []*pb.Term{{Content: &pb.Term_String_{String_: syms.Index("abcd")}}}, } rule := &datalog.Rule{ @@ -711,21 +711,21 @@ func TestBlockConvertV2(t *testing.T) { }, } - pbRule := &pb.RuleV2{ + pbRule := &pb.Rule{ Head: pbPredicate, - Body: []*pb.PredicateV2{pbPredicate}, - Expressions: []*pb.ExpressionV2{ + Body: []*pb.Predicate{pbPredicate}, + Expressions: []*pb.Expression{ {Ops: []*pb.Op{ - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Variable{Variable: uint32(datalog.OFFSET + 13)}}}}, - {Content: &pb.Op_Value{Value: &pb.TermV2{Content: &pb.TermV2_Integer{Integer: 1234}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Variable{Variable: uint32(datalog.OFFSET + 13)}}}}, + {Content: &pb.Op_Value{Value: &pb.Term{Content: &pb.Term_Integer{Integer: 1234}}}}, {Content: &pb.Op_Binary{Binary: &pb.OpBinary{Kind: pb.OpBinary_Equal.Enum()}}}, }}, }, } in := &Block{ - symbols: &datalog.SymbolTable{"a", "b", "c", "d"}, - facts: &datalog.FactSet{datalog.Fact{Predicate: predicate}}, + symbols: &datalog.SymbolTable{Symbols: []string{"a", "b", "c", "d"}}, + facts: []datalog.Fact{datalog.Fact{Predicate: predicate}}, rules: []datalog.Rule{*rule}, checks: []datalog.Check{{Queries: []datalog.Rule{*rule}}}, context: "context", @@ -736,13 +736,13 @@ func TestBlockConvertV2(t *testing.T) { version := uint32(3) expectedPbBlock := &pb.Block{ Symbols: []string{"a", "b", "c", "d"}, - FactsV2: []*pb.FactV2{ + Facts: []*pb.Fact{ {Predicate: pbPredicate}, }, - RulesV2: []*pb.RuleV2{pbRule}, - ChecksV2: []*pb.CheckV2{{Queries: []*pb.RuleV2{pbRule}}}, - Context: &ctx, - Version: proto.Uint32(version), + Rules: []*pb.Rule{pbRule}, + Checks: []*pb.Check{{Queries: []*pb.Rule{pbRule}}}, + Context: &ctx, + Version: proto.Uint32(version), } pbBlock, err := tokenBlockToProtoBlock(in) diff --git a/crypto.go b/crypto.go new file mode 100644 index 00000000..5507d3ba --- /dev/null +++ b/crypto.go @@ -0,0 +1,131 @@ +// Copyright (c) 2019 Titanous, daeMOn63 and Contributors to the Eclipse Foundation. +// SPDX-License-Identifier: Apache-2.0 + +package biscuit + +import ( + "crypto/ed25519" + "errors" + "io" +) + +type Algorithm int32 + +const ( + AlgorithmEd25519 Algorithm = 0 +) + +type PublicKey interface { + Algorithm() Algorithm + Verify(message []byte, signature []byte) bool + Serialize() []byte +} + +type PrivateKey interface { + Algorithm() Algorithm + Sign(message []byte) ([]byte, error) + PublicKey() PublicKey +} + +type SerializablePrivateKey interface { + Algorithm() Algorithm + Serialize() []byte +} + +type Ed25519PublicKey struct { + Key ed25519.PublicKey +} + +func (k *Ed25519PublicKey) Algorithm() Algorithm { + return AlgorithmEd25519 +} + +func (k *Ed25519PublicKey) Verify(message []byte, signature []byte) bool { + return ed25519.Verify(k.Key, message, signature) +} + +func (k *Ed25519PublicKey) Serialize() []byte { + return k.Key +} + +func Ed25519PublicKeyDeserialize(data []byte) (*Ed25519PublicKey, error) { + if len(data) != ed25519.PublicKeySize { + return nil, errors.New("invalid public key size") + } + return &Ed25519PublicKey{Key: data}, nil +} + +type Ed25519PrivateKey struct { + Key ed25519.PrivateKey +} + +func (k *Ed25519PrivateKey) Algorithm() Algorithm { + return AlgorithmEd25519 +} + +func (k *Ed25519PrivateKey) Sign(message []byte) ([]byte, error) { + return ed25519.Sign(k.Key, message), nil +} + +func (k *Ed25519PrivateKey) PublicKey() PublicKey { + return &Ed25519PublicKey{Key: k.Key.Public().(ed25519.PublicKey)} +} + +func (k *Ed25519PrivateKey) Serialize() []byte { + return k.Key.Seed() +} + +func Ed25519PrivateKeyDeserialize(data []byte) (*Ed25519PrivateKey, error) { + if len(data) != ed25519.SeedSize { + return nil, errors.New("invalid seed size") + } + return &Ed25519PrivateKey{Key: ed25519.NewKeyFromSeed(data)}, nil +} + +func NewEd25519KeyPair(rng io.Reader) (*Ed25519PublicKey, *Ed25519PrivateKey, error) { + pub, priv, err := ed25519.GenerateKey(rng) + if err != nil { + return nil, nil, err + } + return &Ed25519PublicKey{Key: pub}, &Ed25519PrivateKey{Key: priv}, nil +} + +type CryptoBlock struct { + Data []byte + NextKey PublicKey + Signature []byte + ExternalSignature *ExternalSignature + Version uint32 +} + +type ExternalSignature struct { + PublicKey PublicKey + Signature []byte +} + +type TokenNextType byte + +const ( + TokenNextTypeSecret TokenNextType = iota + TokenNextTypeSeal +) + +type TokenNext interface { + Type() TokenNextType +} + +type SecretTokenNext struct { + Key PrivateKey +} + +func (t *SecretTokenNext) Type() TokenNextType { + return TokenNextTypeSecret +} + +type SealTokenNext struct { + Signature []byte +} + +func (t *SealTokenNext) Type() TokenNextType { + return TokenNextTypeSeal +} diff --git a/datalog/datalog.go b/datalog/datalog.go index d6190120..4c1fe7cf 100644 --- a/datalog/datalog.go +++ b/datalog/datalog.go @@ -32,11 +32,11 @@ type Term interface { String() string } -type Set []Term +type TermSet []Term -func (Set) Type() TermType { return TermTypeSet } -func (s Set) Equal(t Term) bool { - c, ok := t.(Set) +func (TermSet) Type() TermType { return TermTypeSet } +func (s TermSet) Equal(t Term) bool { + c, ok := t.(TermSet) if !ok || len(c) != len(s) { return false } @@ -53,7 +53,7 @@ func (s Set) Equal(t Term) bool { } return true } -func (s Set) String() string { +func (s TermSet) String() string { eltStr := make([]string, 0, len(s)) for _, e := range s { eltStr = append(eltStr, e.String()) @@ -61,13 +61,13 @@ func (s Set) String() string { sort.Strings(eltStr) return fmt.Sprintf("[%s]", strings.Join(eltStr, ", ")) } -func (s Set) Intersect(t Set) Set { +func (s TermSet) Intersect(t TermSet) TermSet { other := make(map[Term]struct{}, len(t)) for _, v := range t { other[v] = struct{}{} } - result := Set{} + result := TermSet{} for _, id := range s { if _, ok := other[id]; ok { @@ -76,13 +76,13 @@ func (s Set) Intersect(t Set) Set { } return result } -func (s Set) Union(t Set) Set { +func (s TermSet) Union(t TermSet) TermSet { this := make(map[Term]struct{}, len(s)) for _, v := range s { this[v] = struct{}{} } - result := Set{} + result := TermSet{} result = append(result, s...) for _, id := range t { @@ -188,21 +188,55 @@ type Fact struct { } type Rule struct { - Head Predicate - Body []Predicate - Expressions []Expression + Head Predicate + Body []Predicate + Expressions []Expression + TrustedScopes []Scope } type InvalidRuleError struct { - Rule Rule - MissingVariable Variable + Rule Rule + MissingVariables []Variable } func (e InvalidRuleError) Error() string { - return fmt.Sprintf("datalog: variable %d in head is missing from body and/or constraints", e.MissingVariable) + return fmt.Sprintf("datalog: variables %v in head are missing from body and/or constraints", e.MissingVariables) } -func (r Rule) Apply(facts *FactSet, newFacts *FactSet, syms *SymbolTable) error { +// ValidateVariables checks that every variable in the rule's head +// also appears in at least one body predicate. +func (r Rule) ValidateVariables() error { + headVars := make(map[Variable]struct{}) + for _, term := range r.Head.Terms { + if v, ok := term.(Variable); ok { + headVars[v] = struct{}{} + } + } + + for _, predicate := range r.Body { + for _, term := range predicate.Terms { + if v, ok := term.(Variable); ok { + delete(headVars, v) + if len(headVars) == 0 { + return nil + } + } + } + } + + if len(headVars) > 0 { + missing := make([]Variable, 0, len(headVars)) + for v := range headVars { + missing = append(missing, v) + } + return InvalidRuleError{Rule: r, MissingVariables: missing} + } + + return nil +} + +func (r Rule) Apply(ruleOrigin uint64, factsIterator *FactIterator, newFacts *OriginFacts, syms *SymbolTable) error { + // extract all variables from the rule body variables := make(MatchedVariables) for _, predicate := range r.Body { @@ -215,13 +249,31 @@ func (r Rule) Apply(facts *FactSet, newFacts *FactSet, syms *SymbolTable) error } } - combinations := combine(variables, r.Body, r.Expressions, facts, syms) + combinations := combine(variables, r.Body, factsIterator, syms) + currentRuleOrigin := MakeOrigin([]uint64{ruleOrigin}) for res := range combinations { + if res.error != nil { return res.error } + valid := true + for _, e := range r.Expressions { + res, err := e.Evaluate(res.MatchedVariables, syms) + if err != nil { + return err + } + if !res.Equal(Bool(true)) { + valid = false + break + } + } + + if !valid { + continue + } + predicate := r.Head.Clone() for i, term := range predicate.Terms { k, ok := term.(Variable) @@ -230,12 +282,13 @@ func (r Rule) Apply(facts *FactSet, newFacts *FactSet, syms *SymbolTable) error } v, ok := res.MatchedVariables[k] if !ok { - return InvalidRuleError{r, k} + return InvalidRuleError{Rule: r, MissingVariables: []Variable{k}} } predicate.Terms[i] = *v } - newFacts.Insert(Fact{predicate}) + newOrigin := res.Origin.Merge(currentRuleOrigin) + newFacts.Insert(newOrigin, Fact{predicate}) } return nil @@ -243,44 +296,16 @@ func (r Rule) Apply(facts *FactSet, newFacts *FactSet, syms *SymbolTable) error type Check struct { Queries []Rule + Kind CheckKind } -type FactSet []Fact - -func (s *FactSet) Insert(f Fact) bool { - for _, v := range *s { - if v.Equal(f.Predicate) { - return false - } - } - *s = append(*s, f) - return true -} +type CheckKind int -func (s *FactSet) InsertAll(facts []Fact) { - for _, f := range facts { - s.Insert(f) - } -} - -func (s *FactSet) Equal(x *FactSet) bool { - if len(*s) != len(*x) { - return false - } - for _, f1 := range *x { - found := false - for _, f2 := range *s { - if f1.Predicate.Equal(f2.Predicate) { - found = true - break - } - } - if !found { - return false - } - } - return true -} +const ( + CheckKindOne CheckKind = iota + CheckKindAll + CheckKindReject +) type runLimits struct { maxFacts int @@ -321,15 +346,15 @@ func WithMaxDuration(maxDuration time.Duration) WorldOption { } type World struct { - facts *FactSet - rules []Rule + facts *OriginFacts + rules OriginRules runLimits runLimits } func NewWorld(opts ...WorldOption) *World { w := &World{ - facts: &FactSet{}, + facts: &OriginFacts{}, runLimits: defaultRunLimits, } @@ -340,23 +365,23 @@ func NewWorld(opts ...WorldOption) *World { return w } -func (w *World) AddFact(f Fact) { - w.facts.Insert(f) +func (w *World) AddFact(origin Origin, f Fact) { + w.facts.Insert(origin, f) } -func (w *World) Facts() *FactSet { +func (w *World) Facts() *OriginFacts { return w.facts } -func (w *World) AddRule(r Rule) { - w.rules = append(w.rules, r) +func (w *World) AddRule(ruleOrigin uint64, scopes TrustedOrigin, r Rule) { + w.rules.Insert(ruleOrigin, scopes, r) } func (w *World) ResetRules() { - w.rules = make([]Rule, 0) + w.rules = OriginRules{} } -func (w *World) Rules() []Rule { +func (w *World) Rules() OriginRules { return w.rules } @@ -371,23 +396,25 @@ func (w *World) Run(syms *SymbolTable) error { case <-ctx.Done(): return default: - var newFacts FactSet - for _, r := range w.rules { - select { - case <-ctx.Done(): - return - default: - if err := r.Apply(w.facts, &newFacts, syms); err != nil { - done <- err + var newFacts OriginFacts + for _, o := range w.rules { + for _, r := range o.Rules { + select { + case <-ctx.Done(): return + default: + factsIterator := w.facts.Iterator(o.TrustedOrigin) + if err := r.Rule.Apply(r.Origin, &factsIterator, &newFacts, syms); err != nil { + done <- err + return + } } } } - prevCount := len(*w.facts) - w.facts.InsertAll([]Fact(newFacts)) - - newCount := len(*w.facts) + prevCount := w.facts.Len() + w.facts.Merge(newFacts) + newCount := w.facts.Len() if newCount >= w.runLimits.maxFacts { done <- ErrWorldRunLimitMaxFacts return @@ -411,52 +438,21 @@ func (w *World) Run(syms *SymbolTable) error { } } -func (w *World) Query(pred Predicate) *FactSet { - res := &FactSet{} - for _, f := range *w.facts { - if f.Predicate.Name != pred.Name { - continue - } - - // if the predicate has a different number of IDs - // the fact must not match - if len(f.Predicate.Terms) != len(pred.Terms) { - continue - } - - matches := true - for i := 0; i < len(pred.Terms); i++ { - fID := f.Predicate.Terms[i] - pID := pred.Terms[i] - - if pID.Type() != TermTypeVariable { - if fID.Type() != pID.Type() || fID != pID { - matches = false - break - } - - } - } - - if matches { - res.Insert(f) - } - } - return res -} - -func (w *World) QueryRule(rule Rule, syms *SymbolTable) *FactSet { - newFacts := &FactSet{} - rule.Apply(w.facts, newFacts, syms) +func (w *World) QueryRule(ruleOrigin uint64, scopes TrustedOrigin, rule Rule, syms *SymbolTable) *OriginFacts { + newFacts := &OriginFacts{} + factsIterator := w.facts.Iterator(scopes) + rule.Apply(ruleOrigin, &factsIterator, newFacts, syms) return newFacts } func (w *World) Clone() *World { - newFacts := new(FactSet) + newFacts := new(OriginFacts) *newFacts = *w.facts + newRules := make(OriginRules, len(w.rules)) + copy(newRules, w.rules) return &World{ facts: newFacts, - rules: append([]Rule{}, w.rules...), + rules: newRules, runLimits: w.runLimits, } } @@ -489,148 +485,83 @@ func (m MatchedVariables) Clone() MatchedVariables { return res } -func combine(variables MatchedVariables, predicates []Predicate, expressions []Expression, facts *FactSet, syms *SymbolTable) <-chan struct { +func combine(variables MatchedVariables, predicates []Predicate, facts *FactIterator, syms *SymbolTable) <-chan struct { + Origin MatchedVariables error } { c := make(chan struct { + Origin MatchedVariables error }) go func(c chan struct { + Origin MatchedVariables error }) { defer close(c) - current := 0 - indexes := make([]int, len(predicates)) - //fmt.Printf("combine variables %+v preds %+v exp %+v facts %+v indexes %+v\n", variables, predicates, expressions, *facts, indexes) - - // cannot apply a rule on an empty list of facts - if len(predicates) > 0 && len(*facts) == 0 { + if len(predicates) == 0 { + if variables.Complete() != nil { + c <- struct { + Origin + MatchedVariables + error + }{[]uint64{}, variables, nil} + } return } - // main loop - for { - if len(predicates) > 0 && len(*facts) > 0 { - // look for the next matching set of facts - // current indicates which predicate we are looking at, and indexes contains - // a list of indexes in the facts list, for each predicate - // when we are done looking at a set of facts, the last index is incremented - // and if that one reached the max number of facts, the previous one, etc - for { - if (*facts)[indexes[current]].Match(predicates[current]) { - if current == len(predicates)-1 { - // extract and check variables, check expressions, send variables - break - } else { - current += 1 - } - } else { - // did not match, we either increase the current index or the previous one - // then we check again for a match - if !advanceIndexes(¤t, &indexes, facts) { - return - } - } - } - } - - // extract and check variables, check expressions, send variables - var vars = variables.Clone() - var matching = true - - match: - for i, pred := range predicates { - fact := (*facts)[indexes[i]] - //fmt.Printf("evaluating predicate(%d) %+v with fact %+v\n", i, pred, fact) + currentFacts := facts.makeIterator() + Facts: + for fact := range currentFacts { + if fact.Match(predicates[0]) { + vars := variables.Clone() - for j := 0; j < len(pred.Terms); j++ { - term := pred.Terms[j] + for j := 0; j < len(predicates[0].Terms); j++ { + term := predicates[0].Terms[j] k, ok := term.(Variable) if !ok { continue } v := fact.Predicate.Terms[j] if !vars.Insert(k, v) { - matching = false - break match + continue Facts } - } - } - //fmt.Printf("evaluating indexes %+v with extracted variables %+v, matching = %+v\n", indexes, variables, matching) - if matching { - if complete_vars := vars.Complete(); complete_vars != nil { - //fmt.Printf("variables are complete, evaluating expressions\n") - valid := true - for _, e := range expressions { - res, err := e.Evaluate(complete_vars, syms) - if err != nil { - fmt.Printf("expression error: %+v", err) + if len(predicates) == 1 { + if vars.Complete() != nil { + c <- struct { + Origin + MatchedVariables + error + }{fact.Origin, vars, nil} + } + } else { + currentOrigin := fact.Origin + for res := range combine(vars, predicates[1:], facts, syms) { + if res.error != nil { c <- struct { + Origin MatchedVariables error - }{complete_vars, err} - + }{nil, nil, res.error} return } - if !res.Equal(Bool(true)) { - valid = false - break - } - } - if valid { - //fmt.Printf("sending valid variables %+v\n", complete_vars) + newOrigin := currentOrigin.Merge(res.Origin) c <- struct { + Origin MatchedVariables error - }{complete_vars, nil} + }{newOrigin, res.MatchedVariables, res.error} } - } else { - // if all predicates match but variables are not complete, it means - // variables appearing in the head do not appear in the body, - // so we should stop here because there's no way to get a correct match - return } } - - // this was a rule or check with expressions but no predicates, no need to - // update the indexes, an single execution is enough - if len(predicates) == 0 { - return - } - - // next index - if !advanceIndexes(¤t, &indexes, facts) { - return - } } - }(c) return c } - -func advanceIndexes(current *int, indexes *[]int, facts *FactSet) bool { - for i := *current; i >= 0; i-- { - if (*indexes)[i] < len(*facts)-1 { - (*indexes)[i] += 1 - break - } else { - if i > 0 { - (*indexes)[i] = 0 - *current -= 1 - } else { - // we reached the first predicate, we cannot generate more - // combinations, so we stop the task - return false - } - } - } - return true -} diff --git a/datalog/datalog_test.go b/datalog/datalog_test.go index dc5a933e..f50981ef 100644 --- a/datalog/datalog_test.go +++ b/datalog/datalog_test.go @@ -29,13 +29,16 @@ func TestFamily(t *testing.T) { b := syms.Insert("B") c := syms.Insert("C") d := syms.Insert("D") - e := syms.Insert("e") + e := syms.Insert("E") parent := syms.Insert("parent") grandparent := syms.Insert("grandparent") + syms.Insert("grandchild") - w.AddFact(Fact{Predicate{parent, []Term{a, b}}}) - w.AddFact(Fact{Predicate{parent, []Term{b, c}}}) - w.AddFact(Fact{Predicate{parent, []Term{c, d}}}) + authorityOrigin := AuthorityOrigin() + + w.AddFact(authorityOrigin, Fact{Predicate{parent, []Term{a, b}}}) + w.AddFact(authorityOrigin, Fact{Predicate{parent, []Term{b, c}}}) + w.AddFact(authorityOrigin, Fact{Predicate{parent, []Term{c, d}}}) r1 := Rule{ Head: Predicate{grandparent, []Term{hashVar("grandparent"), hashVar("grandchild")}}, @@ -46,9 +49,9 @@ func TestFamily(t *testing.T) { } t.Logf("querying r1: %s", dbg.Rule(r1)) - queryRuleResult := w.QueryRule(r1, syms) - t.Logf("r1 query: %s", dbg.FactSet(queryRuleResult)) - t.Logf("current facts: %s", dbg.FactSet(w.facts)) + queryRuleResult := w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, r1, syms) + t.Logf("r1 query: %s", dbg.OriginFacts(queryRuleResult)) + t.Logf("current facts: %s", dbg.OriginFacts(w.facts)) r2 := Rule{ Head: Predicate{grandparent, []Term{hashVar("grandparent"), hashVar("grandchild")}}, @@ -59,25 +62,34 @@ func TestFamily(t *testing.T) { } t.Logf("adding r2: %s", dbg.Rule(r2)) - w.AddRule(r2) + w.AddRule(0, TrustedOrigin{Origin: []uint64{0}}, r2) if err := w.Run(syms); err != nil { t.Error(err) } - w.AddFact(Fact{Predicate{parent, []Term{c, e}}}) + w.AddFact(authorityOrigin, Fact{Predicate{parent, []Term{c, e}}}) if err := w.Run(syms); err != nil { t.Error(err) } - res := w.Query(Predicate{grandparent, []Term{hashVar("grandparent"), hashVar("grandchild")}}) - t.Logf("grandparents after inserting parent(C, E): %s", dbg.FactSet(res)) - expected := &FactSet{ - Fact{Predicate{grandparent, []Term{a, c}}}, - Fact{Predicate{grandparent, []Term{b, d}}}, - Fact{Predicate{grandparent, []Term{b, e}}}, + res := w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ + Head: Predicate{grandparent, []Term{hashVar("grandparent"), hashVar("grandchild")}}, + Body: []Predicate{ + {grandparent, []Term{hashVar("grandparent"), hashVar("grandchild")}}, + }, + }, syms) + t.Logf("grandparents after inserting parent(C, E): %s", dbg.OriginFacts(res)) + expected := &OriginFacts{ + {Origin: authorityOrigin, Facts: &FactSet{ + Facts: []Fact{ + {Predicate{grandparent, []Term{a, c}}}, + {Predicate{grandparent, []Term{b, d}}}, + {Predicate{grandparent, []Term{b, e}}}, + }, + }}, } if !res.Equal(expected) { - t.Errorf("unexpected result:\nhave %s\n want %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("unexpected result:\nhave %s\n want %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } } @@ -98,33 +110,39 @@ func TestNumbers(t *testing.T) { t2 := syms.Insert("t2") join := syms.Insert("join") - w.AddFact(Fact{Predicate{t1, []Term{Integer(0), abc}}}) - w.AddFact(Fact{Predicate{t1, []Term{Integer(1), def}}}) - w.AddFact(Fact{Predicate{t1, []Term{Integer(2), ghi}}}) - w.AddFact(Fact{Predicate{t1, []Term{Integer(3), jkl}}}) - w.AddFact(Fact{Predicate{t1, []Term{Integer(4), mno}}}) + authorityOrigin := AuthorityOrigin() + + w.AddFact(authorityOrigin, Fact{Predicate{t1, []Term{Integer(0), abc}}}) + w.AddFact(authorityOrigin, Fact{Predicate{t1, []Term{Integer(1), def}}}) + w.AddFact(authorityOrigin, Fact{Predicate{t1, []Term{Integer(2), ghi}}}) + w.AddFact(authorityOrigin, Fact{Predicate{t1, []Term{Integer(3), jkl}}}) + w.AddFact(authorityOrigin, Fact{Predicate{t1, []Term{Integer(4), mno}}}) - w.AddFact(Fact{Predicate{t2, []Term{Integer(0), aaa, Integer(0)}}}) - w.AddFact(Fact{Predicate{t2, []Term{Integer(1), bbb, Integer(0)}}}) - w.AddFact(Fact{Predicate{t2, []Term{Integer(2), ccc, Integer(1)}}}) + w.AddFact(authorityOrigin, Fact{Predicate{t2, []Term{Integer(0), aaa, Integer(0)}}}) + w.AddFact(authorityOrigin, Fact{Predicate{t2, []Term{Integer(1), bbb, Integer(0)}}}) + w.AddFact(authorityOrigin, Fact{Predicate{t2, []Term{Integer(2), ccc, Integer(1)}}}) - res := w.QueryRule(Rule{ + res := w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{join, []Term{hashVar("left"), hashVar("right")}}, Body: []Predicate{ {t1, []Term{hashVar("id"), hashVar("left")}}, {t2, []Term{hashVar("t2_id"), hashVar("right"), hashVar("id")}}, }, }, syms) - expected := &FactSet{ - {Predicate{join, []Term{abc, aaa}}}, - {Predicate{join, []Term{abc, bbb}}}, - {Predicate{join, []Term{def, ccc}}}, + expected := &OriginFacts{ + {Origin: authorityOrigin, Facts: &FactSet{ + Facts: []Fact{ + {Predicate{join, []Term{abc, aaa}}}, + {Predicate{join, []Term{abc, bbb}}}, + {Predicate{join, []Term{def, ccc}}}, + }, + }}, } if !expected.Equal(res) { - t.Errorf("query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } - res = w.QueryRule(Rule{ + res = w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{join, []Term{hashVar("left"), hashVar("right")}}, Body: []Predicate{ {t1, []Term{Variable(1234), hashVar("left")}}, @@ -136,12 +154,16 @@ func TestNumbers(t *testing.T) { BinaryOp{LessThan{}}, }}, }, syms) - expected = &FactSet{ - {Predicate{join, []Term{abc, aaa}}}, - {Predicate{join, []Term{abc, bbb}}}, + expected = &OriginFacts{ + {Origin: authorityOrigin, Facts: &FactSet{ + Facts: []Fact{ + {Predicate{join, []Term{abc, aaa}}}, + {Predicate{join, []Term{abc, bbb}}}, + }, + }}, } if !expected.Equal(res) { - t.Errorf("constraint query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("constraint query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } } @@ -155,15 +177,16 @@ func TestString(t *testing.T) { app2 := syms.Insert("app_2") route := syms.Insert("route") suff := syms.Insert("route suffix") + authorityOrigin := AuthorityOrigin() - w.AddFact(Fact{Predicate{route, []Term{Integer(0), app0, syms.Insert("example.com")}}}) - w.AddFact(Fact{Predicate{route, []Term{Integer(1), app1, syms.Insert("test.com")}}}) - w.AddFact(Fact{Predicate{route, []Term{Integer(2), app2, syms.Insert("test.fr")}}}) - w.AddFact(Fact{Predicate{route, []Term{Integer(3), app0, syms.Insert("www.example.com")}}}) - w.AddFact(Fact{Predicate{route, []Term{Integer(4), app1, syms.Insert("mx.example.com")}}}) + w.AddFact(authorityOrigin, Fact{Predicate{route, []Term{Integer(0), app0, syms.Insert("example.com")}}}) + w.AddFact(authorityOrigin, Fact{Predicate{route, []Term{Integer(1), app1, syms.Insert("test.com")}}}) + w.AddFact(authorityOrigin, Fact{Predicate{route, []Term{Integer(2), app2, syms.Insert("test.fr")}}}) + w.AddFact(authorityOrigin, Fact{Predicate{route, []Term{Integer(3), app0, syms.Insert("www.example.com")}}}) + w.AddFact(authorityOrigin, Fact{Predicate{route, []Term{Integer(4), app1, syms.Insert("mx.example.com")}}}) - testSuffix := func(suffix string, syms *SymbolTable) *FactSet { - return w.QueryRule(Rule{ + testSuffix := func(suffix string, syms *SymbolTable) *OriginFacts { + return w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{suff, []Term{hashVar("app_id"), Variable(1234)}}, Body: []Predicate{{route, []Term{Variable(0), hashVar("app_id"), Variable(1234)}}}, Expressions: []Expression{{ @@ -175,19 +198,25 @@ func TestString(t *testing.T) { } res := testSuffix(".fr", syms) - expected := &FactSet{{Predicate{suff, []Term{app2, syms.Insert("test.fr")}}}} + expected := &OriginFacts{{Origin: authorityOrigin, Facts: &FactSet{Facts: []Fact{ + {Predicate{suff, []Term{app2, syms.Insert("test.fr")}}}, + }}}} if !expected.Equal(res) { - t.Errorf(".fr suffix query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf(".fr suffix query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } res = testSuffix("example.com", syms) - expected = &FactSet{ - {Predicate{suff, []Term{app0, syms.Insert("example.com")}}}, - {Predicate{suff, []Term{app0, syms.Insert("www.example.com")}}}, - {Predicate{suff, []Term{app1, syms.Insert("mx.example.com")}}}, + expected = &OriginFacts{ + {Origin: authorityOrigin, Facts: &FactSet{ + Facts: []Fact{ + {Predicate{suff, []Term{app0, syms.Insert("example.com")}}}, + {Predicate{suff, []Term{app0, syms.Insert("www.example.com")}}}, + {Predicate{suff, []Term{app1, syms.Insert("mx.example.com")}}}, + }, + }}, } if !expected.Equal(res) { - t.Errorf("example.com suffix query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("example.com suffix query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } } @@ -205,11 +234,12 @@ func TestDate(t *testing.T) { x := syms.Insert("x") before := syms.Insert("before") after := syms.Insert("after") + authorityOrigin := AuthorityOrigin() - w.AddFact(Fact{Predicate{x, []Term{Date(t1.Unix()), abc}}}) - w.AddFact(Fact{Predicate{x, []Term{Date(t3.Unix()), def}}}) + w.AddFact(authorityOrigin, Fact{Predicate{x, []Term{Date(t1.Unix()), abc}}}) + w.AddFact(authorityOrigin, Fact{Predicate{x, []Term{Date(t3.Unix()), def}}}) - res := w.QueryRule(Rule{ + res := w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{before, []Term{Variable(1234), hashVar("val")}}, Body: []Predicate{{x, []Term{Variable(1234), hashVar("val")}}}, Expressions: []Expression{{ @@ -222,12 +252,14 @@ func TestDate(t *testing.T) { BinaryOp{GreaterOrEqual{}}, }}, }, syms) - expected := &FactSet{{Predicate{before, []Term{Date(t1.Unix()), abc}}}} + expected := &OriginFacts{{Origin: authorityOrigin, Facts: &FactSet{Facts: []Fact{ + {Predicate{before, []Term{Date(t1.Unix()), abc}}}, + }}}} if !expected.Equal(res) { - t.Errorf("before query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("before query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } - res = w.QueryRule(Rule{ + res = w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{after, []Term{Variable(1234), hashVar("val")}}, Body: []Predicate{{x, []Term{Variable(1234), hashVar("val")}}}, Expressions: []Expression{{ @@ -240,9 +272,11 @@ func TestDate(t *testing.T) { BinaryOp{GreaterOrEqual{}}, }}, }, syms) - expected = &FactSet{{Predicate{after, []Term{Date(t3.Unix()), def}}}} + expected = &OriginFacts{{Origin: authorityOrigin, Facts: &FactSet{Facts: []Fact{ + {Predicate{after, []Term{Date(t3.Unix()), def}}}, + }}}} if !expected.Equal(res) { - t.Errorf("before query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("before query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } } @@ -276,11 +310,13 @@ func TestBytes(t *testing.T) { key := syms.Insert("pkey") keyMatch := syms.Insert("pkey match") - w.AddFact(Fact{Predicate{key, []Term{usr1, Bytes(k1)}}}) - w.AddFact(Fact{Predicate{key, []Term{usr2, Bytes(k2)}}}) - w.AddFact(Fact{Predicate{key, []Term{usr3, Bytes(k3)}}}) + authorityOrigin := AuthorityOrigin() + + w.AddFact(authorityOrigin, Fact{Predicate{key, []Term{usr1, Bytes(k1)}}}) + w.AddFact(authorityOrigin, Fact{Predicate{key, []Term{usr2, Bytes(k2)}}}) + w.AddFact(authorityOrigin, Fact{Predicate{key, []Term{usr3, Bytes(k3)}}}) - res := w.QueryRule(Rule{ + res := w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{keyMatch, []Term{hashVar("usr"), Variable(1)}}, Body: []Predicate{{key, []Term{hashVar("usr"), Variable(1)}}}, Expressions: []Expression{{ @@ -289,46 +325,56 @@ func TestBytes(t *testing.T) { BinaryOp{Equal{}}, }}, }, syms) - expected := &FactSet{ - {Predicate{keyMatch, []Term{usr1, Bytes(k1)}}}, + expected := &OriginFacts{ + {Origin: authorityOrigin, Facts: &FactSet{Facts: []Fact{ + {Predicate{keyMatch, []Term{usr1, Bytes(k1)}}}, + }}}, } if !expected.Equal(res) { - t.Errorf("key equal query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("key equal query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } - res = w.QueryRule(Rule{ + res = w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{keyMatch, []Term{hashVar("usr"), Variable(1)}}, Body: []Predicate{{key, []Term{hashVar("usr"), Variable(1)}}}, Expressions: []Expression{{ - Value{Set{Bytes(k1), Bytes(k3)}}, + Value{TermSet{Bytes(k1), Bytes(k3)}}, Value{Variable(1)}, BinaryOp{Contains{}}, }}, }, syms) - expected = &FactSet{ - {Predicate{keyMatch, []Term{usr1, Bytes(k1)}}}, - {Predicate{keyMatch, []Term{usr3, Bytes(k3)}}}, + expected = &OriginFacts{ + {Origin: authorityOrigin, Facts: &FactSet{ + Facts: []Fact{ + {Predicate{keyMatch, []Term{usr1, Bytes(k1)}}}, + {Predicate{keyMatch, []Term{usr3, Bytes(k3)}}}, + }, + }}, } if !expected.Equal(res) { - t.Errorf("key in query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("key in query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } - res = w.QueryRule(Rule{ + res = w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{keyMatch, []Term{hashVar("usr"), Variable(1)}}, Body: []Predicate{{key, []Term{hashVar("usr"), Variable(1)}}}, Expressions: []Expression{{ - Value{Set{Bytes(k1)}}, + Value{TermSet{Bytes(k1)}}, Value{Variable(1)}, BinaryOp{Contains{}}, UnaryOp{Negate{}}, }}, }, syms) - expected = &FactSet{ - {Predicate{keyMatch, []Term{usr2, Bytes(k2)}}}, - {Predicate{keyMatch, []Term{usr3, Bytes(k3)}}}, + expected = &OriginFacts{ + {Origin: authorityOrigin, Facts: &FactSet{ + Facts: []Fact{ + {Predicate{keyMatch, []Term{usr2, Bytes(k2)}}}, + {Predicate{keyMatch, []Term{usr3, Bytes(k3)}}}, + }, + }}, } if !expected.Equal(res) { - t.Errorf("key not in query failed:\n have: %s\n want: %s", dbg.FactSet(res), dbg.FactSet(expected)) + t.Errorf("key not in query failed:\n have: %s\n want: %s", dbg.OriginFacts(res), dbg.OriginFacts(expected)) } } @@ -347,19 +393,21 @@ func TestResource(t *testing.T) { read := syms.Insert("read") write := syms.Insert("write") - w.AddFact(Fact{Predicate{resource, []Term{ambient, file2}}}) - w.AddFact(Fact{Predicate{operation, []Term{ambient, write}}}) - w.AddFact(Fact{Predicate{right, []Term{authority, file1, read}}}) - w.AddFact(Fact{Predicate{right, []Term{authority, file2, read}}}) - w.AddFact(Fact{Predicate{right, []Term{authority, file1, write}}}) + authorityOrigin := AuthorityOrigin() + + w.AddFact(authorityOrigin, Fact{Predicate{resource, []Term{ambient, file2}}}) + w.AddFact(authorityOrigin, Fact{Predicate{operation, []Term{ambient, write}}}) + w.AddFact(authorityOrigin, Fact{Predicate{right, []Term{authority, file1, read}}}) + w.AddFact(authorityOrigin, Fact{Predicate{right, []Term{authority, file2, read}}}) + w.AddFact(authorityOrigin, Fact{Predicate{right, []Term{authority, file1, write}}}) check1 := syms.Insert("check1") - res := w.QueryRule(Rule{ + res := w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, Rule{ Head: Predicate{check1, []Term{file1}}, Body: []Predicate{{resource, []Term{ambient, file1}}}, }, syms) if len(*res) > 0 { - t.Errorf("unexpected facts: %s", dbg.FactSet(res)) + t.Errorf("unexpected facts: %s", dbg.OriginFacts(res)) } check2 := syms.Insert("check2") @@ -373,27 +421,33 @@ func TestResource(t *testing.T) { }, } t.Logf("r2 = %s", dbg.Rule(r2)) - res = w.QueryRule(r2, syms) + res = w.QueryRule(0, TrustedOrigin{Origin: []uint64{0}}, r2, syms) if len(*res) > 0 { - t.Errorf("unexpected facts: %s", dbg.FactSet(res)) + t.Errorf("unexpected facts: %s", dbg.OriginFacts(res)) } } func TestSymbolTable(t *testing.T) { s1 := new(SymbolTable) - s2 := &SymbolTable{"a", "b", "c"} - s3 := &SymbolTable{"d", "e", "f"} + s2 := &SymbolTable{ + Symbols: []string{"a", "b", "c"}, + } + s3 := &SymbolTable{ + Symbols: []string{"d", "e", "f"}, + } require.True(t, s1.IsDisjoint(s2)) s1.Extend(s2) require.False(t, s1.IsDisjoint(s2)) require.Equal(t, s2, s1) s1.Extend(s3) - require.Equal(t, SymbolTable(append(*s2, *s3...)), *s1) + require.Equal(t, SymbolTable{ + Symbols: append(s2.Symbols, s3.Symbols...), + }, *s1) - require.Equal(t, len(*s2)+len(*s3), s1.Len()) + require.Equal(t, len(s2.Symbols)+len(s3.Symbols), s1.Len()) - new := s1.SplitOff(len(*s2)) + new := s1.SplitOff(len(s2.Symbols)) require.Equal(t, s3, new) require.Equal(t, s2, s1) } @@ -404,12 +458,16 @@ func TestSymbolTableInsertAndSym(t *testing.T) { require.Equal(t, String(1025), s.Insert("b")) require.Equal(t, String(1026), s.Insert("c")) - require.Equal(t, &SymbolTable{"a", "b", "c"}, s) + require.Equal(t, &SymbolTable{ + Symbols: []string{"a", "b", "c"}, + }, s) require.Equal(t, String(1024), s.Insert("a")) require.Equal(t, String(1027), s.Insert("d")) - require.Equal(t, &SymbolTable{"a", "b", "c", "d"}, s) + require.Equal(t, &SymbolTable{ + Symbols: []string{"a", "b", "c", "d"}, + }, s) require.Equal(t, String(1024), s.Sym("a")) require.Equal(t, String(1025), s.Sym("b")) @@ -430,8 +488,12 @@ func TestSymbolTableClone(t *testing.T) { s2.Insert("d") s2.Insert("e") - require.Equal(t, &SymbolTable{"a", "b", "c"}, s) - require.Equal(t, &SymbolTable{"a", "b", "c", "d", "e"}, s2) + require.Equal(t, &SymbolTable{ + Symbols: []string{"a", "b", "c"}, + }, s) + require.Equal(t, &SymbolTable{ + Symbols: []string{"a", "b", "c", "d", "e"}, + }, s2) } func TestSetEqual(t *testing.T) { @@ -439,38 +501,38 @@ func TestSetEqual(t *testing.T) { testCases := []struct { desc string - s1 Set - s2 Set + s1 TermSet + s2 TermSet equal bool }{ { desc: "equal with same values in same order", - s1: Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, - s2: Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, + s1: TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, + s2: TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, equal: true, }, { desc: "equal with same values different order", - s1: Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, - s2: Set{syms.Insert("b"), syms.Insert("c"), syms.Insert("a")}, + s1: TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, + s2: TermSet{syms.Insert("b"), syms.Insert("c"), syms.Insert("a")}, equal: true, }, { desc: "not equal when length mismatch", - s1: Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, - s2: Set{syms.Insert("a"), syms.Insert("b")}, + s1: TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, + s2: TermSet{syms.Insert("a"), syms.Insert("b")}, equal: false, }, { desc: "not equal when length mismatch", - s1: Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, - s2: Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c"), syms.Insert("d")}, + s1: TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, + s2: TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c"), syms.Insert("d")}, equal: false, }, { desc: "not equal when same length but different values", - s1: Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, - s2: Set{syms.Insert("a"), syms.Insert("b"), syms.Insert("d")}, + s1: TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("c")}, + s2: TermSet{syms.Insert("a"), syms.Insert("b"), syms.Insert("d")}, equal: false, }, } @@ -537,12 +599,15 @@ func TestWorldRunLimits(t *testing.T) { }, } + authorityOrigin := AuthorityOrigin() + for _, tc := range testCases { w := NewWorld(tc.opts...) + t.Logf("running test case %s\n", tc.desc) - w.AddFact(Fact{Predicate{parent, []Term{a, b}}}) - w.AddFact(Fact{Predicate{parent, []Term{b, c}}}) - w.AddFact(Fact{Predicate{parent, []Term{c, d}}}) + w.AddFact(authorityOrigin, Fact{Predicate{parent, []Term{a, b}}}) + w.AddFact(authorityOrigin, Fact{Predicate{parent, []Term{b, c}}}) + w.AddFact(authorityOrigin, Fact{Predicate{parent, []Term{c, d}}}) r1 := Rule{ Head: Predicate{grandparent, []Term{hashVar("grandparent"), hashVar("grandchild")}}, @@ -552,7 +617,7 @@ func TestWorldRunLimits(t *testing.T) { }, } - w.AddRule(r1) + w.AddRule(0, TrustedOrigin{Origin: []uint64{0}}, r1) require.Equal(t, tc.expectedErr, w.Run(syms)) } } diff --git a/datalog/expressions.go b/datalog/expressions.go index f7580885..559027bc 100644 --- a/datalog/expressions.go +++ b/datalog/expressions.go @@ -94,23 +94,8 @@ func (e *Expression) Print(symbols *SymbolTable) string { switch op.Type() { case OpTypeValue: id := op.(Value).ID - switch id.Type() { - case TermTypeString: - err := s.Push(fmt.Sprintf("\"%s\"", symbols.Str(id.(String)))) - if err != nil { - return "" - } - case TermTypeVariable: - err := s.Push(fmt.Sprintf("$%s", symbols.Var(id.(Variable)))) - if err != nil { - return "" - } - default: - err := s.Push(id.String()) - if err != nil { - return "" - } - } + debug := SymbolDebugger{symbols} + s.Push(debug.Term(id)) case OpTypeUnary: v, err := s.Pop() if err != nil { @@ -253,7 +238,7 @@ func (Length) Eval(value Term, symbols *SymbolTable) (Term, error) { case TermTypeBytes: out = Integer(len(value.(Bytes))) case TermTypeSet: - out = Integer(len(value.(Set))) + out = Integer(len(value.(TermSet))) default: return nil, fmt.Errorf("datalog: unexpected Length value type: %d", value.Type()) } @@ -323,6 +308,9 @@ const ( BinaryGreaterThan BinaryGreaterOrEqual BinaryEqual + BinaryNotEqual + BinaryStrictEqual + BinaryStrictNotEqual BinaryContains BinaryPrefix BinarySuffix @@ -442,7 +430,7 @@ func (GreaterOrEqual) Eval(left Term, right Term, _ *SymbolTable) (Term, error) } // Equal returns true when left and right are equal. -// It requires left and right to have the same concrete type +// It does not requires left and right to have the same concrete type // and only accepts Integer, Bytes or String. type Equal struct{} @@ -450,6 +438,30 @@ func (Equal) Type() BinaryOpType { return BinaryEqual } func (Equal) Eval(left Term, right Term, _ *SymbolTable) (Term, error) { + return Bool(left.Equal(right)), nil +} + +// NotEqual returns true when left and right are not equal. +// It does not requires left and right to have the same concrete type +// and only accepts Integer, Bytes or String. +type NotEqual struct{} + +func (NotEqual) Type() BinaryOpType { + return BinaryNotEqual +} +func (NotEqual) Eval(left Term, right Term, _ *SymbolTable) (Term, error) { + return Bool(!left.Equal(right)), nil +} + +// StrictEqual returns true when left and right are strictly equal. +// It requires left and right to have the same concrete type +// and only accepts Integer, Bytes or String. +type StrictEqual struct{} + +func (StrictEqual) Type() BinaryOpType { + return BinaryStrictEqual +} +func (StrictEqual) Eval(left Term, right Term, _ *SymbolTable) (Term, error) { if g, w := left.Type(), right.Type(); g != w { return nil, fmt.Errorf("datalog: Equal type mismatch: %d != %d", g, w) } @@ -469,6 +481,34 @@ func (Equal) Eval(left Term, right Term, _ *SymbolTable) (Term, error) { return Bool(left.Equal(right)), nil } +// StrictNotEqual returns true when left and right are strictly not equal. +// It requires left and right to have the same concrete type +// and only accepts Integer, Bytes or String. +type StrictNotEqual struct{} + +func (StrictNotEqual) Type() BinaryOpType { + return BinaryStrictNotEqual +} +func (StrictNotEqual) Eval(left Term, right Term, _ *SymbolTable) (Term, error) { + if g, w := left.Type(), right.Type(); g != w { + return nil, fmt.Errorf("datalog: Equal type mismatch: %d != %d", g, w) + } + + switch left.Type() { + case TermTypeInteger: + case TermTypeBytes: + case TermTypeString: + case TermTypeDate: + case TermTypeBool: + case TermTypeSet: + + default: + return nil, fmt.Errorf("datalog: unexpected Equal value type: %d", left.Type()) + } + + return Bool(!left.Equal(right)), nil +} + // Contains returns true when the right value exists in the left Set. // The right value must be an Integer, Bytes, String or Symbol. // The left value must be a Set, containing elements of right type. @@ -500,12 +540,12 @@ func (Contains) Eval(left Term, right Term, symbols *SymbolTable) (Term, error) return nil, fmt.Errorf("datalog: unexpected Contains right value type: %d", right.Type()) } - set, ok := left.(Set) + set, ok := left.(TermSet) if !ok { return nil, errors.New("datalog: Contains left value must be a Set") } - rhsset, ok := right.(Set) + rhsset, ok := right.(TermSet) if ok { for _, rhselt := range rhsset { @@ -538,12 +578,12 @@ func (Intersection) Type() BinaryOpType { return BinaryIntersection } func (Intersection) Eval(left Term, right Term, _ *SymbolTable) (Term, error) { - set, ok := left.(Set) + set, ok := left.(TermSet) if !ok { return nil, errors.New("datalog: Intersection left value must be a Set") } - set2, ok := right.(Set) + set2, ok := right.(TermSet) if !ok { return nil, errors.New("datalog: Intersection rightt value must be a Set") } @@ -558,12 +598,12 @@ func (Union) Type() BinaryOpType { return BinaryUnion } func (Union) Eval(left Term, right Term, _ *SymbolTable) (Term, error) { - set, ok := left.(Set) + set, ok := left.(TermSet) if !ok { return nil, errors.New("datalog: Union left value must be a Set") } - set2, ok := right.(Set) + set2, ok := right.(TermSet) if !ok { return nil, errors.New("datalog: Union rightt value must be a Set") } diff --git a/datalog/expressions_test.go b/datalog/expressions_test.go index 500c6b4a..d049c184 100644 --- a/datalog/expressions_test.go +++ b/datalog/expressions_test.go @@ -521,61 +521,61 @@ func TestBinaryContains(t *testing.T) { }{ { name: "integer in set", - left: Set{Integer(1), Integer(2), Integer(3)}, + left: TermSet{Integer(1), Integer(2), Integer(3)}, right: Integer(1), want: Bool(true), }, { name: "string not in set", - left: Set{syms.Insert("def"), syms.Insert("ijk")}, + left: TermSet{syms.Insert("def"), syms.Insert("ijk")}, right: syms.Insert("abc"), want: Bool(false), }, { name: "bytes in set", - left: Set{Bytes("abc"), Bytes("def")}, + left: TermSet{Bytes("abc"), Bytes("def")}, right: Bytes("abc"), want: Bool(true), }, { name: "symbol not in set", - left: Set{String(1), String(2)}, + left: TermSet{String(1), String(2)}, right: String(0), want: Bool(false), }, { name: "set element type mismatch", - left: Set{Integer(1), Integer(2)}, + left: TermSet{Integer(1), Integer(2)}, right: String(0), want: Bool(false), }, { name: "bool in set", - left: Set{Bool(true), Bool(false)}, + left: TermSet{Bool(true), Bool(false)}, right: Bool(true), want: Bool(true), }, { name: "date not in set", - left: Set{Date(1), Date(2)}, + left: TermSet{Date(1), Date(2)}, right: Date(0), want: Bool(false), }, { name: "set not subset", - left: Set{Integer(1), Integer(2)}, - right: Set{Integer(0)}, + left: TermSet{Integer(1), Integer(2)}, + right: TermSet{Integer(0)}, want: Bool(false), }, { name: "set is subset", - left: Set{Integer(1), Integer(2)}, - right: Set{Integer(1)}, + left: TermSet{Integer(1), Integer(2)}, + right: TermSet{Integer(1)}, want: Bool(true), }, { name: "variable in set", - left: Set{Integer(1), Integer(2)}, + left: TermSet{Integer(1), Integer(2)}, right: Variable(0), wantErr: true, }, diff --git a/datalog/factset.go b/datalog/factset.go new file mode 100644 index 00000000..52868be7 --- /dev/null +++ b/datalog/factset.go @@ -0,0 +1,324 @@ +// Copyright (c) 2019 Titanous, daeMOn63 and Contributors to the Eclipse Foundation. +// SPDX-License-Identifier: Apache-2.0 + +package datalog + +import ( + "math" + "slices" +) + +type SingleOrigin uint64 +type Origin []uint64 +type TrustedOrigin struct{ Origin } + +func MakeOrigin(ids []uint64) Origin { + slices.Sort(ids) + return slices.Compact(ids) +} + +func AuthorityOrigin() Origin { + return []uint64{0} +} + +func AuthorizerOrigin() Origin { + return []uint64{math.MaxUint64} +} + +func (o Origin) Equal(other Origin) bool { + return slices.Equal(o, other) +} + +func (o Origin) Merge(other Origin) Origin { + ids := append(o, other...) + return MakeOrigin(ids) +} + +func DefaultTrustedOrigin() TrustedOrigin { + ids := []uint64{0, math.MaxUint64} + return TrustedOrigin{Origin: MakeOrigin(ids)} +} + +// let authorizer_trusted_origins = TrustedOrigins::from_scopes( +// +// &authorizer_scopes, +// &TrustedOrigins::default(), +// usize::MAX, +// &public_key_to_block_id, +// +// ); +func AuthorizerTrustedOrigins(authorizerScopes []Scope, publicKeyToBlockId map[uint64][]uint64) TrustedOrigin { + return TrustedOriginsFromScopes(authorizerScopes, DefaultTrustedOrigin(), math.MaxUint64, publicKeyToBlockId) +} + +func TrustedOriginsFromScopes(ruleScopes []Scope, defaultOrigins TrustedOrigin, currentBlock uint64, publicKeyToBlockId map[uint64][]uint64) TrustedOrigin { + if len(ruleScopes) == 0 { + origins := defaultOrigins.Origin + origins = append(origins, currentBlock) + origins = append(origins, math.MaxUint64) + return TrustedOrigin{Origin: origins} + } + + origins := Origin{} + origins = append(origins, currentBlock) + origins = append(origins, math.MaxUint64) + + for _, scope := range ruleScopes { + switch scope.Type() { + case ScopeTypeAuthority: + origins = append(origins, 0) + case ScopeTypePrevious: + if currentBlock != math.MaxUint64 { + origins = append(origins, 0, currentBlock+1) + } + case ScopeTypePublicKey: + if blockIds, ok := publicKeyToBlockId[scope.(PublicKeyScope).ID]; ok { + origins = append(origins, blockIds...) + } + } + } + + return TrustedOrigin{Origin: origins} +} + +func (o TrustedOrigin) Equal(other TrustedOrigin) bool { + return slices.Equal(o.Origin, other.Origin) +} + +func (o TrustedOrigin) Contains(other Origin) bool { + for _, v := range other { + if !slices.Contains(o.Origin, v) { + return false + } + } + return true +} + +type OriginWithFacts struct { + Origin Origin + Facts *FactSet +} + +type OriginFacts []OriginWithFacts + +func (s *OriginFacts) Insert(origin Origin, f Fact) bool { + for _, v := range *s { + if v.Origin.Equal(origin) { + return v.Facts.Insert(f) + } + } + + (*s) = append(*s, OriginWithFacts{Origin: origin, Facts: &FactSet{Facts: []Fact{f}}}) + return true + +} + +func (s *OriginFacts) InsertAll(origin Origin, facts []Fact) { + for _, v := range *s { + if v.Origin.Equal(origin) { + v.Facts.InsertAll(facts) + return + } + } + + (*s) = append(*s, OriginWithFacts{Origin: origin, Facts: &FactSet{Facts: facts}}) +} + +func (s *OriginFacts) Merge(other OriginFacts) { + for _, factSet := range other { + + found := false + for _, v := range *s { + if v.Origin.Equal(factSet.Origin) { + v.Facts.InsertAll(factSet.Facts.Facts) + found = true + } + } + + if !found { + (*s) = append(*s, factSet) + } + + } +} + +func (s *OriginWithFacts) Merge(other OriginWithFacts) { + for _, f := range other.Facts.Facts { + s.Facts.Insert(f) + } +} + +func (s *OriginFacts) Equal(x *OriginFacts) bool { + if len(*s) != len(*x) { + return false + } + + for _, facts := range *x { + found := false + for _, v := range *s { + if v.Origin.Equal(facts.Origin) { + if !v.Facts.Equal(facts.Facts) { + return false + } + found = true + break + } + } + + if !found { + return false + } + } + + return true +} + +func (s *OriginFacts) Len() int { + count := 0 + for _, v := range *s { + count += len(v.Facts.Facts) + } + return count +} + +func (s *OriginFacts) Iterator(o TrustedOrigin) FactIterator { + return FactIterator{ + origin: o, + facts: s, + } +} + +type FactIterator struct { + origin TrustedOrigin + facts *OriginFacts +} + +func (f *FactIterator) makeIterator() <-chan struct { + Origin + Fact +} { + c := make(chan struct { + Origin + Fact + }) + + go func(c chan struct { + Origin + Fact + }) { + defer close(c) + + for _, v := range *f.facts { + if f.origin.Contains(v.Origin) { + for _, fact := range v.Facts.Facts { + c <- struct { + Origin + Fact + }{v.Origin, fact} + } + } + } + }(c) + return c +} + +type FactSet struct { + Facts []Fact +} + +func (s *FactSet) Insert(f Fact) bool { + for _, v := range s.Facts { + if v.Equal(f.Predicate) { + return false + } + } + + s.Facts = append(s.Facts, f) + return true +} + +func (s *FactSet) InsertAll(facts []Fact) { + for _, f := range facts { + s.Insert(f) + } +} + +func (s *FactSet) Equal(x *FactSet) bool { + if len(s.Facts) != len(x.Facts) { + return false + } + for _, f1 := range x.Facts { + found := false + for _, f2 := range s.Facts { + if f1.Predicate.Equal(f2.Predicate) { + found = true + break + } + } + if !found { + return false + } + } + return true +} + +type OriginRules []TrustedOriginWithRules + +type TrustedOriginWithRules struct { + TrustedOrigin TrustedOrigin + Rules []OriginWithRule +} + +type OriginWithRule struct { + Origin uint64 + Rule Rule +} + +func (s *OriginRules) Insert(ruleOrigin uint64, scopes TrustedOrigin, r Rule) { + for _, v := range *s { + if v.TrustedOrigin.Equal(scopes) { + v.Rules = append(v.Rules, OriginWithRule{Origin: ruleOrigin, Rule: r}) + } + } + + (*s) = append(*s, TrustedOriginWithRules{TrustedOrigin: scopes, Rules: []OriginWithRule{{Origin: ruleOrigin, Rule: r}}}) +} + +func (s *OriginRules) InsertAll(ruleOrigin uint64, scopes TrustedOrigin, rules []Rule) { + for _, v := range *s { + if v.TrustedOrigin.Equal(scopes) { + for _, r := range rules { + v.Rules = append(v.Rules, OriginWithRule{Origin: ruleOrigin, Rule: r}) + } + return + } + } + + oRules := make([]OriginWithRule, len(rules)) + for i, r := range rules { + oRules[i] = OriginWithRule{Origin: ruleOrigin, Rule: r} + } + (*s) = append(*s, TrustedOriginWithRules{TrustedOrigin: scopes, Rules: oRules}) +} + +func (s *OriginRules) Merge(other OriginRules) { + for _, v := range other { + + found := false + for _, v := range *s { + if v.TrustedOrigin.Equal(v.TrustedOrigin) { + v.Rules = append(v.Rules, v.Rules...) + found = true + } + } + + if !found { + (*s) = append(*s, v) + } + + } +} + +func (s *TrustedOriginWithRules) Merge(other TrustedOriginWithRules) { + s.Rules = append(s.Rules, other.Rules...) +} diff --git a/datalog/scope.go b/datalog/scope.go new file mode 100644 index 00000000..34032406 --- /dev/null +++ b/datalog/scope.go @@ -0,0 +1,36 @@ +// Copyright (c) 2019 Titanous, daeMOn63 and Contributors to the Eclipse Foundation. +// SPDX-License-Identifier: Apache-2.0 + +package datalog + +type ScopeType byte + +const ( + ScopeTypeAuthority ScopeType = iota + ScopeTypePrevious + ScopeTypePublicKey +) + +type Scope interface { + Type() ScopeType +} + +type AuthorityScope struct{} + +func (AuthorityScope) Type() ScopeType { + return ScopeTypeAuthority +} + +type PreviousScope struct{} + +func (PreviousScope) Type() ScopeType { + return ScopeTypePrevious +} + +type PublicKeyScope struct { + ID uint64 +} + +func (PublicKeyScope) Type() ScopeType { + return ScopeTypePublicKey +} diff --git a/datalog/symbol.go b/datalog/symbol.go index 5b5cb184..2ae51db2 100644 --- a/datalog/symbol.go +++ b/datalog/symbol.go @@ -4,6 +4,7 @@ package datalog import ( + "crypto/ed25519" "fmt" "sort" "strings" @@ -42,7 +43,10 @@ var DEFAULT_SYMBOLS = [...]string{ var OFFSET = 1024 -type SymbolTable []string +type SymbolTable struct { + Symbols []string + PublicKeys []ed25519.PublicKey +} func (t *SymbolTable) Insert(s string) String { for i, v := range DEFAULT_SYMBOLS { @@ -51,14 +55,14 @@ func (t *SymbolTable) Insert(s string) String { } } - for i, v := range *t { - if string(v) == s { + for i, v := range t.Symbols { + if v == s { return String(OFFSET + i) } } - *t = append(*t, s) + t.Symbols = append(t.Symbols, s) - return String(OFFSET + len(*t) - 1) + return String(OFFSET + len(t.Symbols) - 1) } func (t *SymbolTable) Sym(s string) Term { @@ -68,8 +72,8 @@ func (t *SymbolTable) Sym(s string) Term { } } - for i, v := range *t { - if string(v) == s { + for i, v := range t.Symbols { + if v == s { return String(OFFSET + i) } } @@ -83,8 +87,8 @@ func (t *SymbolTable) Index(s string) uint64 { } } - for i, v := range *t { - if string(v) == s { + for i, v := range t.Symbols { + if v == s { return uint64(OFFSET + i) } } @@ -99,10 +103,10 @@ func (t *SymbolTable) Str(sym String) string { return DEFAULT_SYMBOLS[int(sym)] } } - if int(sym)-1024 > len(*t)-1 { + if int(sym)-1024 > len(t.Symbols)-1 { return fmt.Sprintf("", sym) } - return (*t)[int(sym)-1024] + return t.Symbols[int(sym)-1024] } func (t *SymbolTable) Var(v Variable) string { @@ -113,10 +117,10 @@ func (t *SymbolTable) Var(v Variable) string { return DEFAULT_SYMBOLS[int(v)] } } - if int(v)-1024 > len(*t)-1 { + if int(v)-1024 > len(t.Symbols)-1 { return fmt.Sprintf("", v) } - return (*t)[int(v)-1024] + return t.Symbols[int(v)-1024] } func (t *SymbolTable) Clone() *SymbolTable { @@ -128,31 +132,34 @@ func (t *SymbolTable) Clone() *SymbolTable { // [at, len). After the call, the receiver will be left containing // the elements [0, at) with its previous capacity unchanged. func (t *SymbolTable) SplitOff(at int) *SymbolTable { - if at > len(*t) { + if at > len(t.Symbols) { panic("split index out of bound") } - new := make(SymbolTable, len(*t)-at) - copy(new, (*t)[at:]) + new := SymbolTable{ + Symbols: make([]string, len(t.Symbols)-at), + PublicKeys: t.PublicKeys, + } + copy(new.Symbols, t.Symbols[at:]) - *t = (*t)[:at] + t.Symbols = t.Symbols[:at] return &new } func (t *SymbolTable) Len() int { - return len(*t) + return len(t.Symbols) } // IsDisjoint returns true if receiver has no elements in common with other. // This is equivalent to checking for an empty intersection. func (t *SymbolTable) IsDisjoint(other *SymbolTable) bool { - m := make(map[string]struct{}, len(*t)) - for _, s := range *t { + m := make(map[string]struct{}, len(t.Symbols)) + for _, s := range t.Symbols { m[s] = struct{}{} } - for _, os := range *other { + for _, os := range other.Symbols { if _, ok := m[os]; ok { return false } @@ -164,7 +171,7 @@ func (t *SymbolTable) IsDisjoint(other *SymbolTable) bool { // Extend insert symbols from the given SymbolTable in the receiving one // excluding any Symbols already existing func (t *SymbolTable) Extend(other *SymbolTable) { - for _, s := range *other { + for _, s := range other.Symbols { t.Insert(s) } } @@ -176,19 +183,35 @@ type SymbolDebugger struct { func (d SymbolDebugger) Predicate(p Predicate) string { strs := make([]string, len(p.Terms)) for i, id := range p.Terms { - var s string - if sym, ok := id.(String); ok { - s = "\"" + d.Str(sym) + "\"" - } else if variable, ok := id.(Variable); ok { - s = "$" + d.Var(variable) - } else { - s = fmt.Sprintf("%v", id) - } - strs[i] = s + strs[i] = d.Term(id) } return fmt.Sprintf("%s(%s)", d.Str(p.Name), strings.Join(strs, ", ")) } +func (d SymbolDebugger) Fact(origin Origin, f Fact) string { + return fmt.Sprintf("%d: %s", origin, d.Predicate(f.Predicate)) +} + +func (d SymbolDebugger) Term(t Term) string { + switch t.Type() { + case TermTypeString: + return "\"" + d.Str(t.(String)) + "\"" + case TermTypeVariable: + return "$" + d.Var(t.(Variable)) + case TermTypeSet: + if len(t.(TermSet)) == 0 { + return "{,}" + } + terms := make([]string, len(t.(TermSet))) + for i, term := range t.(TermSet) { + terms[i] = d.Term(term) + } + return "{" + strings.Join(terms, ", ") + "}" + default: + return fmt.Sprintf("%v", t) + } +} + func (d SymbolDebugger) Rule(r Rule) string { head := d.Predicate(r.Head) preds := make([]string, len(r.Body)) @@ -239,24 +262,47 @@ func (d SymbolDebugger) Check(c Check) string { } func (d SymbolDebugger) World(w *World) string { - facts := make([]string, len(*w.facts)) - for i, f := range *w.facts { - facts[i] = d.Predicate(f.Predicate) + facts := make(map[string][]string) + for _, f := range *w.facts { + originSlice := make([]uint64, 0) + for _, o := range f.Origin { + originSlice = append(originSlice, o) + } + sort.Slice(originSlice, func(i, j int) bool { + return originSlice[i] < originSlice[j] + }) + origin := fmt.Sprintf("%v", originSlice) + facts[origin] = make([]string, 0) + + for _, fact := range f.Facts.Facts { + facts[origin] = append(facts[origin], d.Predicate(fact.Predicate)) + } + sort.Strings(facts[origin]) + } + rules := make(map[string][]string) + for _, o := range w.rules { + for _, r := range o.Rules { + originStr := fmt.Sprintf("%d", r.Origin) + if _, ok := rules[originStr]; !ok { + rules[originStr] = make([]string, 0) + } + rules[originStr] = append(rules[originStr], d.Rule(r.Rule)) + } } - rules := make([]string, len(w.rules)) - for i, r := range w.rules { - rules[i] = d.Rule(r) + for _, r := range rules { + sort.Strings(r) } - sort.Strings(facts) - sort.Strings(rules) return fmt.Sprintf("World {{\n\tfacts: %v\n\trules: %v\n}}", facts, rules) } -func (d SymbolDebugger) FactSet(s *FactSet) string { - strs := make([]string, len(*s)) - for i, f := range *s { - strs[i] = d.Predicate(f.Predicate) +func (d SymbolDebugger) OriginFacts(s *OriginFacts) string { + facts := make([]string, len(*s)) + for _, f := range *s { + for _, fact := range f.Facts.Facts { + facts = append(facts, d.Fact(f.Origin, fact)) + } } - return fmt.Sprintf("%v", strs) + + return fmt.Sprintf("%v", facts) } diff --git a/example_test.go b/example_test.go index 1073293b..a5d688f8 100644 --- a/example_test.go +++ b/example_test.go @@ -4,7 +4,6 @@ package biscuit_test import ( - "crypto/ed25519" "crypto/rand" "fmt" @@ -14,7 +13,7 @@ import ( func ExampleBiscuit() { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := biscuit.NewEd25519KeyPair(rng) authority, err := parser.FromStringBlockWithParams(` right("/a/file1.txt", {read}); @@ -89,7 +88,9 @@ func ExampleBiscuit() { if err != nil { panic(fmt.Errorf("failed to parse authorizer: %v", err)) } - v1.AddAuthorizer(authorizer) + if err := v1.AddAuthorizer(authorizer); err != nil { + panic(fmt.Errorf("failed to add authorizer: %v", err)) + } if err := v1.Authorize(); err != nil { // fmt.Println(v1.PrintWorld()) @@ -112,7 +113,9 @@ func ExampleBiscuit() { if err != nil { panic(fmt.Errorf("failed to parse authorizer: %v", err)) } - v1.AddAuthorizer(authorizer) + if err := v1.AddAuthorizer(authorizer); err != nil { + panic(fmt.Errorf("failed to add authorizer: %v", err)) + } if err := v1.Authorize(); err != nil { fmt.Println("forbidden to write /a/file1.txt") diff --git a/go.mod b/go.mod index a23a592f..736c39b5 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/biscuit-auth/biscuit-go/v2 -go 1.19 +go 1.20 require ( github.com/alecthomas/participle/v2 v2.1.4 @@ -10,6 +10,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.8.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 57af1557..062cba4b 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/alecthomas/participle/v2 v2.1.4/go.mod h1:8tqVbpTX20Ru4NfYQgZf4mP18eX github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ= +github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/parser/grammar.go b/parser/grammar.go index c68855c2..4bbdab13 100644 --- a/parser/grammar.go +++ b/parser/grammar.go @@ -217,7 +217,8 @@ type Term struct { Date *string `| @DateTime` Integer *int64 `| @Int` Bool *Bool `| @Bool` - Set []*Term `| "[" @@ ("," @@)* "]"` + Set []*Term `| "{" @@ ("," @@)* "}"` + EmptySet bool `| @("{" "," "}")` } type Value struct { @@ -241,6 +242,7 @@ const ( OpLessThan OpGreaterThan OpEqual + OpNotEqual OpContains OpPrefix OpSuffix @@ -249,12 +251,14 @@ const ( OpUnion OpLength OpNegate + OpStrictEqual + OpStrictNotEqual ) var operatorMap = map[string]Operator{ "+": OpAdd, "-": OpSub, "*": OpMul, "/": OpDiv, "&&": OpAnd, "||": OpOr, "<=": OpLessOrEqual, ">=": OpGreaterOrEqual, "<": OpLessThan, ">": OpGreaterThan, - "==": OpEqual, "!": OpNegate, "contains": OpContains, "starts_with": OpPrefix, "ends_with": OpSuffix, "matches": OpMatches, "intersection": OpIntersection, "union": OpUnion, "length": OpLength} + "==": OpEqual, "!=": OpNotEqual, "===": OpStrictEqual, "!==": OpStrictNotEqual, "!": OpNegate, "contains": OpContains, "starts_with": OpPrefix, "ends_with": OpSuffix, "matches": OpMatches, "intersection": OpIntersection, "union": OpUnion, "length": OpLength} func (o *Operator) Capture(s []string) error { *o = operatorMap[s[0]] @@ -287,7 +291,7 @@ type Expr2 struct { } type OpExpr3 struct { - Operator Operator `@("<=" | ">=" | "<" | ">" | "==")` + Operator Operator `@("<=" | ">=" | "<" | ">" | "==" | "!=" | "===" | "!==")` Expr3 *Expr3 `@@` } @@ -432,7 +436,6 @@ func (e *OpExpr7) ToExpr(expr *biscuit.Expression, parameters ParametersMap) { } func (op *Operator) ToExpr(expr *biscuit.Expression) { - var biscuit_op biscuit.Op switch *op { case OpAnd: @@ -457,6 +460,12 @@ func (op *Operator) ToExpr(expr *biscuit.Expression) { biscuit_op = biscuit.BinaryGreaterThan case OpEqual: biscuit_op = biscuit.BinaryEqual + case OpNotEqual: + biscuit_op = biscuit.BinaryNotEqual + case OpStrictEqual: + biscuit_op = biscuit.BinaryStrictEqual + case OpStrictNotEqual: + biscuit_op = biscuit.BinaryStrictNotEqual case OpContains: biscuit_op = biscuit.BinaryContains case OpPrefix: @@ -556,6 +565,8 @@ func (a *Term) ToBiscuit(parameters ParametersMap) (biscuit.Term, error) { biscuitSet = append(biscuitSet, setTerm) } biscuitTerm = biscuitSet + case a.EmptySet: + biscuitTerm = make(biscuit.Set, 0) case a.Parameter != nil: var paramName string = string(*(a.Parameter)) paramValue := parameters[paramName] diff --git a/parser/grammar_test.go b/parser/grammar_test.go index ae5e8e4b..5975425e 100644 --- a/parser/grammar_test.go +++ b/parser/grammar_test.go @@ -89,7 +89,7 @@ func TestGrammarPredicate(t *testing.T) { }, }, { - Input: `right($1, [hex:41414141, "sym"])`, + Input: `right($1, {hex:41414141, "sym"})`, Expected: &Predicate{ Name: sptr("right"), IDs: []*Term{ @@ -193,7 +193,7 @@ func TestGrammarExpression(t *testing.T) { }, }, { - Input: `[1, 2, 3].contains($0)`, + Input: `{1, 2, 3}.contains($0)`, Expected: &biscuit.Expression{ biscuit.Value{Term: biscuit.Set{biscuit.Integer(1), biscuit.Integer(2), biscuit.Integer(3)}}, biscuit.Value{Term: biscuit.Variable("0")}, @@ -201,7 +201,7 @@ func TestGrammarExpression(t *testing.T) { }, }, { - Input: `![4,5,6].contains($0)`, + Input: `!{4,5,6}.contains($0)`, Expected: &biscuit.Expression{ biscuit.Value{Term: biscuit.Set{biscuit.Integer(4), biscuit.Integer(5), biscuit.Integer(6)}}, biscuit.Value{Term: biscuit.Variable("0")}, @@ -242,7 +242,7 @@ func TestGrammarExpression(t *testing.T) { }, }, { - Input: `["abc", "def"].contains($0)`, + Input: `{"abc", "def"}.contains($0)`, Expected: &biscuit.Expression{ biscuit.Value{Term: biscuit.Set{biscuit.String("abc"), biscuit.String("def")}}, biscuit.Value{Term: biscuit.Variable("0")}, @@ -250,7 +250,7 @@ func TestGrammarExpression(t *testing.T) { }, }, { - Input: `!["abc", "def"].contains($0)`, + Input: `!{"abc", "def"}.contains($0)`, Expected: &biscuit.Expression{ biscuit.Value{Term: biscuit.Set{biscuit.String("abc"), biscuit.String("def")}}, biscuit.Value{Term: biscuit.Variable("0")}, @@ -275,7 +275,7 @@ func TestGrammarExpression(t *testing.T) { }, }, { - Input: `[hex:41, hex:42, hex:43].contains($0)`, + Input: `{hex:41, hex:42, hex:43}.contains($0)`, Expected: &biscuit.Expression{ biscuit.Value{Term: biscuit.Set{biscuit.Bytes([]byte("A")), biscuit.Bytes([]byte("B")), biscuit.Bytes([]byte("C"))}}, @@ -284,7 +284,7 @@ func TestGrammarExpression(t *testing.T) { }, }, { - Input: `![hex:41, hex:42, hex:43].contains($0)`, + Input: `!{hex:41, hex:42, hex:43}.contains($0)`, Expected: &biscuit.Expression{ biscuit.Value{Term: biscuit.Set{biscuit.Bytes([]byte("A")), biscuit.Bytes([]byte("B")), biscuit.Bytes([]byte("C"))}}, @@ -294,7 +294,15 @@ func TestGrammarExpression(t *testing.T) { }, }, { - Input: `[hex:41].union([hex:42]).intersection([hex:41]).length() == $0`, + Input: `{1, 2}.contains({2})`, + Expected: &biscuit.Expression{ + biscuit.Value{Term: biscuit.Set{biscuit.Integer(1), biscuit.Integer(2)}}, + biscuit.Value{Term: biscuit.Set{biscuit.Integer(2)}}, + biscuit.BinaryContains, + }, + }, + { + Input: `{hex:41 }.union({hex:42}).intersection({hex:41}).length() == $0`, Expected: &biscuit.Expression{ biscuit.Value{Term: biscuit.Set{biscuit.Bytes([]byte("A"))}}, biscuit.Value{Term: biscuit.Set{biscuit.Bytes([]byte("B"))}}, diff --git a/parser/parser.go b/parser/parser.go index 5c633572..1646027b 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -24,11 +24,11 @@ var BiscuitLexerRules = []lexer.SimpleRule{ {Name: "Arrow", Pattern: `<-`}, {Name: "Or", Pattern: `\|\|`}, {Name: "And", Pattern: `&&`}, - {Name: "Operator", Pattern: `==|>=|<=|>|<|\+|-|\*`}, + {Name: "Operator", Pattern: `===|!==|==|!=|>=|<=|>|<|\+|-|\*`}, {Name: "Comment", Pattern: `//[^\n]*`}, {Name: "String", Pattern: `\"[^\"]*\"`}, {Name: "Variable", Pattern: `\$[a-zA-Z0-9_:]+`}, - {Name: "Parameter", Pattern: `\{[a-zA-Z0-9_:]+\}`}, + {Name: "Parameter", Pattern: `\{[a-zA-Z_][a-zA-Z0-9_]*\}`}, {Name: "DateTime", Pattern: `\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(Z|([-+]\d\d:\d\d))?`}, {Name: "Int", Pattern: `[0-9]+`}, {Name: "Bool", Pattern: `true|false`}, diff --git a/parser/parser_test.go b/parser/parser_test.go index d180cee2..f2e3a453 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -22,7 +22,7 @@ type testCase struct { func getFactTestCases() []testCase { return []testCase{ { - Input: `right("/a/file1.txt", "read", ["read", "/a/file2.txt"])`, + Input: `right("/a/file1.txt", "read", {"read", "/a/file2.txt"})`, Expected: biscuit.Fact{ Predicate: biscuit.Predicate{ Name: "right", @@ -51,7 +51,7 @@ func getFactTestCases() []testCase { ExpectFailure: true, }, { - Input: `right("/a/file1.txt", [$0])`, + Input: `right("/a/file1.txt", {$0})`, ExpectFailure: true, }, } @@ -162,7 +162,7 @@ func getRuleTestCases() []testCase { ExpectFailure: true, }, { - Input: `rule1("a") <- body1("b"), $0 > 0, $1 < 1, $2 >= 2, $3 <= 3, $4 == 4, [1, 2, 3].contains($5), ![4,5,6].contains($6)`, + Input: `rule1("a") <- body1("b"), $0 > 0, $1 < 1, $2 >= 2, $3 <= 3, $4 == 4, {1, 2, 3}.contains($5), !{4,5,6}.contains($6)`, Expected: biscuit.Rule{ Head: biscuit.Predicate{ Name: "rule1", @@ -213,7 +213,7 @@ func getRuleTestCases() []testCase { }, }, { - Input: `rule1("a") <- body1("b"), $0 == "abc", $1.starts_with("def"), $2.ends_with("ghi"), $3.matches("file[0-9]+.txt"), ["a","b"].contains($4), !["c", "d"].contains($5)`, + Input: `rule1("a") <- body1("b"), $0 == "abc", $1.starts_with("def"), $2.ends_with("ghi"), $3.matches("file[0-9]+.txt"), {"a", "b"}.contains($4), !{"c", "d"}.contains($5)`, Expected: biscuit.Rule{ Head: biscuit.Predicate{ Name: "rule1", @@ -259,7 +259,7 @@ func getRuleTestCases() []testCase { }, }, { - Input: `rule1("a") <- body1("b"), ["a", "b"].contains($0), !["c", "d"].contains($1)`, + Input: `rule1("a") <- body1("b"), {"a", "b"}.contains($0), !{"c", "d"}.contains($1)`, Expected: biscuit.Rule{ Head: biscuit.Predicate{ Name: "rule1", @@ -319,7 +319,7 @@ func getRuleTestCases() []testCase { }, }, { - Input: `rule1("a") <- body1($0, $1), ["abc", "def"].contains($0), ! [41, 42].contains($1)`, + Input: `rule1("a") <- body1($0, $1), {"abc", "def"}.contains($0), !{41, 42}.contains($1)`, Expected: biscuit.Rule{ Head: biscuit.Predicate{ Name: "rule1", @@ -368,7 +368,7 @@ func getRuleTestCases() []testCase { ExpectFailure: true, }, { - Input: `rule1(#a) <- body1($0, $1), $0 in [$1, "foo"]`, + Input: `rule1(#a) <- body1($0, $1), $0 in {$1, "foo"}`, ExpectFailure: true, }, { @@ -445,7 +445,7 @@ func getRuleTestCases() []testCase { func getCheckTestCases() []testCase { return []testCase{ { - Input: `check if parent("a", "b"), parent("b", "c"), [1,2,3].contains($0) or right("read", "/a/file1.txt")`, + Input: `check if parent("a", "b"), parent("b", "c"), {1,2,3}.contains($0) or right("read", "/a/file1.txt")`, Expected: biscuit.Check{ Queries: []biscuit.Rule{ { @@ -497,7 +497,7 @@ func getCheckTestCases() []testCase { }, }, { - Input: `[ caveat1($0) <- parent(#a, #b), parent(#b, #c) @ $0 in [1,2,3]`, + Input: `[ caveat1($0) <- parent(#a, #b), parent(#b, #c) @ $0 in {1,2,3}`, ExpectFailure: true, }, } diff --git a/pb/biscuit.pb.go b/pb/biscuit.pb.go index ccc6fa4e..704ba9da 100644 --- a/pb/biscuit.pb.go +++ b/pb/biscuit.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 -// protoc v3.19.4 +// protoc-gen-go v1.36.6 +// protoc v6.30.1 // source: biscuit.proto package pb @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -23,16 +24,19 @@ const ( type PublicKey_Algorithm int32 const ( - PublicKey_Ed25519 PublicKey_Algorithm = 0 + PublicKey_Ed25519 PublicKey_Algorithm = 0 + PublicKey_SECP256R1 PublicKey_Algorithm = 1 ) // Enum value maps for PublicKey_Algorithm. var ( PublicKey_Algorithm_name = map[int32]string{ 0: "Ed25519", + 1: "SECP256R1", } PublicKey_Algorithm_value = map[string]int32{ - "Ed25519": 0, + "Ed25519": 0, + "SECP256R1": 1, } ) @@ -70,7 +74,122 @@ func (x *PublicKey_Algorithm) UnmarshalJSON(b []byte) error { // Deprecated: Use PublicKey_Algorithm.Descriptor instead. func (PublicKey_Algorithm) EnumDescriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{2, 0} + return file_biscuit_proto_rawDescGZIP(), []int{3, 0} +} + +type Scope_ScopeType int32 + +const ( + Scope_Authority Scope_ScopeType = 0 + Scope_Previous Scope_ScopeType = 1 +) + +// Enum value maps for Scope_ScopeType. +var ( + Scope_ScopeType_name = map[int32]string{ + 0: "Authority", + 1: "Previous", + } + Scope_ScopeType_value = map[string]int32{ + "Authority": 0, + "Previous": 1, + } +) + +func (x Scope_ScopeType) Enum() *Scope_ScopeType { + p := new(Scope_ScopeType) + *p = x + return p +} + +func (x Scope_ScopeType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Scope_ScopeType) Descriptor() protoreflect.EnumDescriptor { + return file_biscuit_proto_enumTypes[1].Descriptor() +} + +func (Scope_ScopeType) Type() protoreflect.EnumType { + return &file_biscuit_proto_enumTypes[1] +} + +func (x Scope_ScopeType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Scope_ScopeType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Scope_ScopeType(num) + return nil +} + +// Deprecated: Use Scope_ScopeType.Descriptor instead. +func (Scope_ScopeType) EnumDescriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{6, 0} +} + +type Check_Kind int32 + +const ( + Check_One Check_Kind = 0 + Check_All Check_Kind = 1 + Check_Reject Check_Kind = 2 +) + +// Enum value maps for Check_Kind. +var ( + Check_Kind_name = map[int32]string{ + 0: "One", + 1: "All", + 2: "Reject", + } + Check_Kind_value = map[string]int32{ + "One": 0, + "All": 1, + "Reject": 2, + } +) + +func (x Check_Kind) Enum() *Check_Kind { + p := new(Check_Kind) + *p = x + return p +} + +func (x Check_Kind) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Check_Kind) Descriptor() protoreflect.EnumDescriptor { + return file_biscuit_proto_enumTypes[2].Descriptor() +} + +func (Check_Kind) Type() protoreflect.EnumType { + return &file_biscuit_proto_enumTypes[2] +} + +func (x Check_Kind) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Check_Kind) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Check_Kind(num) + return nil +} + +// Deprecated: Use Check_Kind.Descriptor instead. +func (Check_Kind) EnumDescriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{9, 0} } type OpUnary_Kind int32 @@ -79,6 +198,8 @@ const ( OpUnary_Negate OpUnary_Kind = 0 OpUnary_Parens OpUnary_Kind = 1 OpUnary_Length OpUnary_Kind = 2 + OpUnary_TypeOf OpUnary_Kind = 3 + OpUnary_Ffi OpUnary_Kind = 4 ) // Enum value maps for OpUnary_Kind. @@ -87,11 +208,15 @@ var ( 0: "Negate", 1: "Parens", 2: "Length", + 3: "TypeOf", + 4: "Ffi", } OpUnary_Kind_value = map[string]int32{ "Negate": 0, "Parens": 1, "Length": 2, + "TypeOf": 3, + "Ffi": 4, } ) @@ -106,11 +231,11 @@ func (x OpUnary_Kind) String() string { } func (OpUnary_Kind) Descriptor() protoreflect.EnumDescriptor { - return file_biscuit_proto_enumTypes[1].Descriptor() + return file_biscuit_proto_enumTypes[3].Descriptor() } func (OpUnary_Kind) Type() protoreflect.EnumType { - return &file_biscuit_proto_enumTypes[1] + return &file_biscuit_proto_enumTypes[3] } func (x OpUnary_Kind) Number() protoreflect.EnumNumber { @@ -129,29 +254,42 @@ func (x *OpUnary_Kind) UnmarshalJSON(b []byte) error { // Deprecated: Use OpUnary_Kind.Descriptor instead. func (OpUnary_Kind) EnumDescriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{13, 0} + return file_biscuit_proto_rawDescGZIP(), []int{19, 0} } type OpBinary_Kind int32 const ( - OpBinary_LessThan OpBinary_Kind = 0 - OpBinary_GreaterThan OpBinary_Kind = 1 - OpBinary_LessOrEqual OpBinary_Kind = 2 - OpBinary_GreaterOrEqual OpBinary_Kind = 3 - OpBinary_Equal OpBinary_Kind = 4 - OpBinary_Contains OpBinary_Kind = 5 - OpBinary_Prefix OpBinary_Kind = 6 - OpBinary_Suffix OpBinary_Kind = 7 - OpBinary_Regex OpBinary_Kind = 8 - OpBinary_Add OpBinary_Kind = 9 - OpBinary_Sub OpBinary_Kind = 10 - OpBinary_Mul OpBinary_Kind = 11 - OpBinary_Div OpBinary_Kind = 12 - OpBinary_And OpBinary_Kind = 13 - OpBinary_Or OpBinary_Kind = 14 - OpBinary_Intersection OpBinary_Kind = 15 - OpBinary_Union OpBinary_Kind = 16 + OpBinary_LessThan OpBinary_Kind = 0 + OpBinary_GreaterThan OpBinary_Kind = 1 + OpBinary_LessOrEqual OpBinary_Kind = 2 + OpBinary_GreaterOrEqual OpBinary_Kind = 3 + OpBinary_Equal OpBinary_Kind = 4 + OpBinary_Contains OpBinary_Kind = 5 + OpBinary_Prefix OpBinary_Kind = 6 + OpBinary_Suffix OpBinary_Kind = 7 + OpBinary_Regex OpBinary_Kind = 8 + OpBinary_Add OpBinary_Kind = 9 + OpBinary_Sub OpBinary_Kind = 10 + OpBinary_Mul OpBinary_Kind = 11 + OpBinary_Div OpBinary_Kind = 12 + OpBinary_And OpBinary_Kind = 13 + OpBinary_Or OpBinary_Kind = 14 + OpBinary_Intersection OpBinary_Kind = 15 + OpBinary_Union OpBinary_Kind = 16 + OpBinary_BitwiseAnd OpBinary_Kind = 17 + OpBinary_BitwiseOr OpBinary_Kind = 18 + OpBinary_BitwiseXor OpBinary_Kind = 19 + OpBinary_NotEqual OpBinary_Kind = 20 + OpBinary_HeterogeneousEqual OpBinary_Kind = 21 + OpBinary_HeterogeneousNotEqual OpBinary_Kind = 22 + OpBinary_LazyAnd OpBinary_Kind = 23 + OpBinary_LazyOr OpBinary_Kind = 24 + OpBinary_All OpBinary_Kind = 25 + OpBinary_Any OpBinary_Kind = 26 + OpBinary_Get OpBinary_Kind = 27 + OpBinary_Ffi OpBinary_Kind = 28 + OpBinary_TryOr OpBinary_Kind = 29 ) // Enum value maps for OpBinary_Kind. @@ -174,25 +312,51 @@ var ( 14: "Or", 15: "Intersection", 16: "Union", + 17: "BitwiseAnd", + 18: "BitwiseOr", + 19: "BitwiseXor", + 20: "NotEqual", + 21: "HeterogeneousEqual", + 22: "HeterogeneousNotEqual", + 23: "LazyAnd", + 24: "LazyOr", + 25: "All", + 26: "Any", + 27: "Get", + 28: "Ffi", + 29: "TryOr", } OpBinary_Kind_value = map[string]int32{ - "LessThan": 0, - "GreaterThan": 1, - "LessOrEqual": 2, - "GreaterOrEqual": 3, - "Equal": 4, - "Contains": 5, - "Prefix": 6, - "Suffix": 7, - "Regex": 8, - "Add": 9, - "Sub": 10, - "Mul": 11, - "Div": 12, - "And": 13, - "Or": 14, - "Intersection": 15, - "Union": 16, + "LessThan": 0, + "GreaterThan": 1, + "LessOrEqual": 2, + "GreaterOrEqual": 3, + "Equal": 4, + "Contains": 5, + "Prefix": 6, + "Suffix": 7, + "Regex": 8, + "Add": 9, + "Sub": 10, + "Mul": 11, + "Div": 12, + "And": 13, + "Or": 14, + "Intersection": 15, + "Union": 16, + "BitwiseAnd": 17, + "BitwiseOr": 18, + "BitwiseXor": 19, + "NotEqual": 20, + "HeterogeneousEqual": 21, + "HeterogeneousNotEqual": 22, + "LazyAnd": 23, + "LazyOr": 24, + "All": 25, + "Any": 26, + "Get": 27, + "Ffi": 28, + "TryOr": 29, } ) @@ -207,11 +371,11 @@ func (x OpBinary_Kind) String() string { } func (OpBinary_Kind) Descriptor() protoreflect.EnumDescriptor { - return file_biscuit_proto_enumTypes[2].Descriptor() + return file_biscuit_proto_enumTypes[4].Descriptor() } func (OpBinary_Kind) Type() protoreflect.EnumType { - return &file_biscuit_proto_enumTypes[2] + return &file_biscuit_proto_enumTypes[4] } func (x OpBinary_Kind) Number() protoreflect.EnumNumber { @@ -230,7 +394,7 @@ func (x *OpBinary_Kind) UnmarshalJSON(b []byte) error { // Deprecated: Use OpBinary_Kind.Descriptor instead. func (OpBinary_Kind) EnumDescriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{14, 0} + return file_biscuit_proto_rawDescGZIP(), []int{20, 0} } type Policy_Kind int32 @@ -263,11 +427,11 @@ func (x Policy_Kind) String() string { } func (Policy_Kind) Descriptor() protoreflect.EnumDescriptor { - return file_biscuit_proto_enumTypes[3].Descriptor() + return file_biscuit_proto_enumTypes[5].Descriptor() } func (Policy_Kind) Type() protoreflect.EnumType { - return &file_biscuit_proto_enumTypes[3] + return &file_biscuit_proto_enumTypes[5] } func (x Policy_Kind) Number() protoreflect.EnumNumber { @@ -286,27 +450,24 @@ func (x *Policy_Kind) UnmarshalJSON(b []byte) error { // Deprecated: Use Policy_Kind.Descriptor instead. func (Policy_Kind) EnumDescriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{15, 0} + return file_biscuit_proto_rawDescGZIP(), []int{22, 0} } type Biscuit struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + RootKeyId *uint32 `protobuf:"varint,1,opt,name=rootKeyId" json:"rootKeyId,omitempty"` + Authority *SignedBlock `protobuf:"bytes,2,req,name=authority" json:"authority,omitempty"` + Blocks []*SignedBlock `protobuf:"bytes,3,rep,name=blocks" json:"blocks,omitempty"` + Proof *Proof `protobuf:"bytes,4,req,name=proof" json:"proof,omitempty"` unknownFields protoimpl.UnknownFields - - RootKeyId *uint32 `protobuf:"varint,1,opt,name=rootKeyId" json:"rootKeyId,omitempty"` - Authority *SignedBlock `protobuf:"bytes,2,req,name=authority" json:"authority,omitempty"` - Blocks []*SignedBlock `protobuf:"bytes,3,rep,name=blocks" json:"blocks,omitempty"` - Proof *Proof `protobuf:"bytes,4,req,name=proof" json:"proof,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Biscuit) Reset() { *x = Biscuit{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_biscuit_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Biscuit) String() string { @@ -317,7 +478,7 @@ func (*Biscuit) ProtoMessage() {} func (x *Biscuit) ProtoReflect() protoreflect.Message { mi := &file_biscuit_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -361,22 +522,21 @@ func (x *Biscuit) GetProof() *Proof { } type SignedBlock struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Block []byte `protobuf:"bytes,1,req,name=block" json:"block,omitempty"` - NextKey *PublicKey `protobuf:"bytes,2,req,name=nextKey" json:"nextKey,omitempty"` - Signature []byte `protobuf:"bytes,3,req,name=signature" json:"signature,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Block []byte `protobuf:"bytes,1,req,name=block" json:"block,omitempty"` + NextKey *PublicKey `protobuf:"bytes,2,req,name=nextKey" json:"nextKey,omitempty"` + Signature []byte `protobuf:"bytes,3,req,name=signature" json:"signature,omitempty"` + ExternalSignature *ExternalSignature `protobuf:"bytes,4,opt,name=externalSignature" json:"externalSignature,omitempty"` + Version *uint32 `protobuf:"varint,5,opt,name=version" json:"version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SignedBlock) Reset() { *x = SignedBlock{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_biscuit_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SignedBlock) String() string { @@ -387,7 +547,7 @@ func (*SignedBlock) ProtoMessage() {} func (x *SignedBlock) ProtoReflect() protoreflect.Message { mi := &file_biscuit_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -423,22 +583,85 @@ func (x *SignedBlock) GetSignature() []byte { return nil } -type PublicKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +func (x *SignedBlock) GetExternalSignature() *ExternalSignature { + if x != nil { + return x.ExternalSignature + } + return nil +} + +func (x *SignedBlock) GetVersion() uint32 { + if x != nil && x.Version != nil { + return *x.Version + } + return 0 +} + +type ExternalSignature struct { + state protoimpl.MessageState `protogen:"open.v1"` + Signature []byte `protobuf:"bytes,1,req,name=signature" json:"signature,omitempty"` + PublicKey *PublicKey `protobuf:"bytes,2,req,name=publicKey" json:"publicKey,omitempty"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} - Algorithm *PublicKey_Algorithm `protobuf:"varint,1,req,name=algorithm,enum=PublicKey_Algorithm" json:"algorithm,omitempty"` - Key []byte `protobuf:"bytes,2,req,name=key" json:"key,omitempty"` +func (x *ExternalSignature) Reset() { + *x = ExternalSignature{} + mi := &file_biscuit_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *PublicKey) Reset() { - *x = PublicKey{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[2] +func (x *ExternalSignature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalSignature) ProtoMessage() {} + +func (x *ExternalSignature) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[2] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExternalSignature.ProtoReflect.Descriptor instead. +func (*ExternalSignature) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{2} +} + +func (x *ExternalSignature) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +func (x *ExternalSignature) GetPublicKey() *PublicKey { + if x != nil { + return x.PublicKey } + return nil +} + +type PublicKey struct { + state protoimpl.MessageState `protogen:"open.v1"` + Algorithm *PublicKey_Algorithm `protobuf:"varint,1,req,name=algorithm,enum=biscuit.format.schema.PublicKey_Algorithm" json:"algorithm,omitempty"` + Key []byte `protobuf:"bytes,2,req,name=key" json:"key,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PublicKey) Reset() { + *x = PublicKey{} + mi := &file_biscuit_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PublicKey) String() string { @@ -448,8 +671,8 @@ func (x *PublicKey) String() string { func (*PublicKey) ProtoMessage() {} func (x *PublicKey) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_biscuit_proto_msgTypes[3] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -461,7 +684,7 @@ func (x *PublicKey) ProtoReflect() protoreflect.Message { // Deprecated: Use PublicKey.ProtoReflect.Descriptor instead. func (*PublicKey) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{2} + return file_biscuit_proto_rawDescGZIP(), []int{3} } func (x *PublicKey) GetAlgorithm() PublicKey_Algorithm { @@ -479,23 +702,21 @@ func (x *PublicKey) GetKey() []byte { } type Proof struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Content: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // // *Proof_NextSecret // *Proof_FinalSignature - Content isProof_Content `protobuf_oneof:"Content"` + Content isProof_Content `protobuf_oneof:"Content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Proof) Reset() { *x = Proof{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_biscuit_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Proof) String() string { @@ -505,8 +726,8 @@ func (x *Proof) String() string { func (*Proof) ProtoMessage() {} func (x *Proof) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_biscuit_proto_msgTypes[4] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -518,26 +739,30 @@ func (x *Proof) ProtoReflect() protoreflect.Message { // Deprecated: Use Proof.ProtoReflect.Descriptor instead. func (*Proof) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{3} + return file_biscuit_proto_rawDescGZIP(), []int{4} } -func (m *Proof) GetContent() isProof_Content { - if m != nil { - return m.Content +func (x *Proof) GetContent() isProof_Content { + if x != nil { + return x.Content } return nil } func (x *Proof) GetNextSecret() []byte { - if x, ok := x.GetContent().(*Proof_NextSecret); ok { - return x.NextSecret + if x != nil { + if x, ok := x.Content.(*Proof_NextSecret); ok { + return x.NextSecret + } } return nil } func (x *Proof) GetFinalSignature() []byte { - if x, ok := x.GetContent().(*Proof_FinalSignature); ok { - return x.FinalSignature + if x != nil { + if x, ok := x.Content.(*Proof_FinalSignature); ok { + return x.FinalSignature + } } return nil } @@ -559,25 +784,24 @@ func (*Proof_NextSecret) isProof_Content() {} func (*Proof_FinalSignature) isProof_Content() {} type Block struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Symbols []string `protobuf:"bytes,1,rep,name=symbols" json:"symbols,omitempty"` + Context *string `protobuf:"bytes,2,opt,name=context" json:"context,omitempty"` + Version *uint32 `protobuf:"varint,3,opt,name=version" json:"version,omitempty"` + Facts []*Fact `protobuf:"bytes,4,rep,name=facts" json:"facts,omitempty"` + Rules []*Rule `protobuf:"bytes,5,rep,name=rules" json:"rules,omitempty"` + Checks []*Check `protobuf:"bytes,6,rep,name=checks" json:"checks,omitempty"` + Scope []*Scope `protobuf:"bytes,7,rep,name=scope" json:"scope,omitempty"` + PublicKeys []*PublicKey `protobuf:"bytes,8,rep,name=publicKeys" json:"publicKeys,omitempty"` unknownFields protoimpl.UnknownFields - - Symbols []string `protobuf:"bytes,1,rep,name=symbols" json:"symbols,omitempty"` - Context *string `protobuf:"bytes,2,opt,name=context" json:"context,omitempty"` - Version *uint32 `protobuf:"varint,3,opt,name=version" json:"version,omitempty"` - FactsV2 []*FactV2 `protobuf:"bytes,4,rep,name=facts_v2,json=factsV2" json:"facts_v2,omitempty"` - RulesV2 []*RuleV2 `protobuf:"bytes,5,rep,name=rules_v2,json=rulesV2" json:"rules_v2,omitempty"` - ChecksV2 []*CheckV2 `protobuf:"bytes,6,rep,name=checks_v2,json=checksV2" json:"checks_v2,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Block) Reset() { *x = Block{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_biscuit_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Block) String() string { @@ -587,8 +811,8 @@ func (x *Block) String() string { func (*Block) ProtoMessage() {} func (x *Block) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_biscuit_proto_msgTypes[5] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -600,7 +824,7 @@ func (x *Block) ProtoReflect() protoreflect.Message { // Deprecated: Use Block.ProtoReflect.Descriptor instead. func (*Block) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{4} + return file_biscuit_proto_rawDescGZIP(), []int{5} } func (x *Block) GetSymbols() []string { @@ -624,102 +848,68 @@ func (x *Block) GetVersion() uint32 { return 0 } -func (x *Block) GetFactsV2() []*FactV2 { +func (x *Block) GetFacts() []*Fact { if x != nil { - return x.FactsV2 + return x.Facts } return nil } -func (x *Block) GetRulesV2() []*RuleV2 { +func (x *Block) GetRules() []*Rule { if x != nil { - return x.RulesV2 + return x.Rules } return nil } -func (x *Block) GetChecksV2() []*CheckV2 { +func (x *Block) GetChecks() []*Check { if x != nil { - return x.ChecksV2 + return x.Checks } return nil } -type FactV2 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Predicate *PredicateV2 `protobuf:"bytes,1,req,name=predicate" json:"predicate,omitempty"` -} - -func (x *FactV2) Reset() { - *x = FactV2{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FactV2) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FactV2) ProtoMessage() {} - -func (x *FactV2) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms +func (x *Block) GetScope() []*Scope { + if x != nil { + return x.Scope } - return mi.MessageOf(x) -} - -// Deprecated: Use FactV2.ProtoReflect.Descriptor instead. -func (*FactV2) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{5} + return nil } -func (x *FactV2) GetPredicate() *PredicateV2 { +func (x *Block) GetPublicKeys() []*PublicKey { if x != nil { - return x.Predicate + return x.PublicKeys } return nil } -type RuleV2 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type Scope struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *Scope_ScopeType_ + // *Scope_PublicKey + Content isScope_Content `protobuf_oneof:"Content"` unknownFields protoimpl.UnknownFields - - Head *PredicateV2 `protobuf:"bytes,1,req,name=head" json:"head,omitempty"` - Body []*PredicateV2 `protobuf:"bytes,2,rep,name=body" json:"body,omitempty"` - Expressions []*ExpressionV2 `protobuf:"bytes,3,rep,name=expressions" json:"expressions,omitempty"` + sizeCache protoimpl.SizeCache } -func (x *RuleV2) Reset() { - *x = RuleV2{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *Scope) Reset() { + *x = Scope{} + mi := &file_biscuit_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *RuleV2) String() string { +func (x *Scope) String() string { return protoimpl.X.MessageStringOf(x) } -func (*RuleV2) ProtoMessage() {} +func (*Scope) ProtoMessage() {} -func (x *RuleV2) ProtoReflect() protoreflect.Message { +func (x *Scope) ProtoReflect() protoreflect.Message { mi := &file_biscuit_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -729,58 +919,75 @@ func (x *RuleV2) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use RuleV2.ProtoReflect.Descriptor instead. -func (*RuleV2) Descriptor() ([]byte, []int) { +// Deprecated: Use Scope.ProtoReflect.Descriptor instead. +func (*Scope) Descriptor() ([]byte, []int) { return file_biscuit_proto_rawDescGZIP(), []int{6} } -func (x *RuleV2) GetHead() *PredicateV2 { +func (x *Scope) GetContent() isScope_Content { if x != nil { - return x.Head + return x.Content } return nil } -func (x *RuleV2) GetBody() []*PredicateV2 { +func (x *Scope) GetScopeType() Scope_ScopeType { if x != nil { - return x.Body + if x, ok := x.Content.(*Scope_ScopeType_); ok { + return x.ScopeType + } } - return nil + return Scope_Authority } -func (x *RuleV2) GetExpressions() []*ExpressionV2 { +func (x *Scope) GetPublicKey() int64 { if x != nil { - return x.Expressions + if x, ok := x.Content.(*Scope_PublicKey); ok { + return x.PublicKey + } } - return nil + return 0 } -type CheckV2 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields +type isScope_Content interface { + isScope_Content() +} - Queries []*RuleV2 `protobuf:"bytes,1,rep,name=queries" json:"queries,omitempty"` +type Scope_ScopeType_ struct { + ScopeType Scope_ScopeType `protobuf:"varint,1,opt,name=scopeType,enum=biscuit.format.schema.Scope_ScopeType,oneof"` } -func (x *CheckV2) Reset() { - *x = CheckV2{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +type Scope_PublicKey struct { + PublicKey int64 `protobuf:"varint,2,opt,name=publicKey,oneof"` +} + +func (*Scope_ScopeType_) isScope_Content() {} + +func (*Scope_PublicKey) isScope_Content() {} + +type Fact struct { + state protoimpl.MessageState `protogen:"open.v1"` + Predicate *Predicate `protobuf:"bytes,1,req,name=predicate" json:"predicate,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Fact) Reset() { + *x = Fact{} + mi := &file_biscuit_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *CheckV2) String() string { +func (x *Fact) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CheckV2) ProtoMessage() {} +func (*Fact) ProtoMessage() {} -func (x *CheckV2) ProtoReflect() protoreflect.Message { +func (x *Fact) ProtoReflect() protoreflect.Message { mi := &file_biscuit_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -790,45 +997,44 @@ func (x *CheckV2) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CheckV2.ProtoReflect.Descriptor instead. -func (*CheckV2) Descriptor() ([]byte, []int) { +// Deprecated: Use Fact.ProtoReflect.Descriptor instead. +func (*Fact) Descriptor() ([]byte, []int) { return file_biscuit_proto_rawDescGZIP(), []int{7} } -func (x *CheckV2) GetQueries() []*RuleV2 { +func (x *Fact) GetPredicate() *Predicate { if x != nil { - return x.Queries + return x.Predicate } return nil } -type PredicateV2 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type Rule struct { + state protoimpl.MessageState `protogen:"open.v1"` + Head *Predicate `protobuf:"bytes,1,req,name=head" json:"head,omitempty"` + Body []*Predicate `protobuf:"bytes,2,rep,name=body" json:"body,omitempty"` + Expressions []*Expression `protobuf:"bytes,3,rep,name=expressions" json:"expressions,omitempty"` + Scope []*Scope `protobuf:"bytes,4,rep,name=scope" json:"scope,omitempty"` unknownFields protoimpl.UnknownFields - - Name *uint64 `protobuf:"varint,1,req,name=name" json:"name,omitempty"` - Terms []*TermV2 `protobuf:"bytes,2,rep,name=terms" json:"terms,omitempty"` + sizeCache protoimpl.SizeCache } -func (x *PredicateV2) Reset() { - *x = PredicateV2{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *Rule) Reset() { + *x = Rule{} + mi := &file_biscuit_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *PredicateV2) String() string { +func (x *Rule) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PredicateV2) ProtoMessage() {} +func (*Rule) ProtoMessage() {} -func (x *PredicateV2) ProtoReflect() protoreflect.Message { +func (x *Rule) ProtoReflect() protoreflect.Message { mi := &file_biscuit_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -838,59 +1044,63 @@ func (x *PredicateV2) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PredicateV2.ProtoReflect.Descriptor instead. -func (*PredicateV2) Descriptor() ([]byte, []int) { +// Deprecated: Use Rule.ProtoReflect.Descriptor instead. +func (*Rule) Descriptor() ([]byte, []int) { return file_biscuit_proto_rawDescGZIP(), []int{8} } -func (x *PredicateV2) GetName() uint64 { - if x != nil && x.Name != nil { - return *x.Name +func (x *Rule) GetHead() *Predicate { + if x != nil { + return x.Head } - return 0 + return nil } -func (x *PredicateV2) GetTerms() []*TermV2 { +func (x *Rule) GetBody() []*Predicate { if x != nil { - return x.Terms + return x.Body } return nil } -type TermV2 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields +func (x *Rule) GetExpressions() []*Expression { + if x != nil { + return x.Expressions + } + return nil +} - // Types that are assignable to Content: - // *TermV2_Variable - // *TermV2_Integer - // *TermV2_String_ - // *TermV2_Date - // *TermV2_Bytes - // *TermV2_Bool - // *TermV2_Set - Content isTermV2_Content `protobuf_oneof:"Content"` -} - -func (x *TermV2) Reset() { - *x = TermV2{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *Rule) GetScope() []*Scope { + if x != nil { + return x.Scope } + return nil +} + +type Check struct { + state protoimpl.MessageState `protogen:"open.v1"` + Queries []*Rule `protobuf:"bytes,1,rep,name=queries" json:"queries,omitempty"` + Kind *Check_Kind `protobuf:"varint,2,opt,name=kind,enum=biscuit.format.schema.Check_Kind" json:"kind,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Check) Reset() { + *x = Check{} + mi := &file_biscuit_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *TermV2) String() string { +func (x *Check) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TermV2) ProtoMessage() {} +func (*Check) ProtoMessage() {} -func (x *TermV2) ProtoReflect() protoreflect.Message { +func (x *Check) ProtoReflect() protoreflect.Message { mi := &file_biscuit_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -900,139 +1110,1140 @@ func (x *TermV2) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TermV2.ProtoReflect.Descriptor instead. -func (*TermV2) Descriptor() ([]byte, []int) { +// Deprecated: Use Check.ProtoReflect.Descriptor instead. +func (*Check) Descriptor() ([]byte, []int) { return file_biscuit_proto_rawDescGZIP(), []int{9} } -func (m *TermV2) GetContent() isTermV2_Content { - if m != nil { - return m.Content +func (x *Check) GetQueries() []*Rule { + if x != nil { + return x.Queries + } + return nil +} + +func (x *Check) GetKind() Check_Kind { + if x != nil && x.Kind != nil { + return *x.Kind + } + return Check_One +} + +type Predicate struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *uint64 `protobuf:"varint,1,req,name=name" json:"name,omitempty"` + Terms []*Term `protobuf:"bytes,2,rep,name=terms" json:"terms,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Predicate) Reset() { + *x = Predicate{} + mi := &file_biscuit_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Predicate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Predicate) ProtoMessage() {} + +func (x *Predicate) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Predicate.ProtoReflect.Descriptor instead. +func (*Predicate) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{10} +} + +func (x *Predicate) GetName() uint64 { + if x != nil && x.Name != nil { + return *x.Name + } + return 0 +} + +func (x *Predicate) GetTerms() []*Term { + if x != nil { + return x.Terms + } + return nil +} + +type Term struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *Term_Variable + // *Term_Integer + // *Term_String_ + // *Term_Date + // *Term_Bytes + // *Term_Bool + // *Term_Set + // *Term_Null + // *Term_Array + // *Term_Map + Content isTerm_Content `protobuf_oneof:"Content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Term) Reset() { + *x = Term{} + mi := &file_biscuit_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Term) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Term) ProtoMessage() {} + +func (x *Term) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Term.ProtoReflect.Descriptor instead. +func (*Term) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{11} +} + +func (x *Term) GetContent() isTerm_Content { + if x != nil { + return x.Content } return nil } -func (x *TermV2) GetVariable() uint32 { - if x, ok := x.GetContent().(*TermV2_Variable); ok { - return x.Variable +func (x *Term) GetVariable() uint32 { + if x != nil { + if x, ok := x.Content.(*Term_Variable); ok { + return x.Variable + } } return 0 } -func (x *TermV2) GetInteger() int64 { - if x, ok := x.GetContent().(*TermV2_Integer); ok { - return x.Integer +func (x *Term) GetInteger() int64 { + if x != nil { + if x, ok := x.Content.(*Term_Integer); ok { + return x.Integer + } } return 0 } -func (x *TermV2) GetString_() uint64 { - if x, ok := x.GetContent().(*TermV2_String_); ok { - return x.String_ +func (x *Term) GetString_() uint64 { + if x != nil { + if x, ok := x.Content.(*Term_String_); ok { + return x.String_ + } } return 0 } -func (x *TermV2) GetDate() uint64 { - if x, ok := x.GetContent().(*TermV2_Date); ok { - return x.Date +func (x *Term) GetDate() uint64 { + if x != nil { + if x, ok := x.Content.(*Term_Date); ok { + return x.Date + } } return 0 } -func (x *TermV2) GetBytes() []byte { - if x, ok := x.GetContent().(*TermV2_Bytes); ok { - return x.Bytes +func (x *Term) GetBytes() []byte { + if x != nil { + if x, ok := x.Content.(*Term_Bytes); ok { + return x.Bytes + } } return nil } -func (x *TermV2) GetBool() bool { - if x, ok := x.GetContent().(*TermV2_Bool); ok { - return x.Bool +func (x *Term) GetBool() bool { + if x != nil { + if x, ok := x.Content.(*Term_Bool); ok { + return x.Bool + } } return false } -func (x *TermV2) GetSet() *TermSet { - if x, ok := x.GetContent().(*TermV2_Set); ok { - return x.Set +func (x *Term) GetSet() *TermSet { + if x != nil { + if x, ok := x.Content.(*Term_Set); ok { + return x.Set + } + } + return nil +} + +func (x *Term) GetNull() *Empty { + if x != nil { + if x, ok := x.Content.(*Term_Null); ok { + return x.Null + } } return nil } -type isTermV2_Content interface { - isTermV2_Content() +func (x *Term) GetArray() *Array { + if x != nil { + if x, ok := x.Content.(*Term_Array); ok { + return x.Array + } + } + return nil +} + +func (x *Term) GetMap() *Map { + if x != nil { + if x, ok := x.Content.(*Term_Map); ok { + return x.Map + } + } + return nil +} + +type isTerm_Content interface { + isTerm_Content() } -type TermV2_Variable struct { +type Term_Variable struct { Variable uint32 `protobuf:"varint,1,opt,name=variable,oneof"` } -type TermV2_Integer struct { +type Term_Integer struct { Integer int64 `protobuf:"varint,2,opt,name=integer,oneof"` } -type TermV2_String_ struct { +type Term_String_ struct { String_ uint64 `protobuf:"varint,3,opt,name=string,oneof"` } -type TermV2_Date struct { +type Term_Date struct { Date uint64 `protobuf:"varint,4,opt,name=date,oneof"` } -type TermV2_Bytes struct { - Bytes []byte `protobuf:"bytes,5,opt,name=bytes,oneof"` +type Term_Bytes struct { + Bytes []byte `protobuf:"bytes,5,opt,name=bytes,oneof"` +} + +type Term_Bool struct { + Bool bool `protobuf:"varint,6,opt,name=bool,oneof"` +} + +type Term_Set struct { + Set *TermSet `protobuf:"bytes,7,opt,name=set,oneof"` +} + +type Term_Null struct { + Null *Empty `protobuf:"bytes,8,opt,name=null,oneof"` +} + +type Term_Array struct { + Array *Array `protobuf:"bytes,9,opt,name=array,oneof"` +} + +type Term_Map struct { + Map *Map `protobuf:"bytes,10,opt,name=map,oneof"` +} + +func (*Term_Variable) isTerm_Content() {} + +func (*Term_Integer) isTerm_Content() {} + +func (*Term_String_) isTerm_Content() {} + +func (*Term_Date) isTerm_Content() {} + +func (*Term_Bytes) isTerm_Content() {} + +func (*Term_Bool) isTerm_Content() {} + +func (*Term_Set) isTerm_Content() {} + +func (*Term_Null) isTerm_Content() {} + +func (*Term_Array) isTerm_Content() {} + +func (*Term_Map) isTerm_Content() {} + +type TermSet struct { + state protoimpl.MessageState `protogen:"open.v1"` + Set []*Term `protobuf:"bytes,1,rep,name=set" json:"set,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TermSet) Reset() { + *x = TermSet{} + mi := &file_biscuit_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TermSet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TermSet) ProtoMessage() {} + +func (x *TermSet) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TermSet.ProtoReflect.Descriptor instead. +func (*TermSet) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{12} +} + +func (x *TermSet) GetSet() []*Term { + if x != nil { + return x.Set + } + return nil +} + +type Array struct { + state protoimpl.MessageState `protogen:"open.v1"` + Array []*Term `protobuf:"bytes,1,rep,name=array" json:"array,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Array) Reset() { + *x = Array{} + mi := &file_biscuit_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Array) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Array) ProtoMessage() {} + +func (x *Array) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Array.ProtoReflect.Descriptor instead. +func (*Array) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{13} +} + +func (x *Array) GetArray() []*Term { + if x != nil { + return x.Array + } + return nil +} + +type Map struct { + state protoimpl.MessageState `protogen:"open.v1"` + Entries []*MapEntry `protobuf:"bytes,1,rep,name=entries" json:"entries,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Map) Reset() { + *x = Map{} + mi := &file_biscuit_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Map) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Map) ProtoMessage() {} + +func (x *Map) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Map.ProtoReflect.Descriptor instead. +func (*Map) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{14} +} + +func (x *Map) GetEntries() []*MapEntry { + if x != nil { + return x.Entries + } + return nil +} + +type MapEntry struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key *MapKey `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` + Value *Term `protobuf:"bytes,2,req,name=value" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MapEntry) Reset() { + *x = MapEntry{} + mi := &file_biscuit_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MapEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MapEntry) ProtoMessage() {} + +func (x *MapEntry) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MapEntry.ProtoReflect.Descriptor instead. +func (*MapEntry) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{15} +} + +func (x *MapEntry) GetKey() *MapKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *MapEntry) GetValue() *Term { + if x != nil { + return x.Value + } + return nil +} + +type MapKey struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *MapKey_Integer + // *MapKey_String_ + Content isMapKey_Content `protobuf_oneof:"Content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MapKey) Reset() { + *x = MapKey{} + mi := &file_biscuit_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MapKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MapKey) ProtoMessage() {} + +func (x *MapKey) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MapKey.ProtoReflect.Descriptor instead. +func (*MapKey) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{16} +} + +func (x *MapKey) GetContent() isMapKey_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *MapKey) GetInteger() int64 { + if x != nil { + if x, ok := x.Content.(*MapKey_Integer); ok { + return x.Integer + } + } + return 0 +} + +func (x *MapKey) GetString_() uint64 { + if x != nil { + if x, ok := x.Content.(*MapKey_String_); ok { + return x.String_ + } + } + return 0 +} + +type isMapKey_Content interface { + isMapKey_Content() +} + +type MapKey_Integer struct { + Integer int64 `protobuf:"varint,1,opt,name=integer,oneof"` +} + +type MapKey_String_ struct { + String_ uint64 `protobuf:"varint,2,opt,name=string,oneof"` +} + +func (*MapKey_Integer) isMapKey_Content() {} + +func (*MapKey_String_) isMapKey_Content() {} + +type Expression struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ops []*Op `protobuf:"bytes,1,rep,name=ops" json:"ops,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Expression) Reset() { + *x = Expression{} + mi := &file_biscuit_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Expression) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Expression) ProtoMessage() {} + +func (x *Expression) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Expression.ProtoReflect.Descriptor instead. +func (*Expression) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{17} +} + +func (x *Expression) GetOps() []*Op { + if x != nil { + return x.Ops + } + return nil +} + +type Op struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *Op_Value + // *Op_Unary + // *Op_Binary + // *Op_Closure + Content isOp_Content `protobuf_oneof:"Content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Op) Reset() { + *x = Op{} + mi := &file_biscuit_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Op) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Op) ProtoMessage() {} + +func (x *Op) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Op.ProtoReflect.Descriptor instead. +func (*Op) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{18} +} + +func (x *Op) GetContent() isOp_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *Op) GetValue() *Term { + if x != nil { + if x, ok := x.Content.(*Op_Value); ok { + return x.Value + } + } + return nil +} + +func (x *Op) GetUnary() *OpUnary { + if x != nil { + if x, ok := x.Content.(*Op_Unary); ok { + return x.Unary + } + } + return nil +} + +func (x *Op) GetBinary() *OpBinary { + if x != nil { + if x, ok := x.Content.(*Op_Binary); ok { + return x.Binary + } + } + return nil +} + +func (x *Op) GetClosure() *OpClosure { + if x != nil { + if x, ok := x.Content.(*Op_Closure); ok { + return x.Closure + } + } + return nil +} + +type isOp_Content interface { + isOp_Content() +} + +type Op_Value struct { + Value *Term `protobuf:"bytes,1,opt,name=value,oneof"` +} + +type Op_Unary struct { + Unary *OpUnary `protobuf:"bytes,2,opt,name=unary,oneof"` +} + +type Op_Binary struct { + Binary *OpBinary `protobuf:"bytes,3,opt,name=Binary,oneof"` +} + +type Op_Closure struct { + Closure *OpClosure `protobuf:"bytes,4,opt,name=closure,oneof"` +} + +func (*Op_Value) isOp_Content() {} + +func (*Op_Unary) isOp_Content() {} + +func (*Op_Binary) isOp_Content() {} + +func (*Op_Closure) isOp_Content() {} + +type OpUnary struct { + state protoimpl.MessageState `protogen:"open.v1"` + Kind *OpUnary_Kind `protobuf:"varint,1,req,name=kind,enum=biscuit.format.schema.OpUnary_Kind" json:"kind,omitempty"` + FfiName *uint64 `protobuf:"varint,2,opt,name=ffiName" json:"ffiName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpUnary) Reset() { + *x = OpUnary{} + mi := &file_biscuit_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpUnary) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpUnary) ProtoMessage() {} + +func (x *OpUnary) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OpUnary.ProtoReflect.Descriptor instead. +func (*OpUnary) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{19} +} + +func (x *OpUnary) GetKind() OpUnary_Kind { + if x != nil && x.Kind != nil { + return *x.Kind + } + return OpUnary_Negate +} + +func (x *OpUnary) GetFfiName() uint64 { + if x != nil && x.FfiName != nil { + return *x.FfiName + } + return 0 +} + +type OpBinary struct { + state protoimpl.MessageState `protogen:"open.v1"` + Kind *OpBinary_Kind `protobuf:"varint,1,req,name=kind,enum=biscuit.format.schema.OpBinary_Kind" json:"kind,omitempty"` + FfiName *uint64 `protobuf:"varint,2,opt,name=ffiName" json:"ffiName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpBinary) Reset() { + *x = OpBinary{} + mi := &file_biscuit_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpBinary) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpBinary) ProtoMessage() {} + +func (x *OpBinary) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OpBinary.ProtoReflect.Descriptor instead. +func (*OpBinary) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{20} +} + +func (x *OpBinary) GetKind() OpBinary_Kind { + if x != nil && x.Kind != nil { + return *x.Kind + } + return OpBinary_LessThan +} + +func (x *OpBinary) GetFfiName() uint64 { + if x != nil && x.FfiName != nil { + return *x.FfiName + } + return 0 +} + +type OpClosure struct { + state protoimpl.MessageState `protogen:"open.v1"` + Params []uint32 `protobuf:"varint,1,rep,name=params" json:"params,omitempty"` + Ops []*Op `protobuf:"bytes,2,rep,name=ops" json:"ops,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpClosure) Reset() { + *x = OpClosure{} + mi := &file_biscuit_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpClosure) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpClosure) ProtoMessage() {} + +func (x *OpClosure) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OpClosure.ProtoReflect.Descriptor instead. +func (*OpClosure) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{21} +} + +func (x *OpClosure) GetParams() []uint32 { + if x != nil { + return x.Params + } + return nil +} + +func (x *OpClosure) GetOps() []*Op { + if x != nil { + return x.Ops + } + return nil +} + +type Policy struct { + state protoimpl.MessageState `protogen:"open.v1"` + Queries []*Rule `protobuf:"bytes,1,rep,name=queries" json:"queries,omitempty"` + Kind *Policy_Kind `protobuf:"varint,2,req,name=kind,enum=biscuit.format.schema.Policy_Kind" json:"kind,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Policy) Reset() { + *x = Policy{} + mi := &file_biscuit_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Policy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Policy) ProtoMessage() {} + +func (x *Policy) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Policy.ProtoReflect.Descriptor instead. +func (*Policy) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{22} +} + +func (x *Policy) GetQueries() []*Rule { + if x != nil { + return x.Queries + } + return nil +} + +func (x *Policy) GetKind() Policy_Kind { + if x != nil && x.Kind != nil { + return *x.Kind + } + return Policy_Allow +} + +type AuthorizerPolicies struct { + state protoimpl.MessageState `protogen:"open.v1"` + Symbols []string `protobuf:"bytes,1,rep,name=symbols" json:"symbols,omitempty"` + Version *uint32 `protobuf:"varint,2,opt,name=version" json:"version,omitempty"` + Facts []*Fact `protobuf:"bytes,3,rep,name=facts" json:"facts,omitempty"` + Rules []*Rule `protobuf:"bytes,4,rep,name=rules" json:"rules,omitempty"` + Checks []*Check `protobuf:"bytes,5,rep,name=checks" json:"checks,omitempty"` + Policies []*Policy `protobuf:"bytes,6,rep,name=policies" json:"policies,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AuthorizerPolicies) Reset() { + *x = AuthorizerPolicies{} + mi := &file_biscuit_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AuthorizerPolicies) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorizerPolicies) ProtoMessage() {} + +func (x *AuthorizerPolicies) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthorizerPolicies.ProtoReflect.Descriptor instead. +func (*AuthorizerPolicies) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{23} +} + +func (x *AuthorizerPolicies) GetSymbols() []string { + if x != nil { + return x.Symbols + } + return nil +} + +func (x *AuthorizerPolicies) GetVersion() uint32 { + if x != nil && x.Version != nil { + return *x.Version + } + return 0 +} + +func (x *AuthorizerPolicies) GetFacts() []*Fact { + if x != nil { + return x.Facts + } + return nil +} + +func (x *AuthorizerPolicies) GetRules() []*Rule { + if x != nil { + return x.Rules + } + return nil +} + +func (x *AuthorizerPolicies) GetChecks() []*Check { + if x != nil { + return x.Checks + } + return nil +} + +func (x *AuthorizerPolicies) GetPolicies() []*Policy { + if x != nil { + return x.Policies + } + return nil +} + +type ThirdPartyBlockRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + LegacyPreviousKey *PublicKey `protobuf:"bytes,1,opt,name=legacyPreviousKey" json:"legacyPreviousKey,omitempty"` + LegacyPublicKeys []*PublicKey `protobuf:"bytes,2,rep,name=legacyPublicKeys" json:"legacyPublicKeys,omitempty"` + PreviousSignature []byte `protobuf:"bytes,3,req,name=previousSignature" json:"previousSignature,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThirdPartyBlockRequest) Reset() { + *x = ThirdPartyBlockRequest{} + mi := &file_biscuit_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThirdPartyBlockRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThirdPartyBlockRequest) ProtoMessage() {} + +func (x *ThirdPartyBlockRequest) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThirdPartyBlockRequest.ProtoReflect.Descriptor instead. +func (*ThirdPartyBlockRequest) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{24} +} + +func (x *ThirdPartyBlockRequest) GetLegacyPreviousKey() *PublicKey { + if x != nil { + return x.LegacyPreviousKey + } + return nil +} + +func (x *ThirdPartyBlockRequest) GetLegacyPublicKeys() []*PublicKey { + if x != nil { + return x.LegacyPublicKeys + } + return nil +} + +func (x *ThirdPartyBlockRequest) GetPreviousSignature() []byte { + if x != nil { + return x.PreviousSignature + } + return nil +} + +type ThirdPartyBlockContents struct { + state protoimpl.MessageState `protogen:"open.v1"` + Payload []byte `protobuf:"bytes,1,req,name=payload" json:"payload,omitempty"` + ExternalSignature *ExternalSignature `protobuf:"bytes,2,req,name=externalSignature" json:"externalSignature,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThirdPartyBlockContents) Reset() { + *x = ThirdPartyBlockContents{} + mi := &file_biscuit_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThirdPartyBlockContents) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThirdPartyBlockContents) ProtoMessage() {} + +func (x *ThirdPartyBlockContents) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThirdPartyBlockContents.ProtoReflect.Descriptor instead. +func (*ThirdPartyBlockContents) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{25} } -type TermV2_Bool struct { - Bool bool `protobuf:"varint,6,opt,name=bool,oneof"` +func (x *ThirdPartyBlockContents) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil } -type TermV2_Set struct { - Set *TermSet `protobuf:"bytes,7,opt,name=set,oneof"` +func (x *ThirdPartyBlockContents) GetExternalSignature() *ExternalSignature { + if x != nil { + return x.ExternalSignature + } + return nil } -func (*TermV2_Variable) isTermV2_Content() {} - -func (*TermV2_Integer) isTermV2_Content() {} - -func (*TermV2_String_) isTermV2_Content() {} - -func (*TermV2_Date) isTermV2_Content() {} - -func (*TermV2_Bytes) isTermV2_Content() {} - -func (*TermV2_Bool) isTermV2_Content() {} - -func (*TermV2_Set) isTermV2_Content() {} - -type TermSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type AuthorizerSnapshot struct { + state protoimpl.MessageState `protogen:"open.v1"` + Limits *RunLimits `protobuf:"bytes,1,req,name=limits" json:"limits,omitempty"` + ExecutionTime *uint64 `protobuf:"varint,2,req,name=executionTime" json:"executionTime,omitempty"` + World *AuthorizerWorld `protobuf:"bytes,3,req,name=world" json:"world,omitempty"` unknownFields protoimpl.UnknownFields - - Set []*TermV2 `protobuf:"bytes,1,rep,name=set" json:"set,omitempty"` + sizeCache protoimpl.SizeCache } -func (x *TermSet) Reset() { - *x = TermSet{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *AuthorizerSnapshot) Reset() { + *x = AuthorizerSnapshot{} + mi := &file_biscuit_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *TermSet) String() string { +func (x *AuthorizerSnapshot) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TermSet) ProtoMessage() {} +func (*AuthorizerSnapshot) ProtoMessage() {} -func (x *TermSet) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { +func (x *AuthorizerSnapshot) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[26] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1042,44 +2253,57 @@ func (x *TermSet) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TermSet.ProtoReflect.Descriptor instead. -func (*TermSet) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{10} +// Deprecated: Use AuthorizerSnapshot.ProtoReflect.Descriptor instead. +func (*AuthorizerSnapshot) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{26} } -func (x *TermSet) GetSet() []*TermV2 { +func (x *AuthorizerSnapshot) GetLimits() *RunLimits { if x != nil { - return x.Set + return x.Limits } return nil } -type ExpressionV2 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ops []*Op `protobuf:"bytes,1,rep,name=ops" json:"ops,omitempty"` +func (x *AuthorizerSnapshot) GetExecutionTime() uint64 { + if x != nil && x.ExecutionTime != nil { + return *x.ExecutionTime + } + return 0 } -func (x *ExpressionV2) Reset() { - *x = ExpressionV2{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *AuthorizerSnapshot) GetWorld() *AuthorizerWorld { + if x != nil { + return x.World } + return nil +} + +type RunLimits struct { + state protoimpl.MessageState `protogen:"open.v1"` + MaxFacts *uint64 `protobuf:"varint,1,req,name=maxFacts" json:"maxFacts,omitempty"` + MaxIterations *uint64 `protobuf:"varint,2,req,name=maxIterations" json:"maxIterations,omitempty"` + MaxTime *uint64 `protobuf:"varint,3,req,name=maxTime" json:"maxTime,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RunLimits) Reset() { + *x = RunLimits{} + mi := &file_biscuit_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *ExpressionV2) String() string { +func (x *RunLimits) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ExpressionV2) ProtoMessage() {} +func (*RunLimits) ProtoMessage() {} -func (x *ExpressionV2) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { +func (x *RunLimits) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[27] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1089,48 +2313,62 @@ func (x *ExpressionV2) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ExpressionV2.ProtoReflect.Descriptor instead. -func (*ExpressionV2) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{11} +// Deprecated: Use RunLimits.ProtoReflect.Descriptor instead. +func (*RunLimits) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{27} } -func (x *ExpressionV2) GetOps() []*Op { - if x != nil { - return x.Ops +func (x *RunLimits) GetMaxFacts() uint64 { + if x != nil && x.MaxFacts != nil { + return *x.MaxFacts } - return nil + return 0 } -type Op struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Content: - // *Op_Value - // *Op_Unary - // *Op_Binary - Content isOp_Content `protobuf_oneof:"Content"` +func (x *RunLimits) GetMaxIterations() uint64 { + if x != nil && x.MaxIterations != nil { + return *x.MaxIterations + } + return 0 } -func (x *Op) Reset() { - *x = Op{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *RunLimits) GetMaxTime() uint64 { + if x != nil && x.MaxTime != nil { + return *x.MaxTime } + return 0 } -func (x *Op) String() string { +type AuthorizerWorld struct { + state protoimpl.MessageState `protogen:"open.v1"` + Version *uint32 `protobuf:"varint,1,opt,name=version" json:"version,omitempty"` + Symbols []string `protobuf:"bytes,2,rep,name=symbols" json:"symbols,omitempty"` + PublicKeys []*PublicKey `protobuf:"bytes,3,rep,name=publicKeys" json:"publicKeys,omitempty"` + Blocks []*SnapshotBlock `protobuf:"bytes,4,rep,name=blocks" json:"blocks,omitempty"` + AuthorizerBlock *SnapshotBlock `protobuf:"bytes,5,req,name=authorizerBlock" json:"authorizerBlock,omitempty"` + AuthorizerPolicies []*Policy `protobuf:"bytes,6,rep,name=authorizerPolicies" json:"authorizerPolicies,omitempty"` + GeneratedFacts []*GeneratedFacts `protobuf:"bytes,7,rep,name=generatedFacts" json:"generatedFacts,omitempty"` + Iterations *uint64 `protobuf:"varint,8,req,name=iterations" json:"iterations,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AuthorizerWorld) Reset() { + *x = AuthorizerWorld{} + mi := &file_biscuit_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AuthorizerWorld) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Op) ProtoMessage() {} +func (*AuthorizerWorld) ProtoMessage() {} -func (x *Op) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { +func (x *AuthorizerWorld) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[28] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1140,87 +2378,94 @@ func (x *Op) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Op.ProtoReflect.Descriptor instead. -func (*Op) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{12} +// Deprecated: Use AuthorizerWorld.ProtoReflect.Descriptor instead. +func (*AuthorizerWorld) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{28} } -func (m *Op) GetContent() isOp_Content { - if m != nil { - return m.Content +func (x *AuthorizerWorld) GetVersion() uint32 { + if x != nil && x.Version != nil { + return *x.Version } - return nil + return 0 } -func (x *Op) GetValue() *TermV2 { - if x, ok := x.GetContent().(*Op_Value); ok { - return x.Value +func (x *AuthorizerWorld) GetSymbols() []string { + if x != nil { + return x.Symbols } return nil } -func (x *Op) GetUnary() *OpUnary { - if x, ok := x.GetContent().(*Op_Unary); ok { - return x.Unary +func (x *AuthorizerWorld) GetPublicKeys() []*PublicKey { + if x != nil { + return x.PublicKeys } return nil } -func (x *Op) GetBinary() *OpBinary { - if x, ok := x.GetContent().(*Op_Binary); ok { - return x.Binary +func (x *AuthorizerWorld) GetBlocks() []*SnapshotBlock { + if x != nil { + return x.Blocks } return nil } -type isOp_Content interface { - isOp_Content() +func (x *AuthorizerWorld) GetAuthorizerBlock() *SnapshotBlock { + if x != nil { + return x.AuthorizerBlock + } + return nil } -type Op_Value struct { - Value *TermV2 `protobuf:"bytes,1,opt,name=value,oneof"` +func (x *AuthorizerWorld) GetAuthorizerPolicies() []*Policy { + if x != nil { + return x.AuthorizerPolicies + } + return nil } -type Op_Unary struct { - Unary *OpUnary `protobuf:"bytes,2,opt,name=unary,oneof"` +func (x *AuthorizerWorld) GetGeneratedFacts() []*GeneratedFacts { + if x != nil { + return x.GeneratedFacts + } + return nil } -type Op_Binary struct { - Binary *OpBinary `protobuf:"bytes,3,opt,name=Binary,oneof"` +func (x *AuthorizerWorld) GetIterations() uint64 { + if x != nil && x.Iterations != nil { + return *x.Iterations + } + return 0 } -func (*Op_Value) isOp_Content() {} - -func (*Op_Unary) isOp_Content() {} - -func (*Op_Binary) isOp_Content() {} - -type OpUnary struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type Origin struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *Origin_Authorizer + // *Origin_Origin + Content isOrigin_Content `protobuf_oneof:"Content"` unknownFields protoimpl.UnknownFields - - Kind *OpUnary_Kind `protobuf:"varint,1,req,name=kind,enum=OpUnary_Kind" json:"kind,omitempty"` + sizeCache protoimpl.SizeCache } -func (x *OpUnary) Reset() { - *x = OpUnary{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *Origin) Reset() { + *x = Origin{} + mi := &file_biscuit_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *OpUnary) String() string { +func (x *Origin) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OpUnary) ProtoMessage() {} +func (*Origin) ProtoMessage() {} -func (x *OpUnary) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { +func (x *Origin) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[29] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1230,44 +2475,74 @@ func (x *OpUnary) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OpUnary.ProtoReflect.Descriptor instead. -func (*OpUnary) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{13} +// Deprecated: Use Origin.ProtoReflect.Descriptor instead. +func (*Origin) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{29} } -func (x *OpUnary) GetKind() OpUnary_Kind { - if x != nil && x.Kind != nil { - return *x.Kind +func (x *Origin) GetContent() isOrigin_Content { + if x != nil { + return x.Content } - return OpUnary_Negate + return nil } -type OpBinary struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Kind *OpBinary_Kind `protobuf:"varint,1,req,name=kind,enum=OpBinary_Kind" json:"kind,omitempty"` +func (x *Origin) GetAuthorizer() *Empty { + if x != nil { + if x, ok := x.Content.(*Origin_Authorizer); ok { + return x.Authorizer + } + } + return nil } -func (x *OpBinary) Reset() { - *x = OpBinary{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *Origin) GetOrigin() uint32 { + if x != nil { + if x, ok := x.Content.(*Origin_Origin); ok { + return x.Origin + } } + return 0 } -func (x *OpBinary) String() string { +type isOrigin_Content interface { + isOrigin_Content() +} + +type Origin_Authorizer struct { + Authorizer *Empty `protobuf:"bytes,1,opt,name=authorizer,oneof"` +} + +type Origin_Origin struct { + Origin uint32 `protobuf:"varint,2,opt,name=origin,oneof"` +} + +func (*Origin_Authorizer) isOrigin_Content() {} + +func (*Origin_Origin) isOrigin_Content() {} + +type Empty struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Empty) Reset() { + *x = Empty{} + mi := &file_biscuit_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Empty) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OpBinary) ProtoMessage() {} +func (*Empty) ProtoMessage() {} -func (x *OpBinary) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[30] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1277,45 +2552,35 @@ func (x *OpBinary) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OpBinary.ProtoReflect.Descriptor instead. -func (*OpBinary) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{14} -} - -func (x *OpBinary) GetKind() OpBinary_Kind { - if x != nil && x.Kind != nil { - return *x.Kind - } - return OpBinary_LessThan +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{30} } -type Policy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type GeneratedFacts struct { + state protoimpl.MessageState `protogen:"open.v1"` + Origins []*Origin `protobuf:"bytes,1,rep,name=origins" json:"origins,omitempty"` + Facts []*Fact `protobuf:"bytes,2,rep,name=facts" json:"facts,omitempty"` unknownFields protoimpl.UnknownFields - - Queries []*RuleV2 `protobuf:"bytes,1,rep,name=queries" json:"queries,omitempty"` - Kind *Policy_Kind `protobuf:"varint,2,req,name=kind,enum=Policy_Kind" json:"kind,omitempty"` + sizeCache protoimpl.SizeCache } -func (x *Policy) Reset() { - *x = Policy{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *GeneratedFacts) Reset() { + *x = GeneratedFacts{} + mi := &file_biscuit_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *Policy) String() string { +func (x *GeneratedFacts) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Policy) ProtoMessage() {} +func (*GeneratedFacts) ProtoMessage() {} -func (x *Policy) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { +func (x *GeneratedFacts) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[31] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1325,56 +2590,54 @@ func (x *Policy) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Policy.ProtoReflect.Descriptor instead. -func (*Policy) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{15} +// Deprecated: Use GeneratedFacts.ProtoReflect.Descriptor instead. +func (*GeneratedFacts) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{31} } -func (x *Policy) GetQueries() []*RuleV2 { +func (x *GeneratedFacts) GetOrigins() []*Origin { if x != nil { - return x.Queries + return x.Origins } return nil } -func (x *Policy) GetKind() Policy_Kind { - if x != nil && x.Kind != nil { - return *x.Kind +func (x *GeneratedFacts) GetFacts() []*Fact { + if x != nil { + return x.Facts } - return Policy_Allow + return nil } -type AuthorizerPolicies struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type SnapshotBlock struct { + state protoimpl.MessageState `protogen:"open.v1"` + Context *string `protobuf:"bytes,1,opt,name=context" json:"context,omitempty"` + Version *uint32 `protobuf:"varint,2,opt,name=version" json:"version,omitempty"` + Facts []*Fact `protobuf:"bytes,3,rep,name=facts" json:"facts,omitempty"` + Rules []*Rule `protobuf:"bytes,4,rep,name=rules" json:"rules,omitempty"` + Checks []*Check `protobuf:"bytes,5,rep,name=checks" json:"checks,omitempty"` + Scope []*Scope `protobuf:"bytes,6,rep,name=scope" json:"scope,omitempty"` + ExternalKey *PublicKey `protobuf:"bytes,7,opt,name=externalKey" json:"externalKey,omitempty"` unknownFields protoimpl.UnknownFields - - Symbols []string `protobuf:"bytes,1,rep,name=symbols" json:"symbols,omitempty"` - Version *uint32 `protobuf:"varint,2,opt,name=version" json:"version,omitempty"` - Facts []*FactV2 `protobuf:"bytes,3,rep,name=facts" json:"facts,omitempty"` - Rules []*RuleV2 `protobuf:"bytes,4,rep,name=rules" json:"rules,omitempty"` - Checks []*CheckV2 `protobuf:"bytes,5,rep,name=checks" json:"checks,omitempty"` - Policies []*Policy `protobuf:"bytes,6,rep,name=policies" json:"policies,omitempty"` + sizeCache protoimpl.SizeCache } -func (x *AuthorizerPolicies) Reset() { - *x = AuthorizerPolicies{} - if protoimpl.UnsafeEnabled { - mi := &file_biscuit_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *SnapshotBlock) Reset() { + *x = SnapshotBlock{} + mi := &file_biscuit_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *AuthorizerPolicies) String() string { +func (x *SnapshotBlock) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AuthorizerPolicies) ProtoMessage() {} +func (*SnapshotBlock) ProtoMessage() {} -func (x *AuthorizerPolicies) ProtoReflect() protoreflect.Message { - mi := &file_biscuit_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { +func (x *SnapshotBlock) ProtoReflect() protoreflect.Message { + mi := &file_biscuit_proto_msgTypes[32] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1384,258 +2647,401 @@ func (x *AuthorizerPolicies) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AuthorizerPolicies.ProtoReflect.Descriptor instead. -func (*AuthorizerPolicies) Descriptor() ([]byte, []int) { - return file_biscuit_proto_rawDescGZIP(), []int{16} +// Deprecated: Use SnapshotBlock.ProtoReflect.Descriptor instead. +func (*SnapshotBlock) Descriptor() ([]byte, []int) { + return file_biscuit_proto_rawDescGZIP(), []int{32} } -func (x *AuthorizerPolicies) GetSymbols() []string { - if x != nil { - return x.Symbols +func (x *SnapshotBlock) GetContext() string { + if x != nil && x.Context != nil { + return *x.Context } - return nil + return "" } -func (x *AuthorizerPolicies) GetVersion() uint32 { +func (x *SnapshotBlock) GetVersion() uint32 { if x != nil && x.Version != nil { return *x.Version } return 0 } -func (x *AuthorizerPolicies) GetFacts() []*FactV2 { +func (x *SnapshotBlock) GetFacts() []*Fact { if x != nil { return x.Facts } return nil } -func (x *AuthorizerPolicies) GetRules() []*RuleV2 { +func (x *SnapshotBlock) GetRules() []*Rule { if x != nil { return x.Rules } return nil } -func (x *AuthorizerPolicies) GetChecks() []*CheckV2 { +func (x *SnapshotBlock) GetChecks() []*Check { if x != nil { return x.Checks } return nil } -func (x *AuthorizerPolicies) GetPolicies() []*Policy { +func (x *SnapshotBlock) GetScope() []*Scope { if x != nil { - return x.Policies + return x.Scope + } + return nil +} + +func (x *SnapshotBlock) GetExternalKey() *PublicKey { + if x != nil { + return x.ExternalKey } return nil } var File_biscuit_proto protoreflect.FileDescriptor -var file_biscuit_proto_rawDesc = []byte{ - 0x0a, 0x0d, 0x62, 0x69, 0x73, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x97, 0x01, 0x0a, 0x07, 0x42, 0x69, 0x73, 0x63, 0x75, 0x69, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, - 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x09, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x53, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x24, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x1c, 0x0a, 0x05, 0x70, - 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x50, 0x72, 0x6f, - 0x6f, 0x66, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x67, 0x0a, 0x0b, 0x53, 0x69, 0x67, - 0x6e, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x24, - 0x0a, 0x07, 0x6e, 0x65, 0x78, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0b, 0x32, - 0x0a, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x6e, 0x65, 0x78, - 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x18, 0x03, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, - 0x32, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, 0x02, - 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x2e, 0x41, - 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, - 0x74, 0x68, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x18, 0x0a, 0x09, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, - 0x68, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x00, 0x22, - 0x5e, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x20, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, - 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a, - 0x6e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x28, 0x0a, 0x0e, 0x66, 0x69, - 0x6e, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0e, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, - 0xc4, 0x01, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x79, 0x6d, - 0x62, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x08, 0x66, 0x61, 0x63, 0x74, 0x73, - 0x5f, 0x76, 0x32, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x46, 0x61, 0x63, 0x74, - 0x56, 0x32, 0x52, 0x07, 0x66, 0x61, 0x63, 0x74, 0x73, 0x56, 0x32, 0x12, 0x22, 0x0a, 0x08, 0x72, - 0x75, 0x6c, 0x65, 0x73, 0x5f, 0x76, 0x32, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, 0x2e, - 0x52, 0x75, 0x6c, 0x65, 0x56, 0x32, 0x52, 0x07, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x56, 0x32, 0x12, - 0x25, 0x0a, 0x09, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x5f, 0x76, 0x32, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x56, 0x32, 0x52, 0x08, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x73, 0x56, 0x32, 0x22, 0x34, 0x0a, 0x06, 0x46, 0x61, 0x63, 0x74, 0x56, 0x32, - 0x12, 0x2a, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, - 0x02, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, - 0x32, 0x52, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x7d, 0x0a, 0x06, - 0x52, 0x75, 0x6c, 0x65, 0x56, 0x32, 0x12, 0x20, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x01, - 0x20, 0x02, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x56, 0x32, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x20, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x56, 0x32, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2f, 0x0a, 0x0b, 0x65, 0x78, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x52, 0x0b, - 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x2c, 0x0a, 0x07, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x56, 0x32, 0x12, 0x21, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x56, 0x32, - 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0x40, 0x0a, 0x0b, 0x50, 0x72, 0x65, - 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x32, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x02, 0x28, 0x04, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x05, - 0x74, 0x65, 0x72, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x54, 0x65, - 0x72, 0x6d, 0x56, 0x32, 0x52, 0x05, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x22, 0xc9, 0x01, 0x0a, 0x06, - 0x54, 0x65, 0x72, 0x6d, 0x56, 0x32, 0x12, 0x1c, 0x0a, 0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x08, 0x76, 0x61, 0x72, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, - 0x12, 0x18, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x16, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, - 0x00, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x6c, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x1c, - 0x0a, 0x03, 0x73, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x54, 0x65, - 0x72, 0x6d, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x73, 0x65, 0x74, 0x42, 0x09, 0x0a, 0x07, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x24, 0x0a, 0x07, 0x54, 0x65, 0x72, 0x6d, 0x53, - 0x65, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x07, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x56, 0x32, 0x52, 0x03, 0x73, 0x65, 0x74, 0x22, 0x25, 0x0a, - 0x0c, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x12, 0x15, 0x0a, - 0x03, 0x6f, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x03, 0x2e, 0x4f, 0x70, 0x52, - 0x03, 0x6f, 0x70, 0x73, 0x22, 0x77, 0x0a, 0x02, 0x4f, 0x70, 0x12, 0x1f, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x54, 0x65, 0x72, 0x6d, - 0x56, 0x32, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x75, - 0x6e, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x4f, 0x70, 0x55, - 0x6e, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x23, 0x0a, - 0x06, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, - 0x4f, 0x70, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x06, 0x42, 0x69, 0x6e, 0x61, - 0x72, 0x79, 0x42, 0x09, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x58, 0x0a, - 0x07, 0x4f, 0x70, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x18, 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x4f, 0x70, 0x55, 0x6e, 0x61, 0x72, 0x79, - 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x2a, 0x0a, 0x04, 0x4b, - 0x69, 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x65, 0x67, 0x61, 0x74, 0x65, 0x10, 0x00, 0x12, - 0x0a, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x73, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x10, 0x02, 0x22, 0x89, 0x02, 0x0a, 0x08, 0x4f, 0x70, 0x42, 0x69, - 0x6e, 0x61, 0x72, 0x79, 0x12, 0x22, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x02, - 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x4f, 0x70, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x2e, 0x4b, 0x69, - 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xd8, 0x01, 0x0a, 0x04, 0x4b, 0x69, 0x6e, - 0x64, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x65, 0x73, 0x73, 0x54, 0x68, 0x61, 0x6e, 0x10, 0x00, 0x12, - 0x0f, 0x0a, 0x0b, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x10, 0x01, - 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x65, 0x73, 0x73, 0x4f, 0x72, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x10, - 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x4f, 0x72, 0x45, 0x71, - 0x75, 0x61, 0x6c, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x10, 0x04, - 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x10, 0x05, 0x12, 0x0a, - 0x0a, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x10, 0x06, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x75, - 0x66, 0x66, 0x69, 0x78, 0x10, 0x07, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, - 0x08, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x10, 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x75, - 0x62, 0x10, 0x0a, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x75, 0x6c, 0x10, 0x0b, 0x12, 0x07, 0x0a, 0x03, - 0x44, 0x69, 0x76, 0x10, 0x0c, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6e, 0x64, 0x10, 0x0d, 0x12, 0x06, - 0x0a, 0x02, 0x4f, 0x72, 0x10, 0x0e, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x0f, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x6e, 0x69, 0x6f, - 0x6e, 0x10, 0x10, 0x22, 0x6a, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x21, 0x0a, - 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, - 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x56, 0x32, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x12, 0x20, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x0c, - 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, - 0x6e, 0x64, 0x22, 0x1b, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x6c, - 0x6c, 0x6f, 0x77, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x65, 0x6e, 0x79, 0x10, 0x01, 0x22, - 0xcd, 0x01, 0x0a, 0x12, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, - 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x05, 0x66, 0x61, - 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x46, 0x61, 0x63, 0x74, - 0x56, 0x32, 0x52, 0x05, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x05, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x56, - 0x32, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x56, 0x32, 0x52, 0x06, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x23, 0x0a, 0x08, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x42, - 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, -} +const file_biscuit_proto_rawDesc = "" + + "\n" + + "\rbiscuit.proto\x12\x15biscuit.format.schema\"\xd9\x01\n" + + "\aBiscuit\x12\x1c\n" + + "\trootKeyId\x18\x01 \x01(\rR\trootKeyId\x12@\n" + + "\tauthority\x18\x02 \x02(\v2\".biscuit.format.schema.SignedBlockR\tauthority\x12:\n" + + "\x06blocks\x18\x03 \x03(\v2\".biscuit.format.schema.SignedBlockR\x06blocks\x122\n" + + "\x05proof\x18\x04 \x02(\v2\x1c.biscuit.format.schema.ProofR\x05proof\"\xef\x01\n" + + "\vSignedBlock\x12\x14\n" + + "\x05block\x18\x01 \x02(\fR\x05block\x12:\n" + + "\anextKey\x18\x02 \x02(\v2 .biscuit.format.schema.PublicKeyR\anextKey\x12\x1c\n" + + "\tsignature\x18\x03 \x02(\fR\tsignature\x12V\n" + + "\x11externalSignature\x18\x04 \x01(\v2(.biscuit.format.schema.ExternalSignatureR\x11externalSignature\x12\x18\n" + + "\aversion\x18\x05 \x01(\rR\aversion\"q\n" + + "\x11ExternalSignature\x12\x1c\n" + + "\tsignature\x18\x01 \x02(\fR\tsignature\x12>\n" + + "\tpublicKey\x18\x02 \x02(\v2 .biscuit.format.schema.PublicKeyR\tpublicKey\"\x90\x01\n" + + "\tPublicKey\x12H\n" + + "\talgorithm\x18\x01 \x02(\x0e2*.biscuit.format.schema.PublicKey.AlgorithmR\talgorithm\x12\x10\n" + + "\x03key\x18\x02 \x02(\fR\x03key\"'\n" + + "\tAlgorithm\x12\v\n" + + "\aEd25519\x10\x00\x12\r\n" + + "\tSECP256R1\x10\x01\"^\n" + + "\x05Proof\x12 \n" + + "\n" + + "nextSecret\x18\x01 \x01(\fH\x00R\n" + + "nextSecret\x12(\n" + + "\x0efinalSignature\x18\x02 \x01(\fH\x00R\x0efinalSignatureB\t\n" + + "\aContent\"\xe7\x02\n" + + "\x05Block\x12\x18\n" + + "\asymbols\x18\x01 \x03(\tR\asymbols\x12\x18\n" + + "\acontext\x18\x02 \x01(\tR\acontext\x12\x18\n" + + "\aversion\x18\x03 \x01(\rR\aversion\x121\n" + + "\x05facts\x18\x04 \x03(\v2\x1b.biscuit.format.schema.FactR\x05facts\x121\n" + + "\x05rules\x18\x05 \x03(\v2\x1b.biscuit.format.schema.RuleR\x05rules\x124\n" + + "\x06checks\x18\x06 \x03(\v2\x1c.biscuit.format.schema.CheckR\x06checks\x122\n" + + "\x05scope\x18\a \x03(\v2\x1c.biscuit.format.schema.ScopeR\x05scope\x12@\n" + + "\n" + + "publicKeys\x18\b \x03(\v2 .biscuit.format.schema.PublicKeyR\n" + + "publicKeys\"\xa4\x01\n" + + "\x05Scope\x12F\n" + + "\tscopeType\x18\x01 \x01(\x0e2&.biscuit.format.schema.Scope.ScopeTypeH\x00R\tscopeType\x12\x1e\n" + + "\tpublicKey\x18\x02 \x01(\x03H\x00R\tpublicKey\"(\n" + + "\tScopeType\x12\r\n" + + "\tAuthority\x10\x00\x12\f\n" + + "\bPrevious\x10\x01B\t\n" + + "\aContent\"F\n" + + "\x04Fact\x12>\n" + + "\tpredicate\x18\x01 \x02(\v2 .biscuit.format.schema.PredicateR\tpredicate\"\xeb\x01\n" + + "\x04Rule\x124\n" + + "\x04head\x18\x01 \x02(\v2 .biscuit.format.schema.PredicateR\x04head\x124\n" + + "\x04body\x18\x02 \x03(\v2 .biscuit.format.schema.PredicateR\x04body\x12C\n" + + "\vexpressions\x18\x03 \x03(\v2!.biscuit.format.schema.ExpressionR\vexpressions\x122\n" + + "\x05scope\x18\x04 \x03(\v2\x1c.biscuit.format.schema.ScopeR\x05scope\"\x9b\x01\n" + + "\x05Check\x125\n" + + "\aqueries\x18\x01 \x03(\v2\x1b.biscuit.format.schema.RuleR\aqueries\x125\n" + + "\x04kind\x18\x02 \x01(\x0e2!.biscuit.format.schema.Check.KindR\x04kind\"$\n" + + "\x04Kind\x12\a\n" + + "\x03One\x10\x00\x12\a\n" + + "\x03All\x10\x01\x12\n" + + "\n" + + "\x06Reject\x10\x02\"R\n" + + "\tPredicate\x12\x12\n" + + "\x04name\x18\x01 \x02(\x04R\x04name\x121\n" + + "\x05terms\x18\x02 \x03(\v2\x1b.biscuit.format.schema.TermR\x05terms\"\xf7\x02\n" + + "\x04Term\x12\x1c\n" + + "\bvariable\x18\x01 \x01(\rH\x00R\bvariable\x12\x1a\n" + + "\ainteger\x18\x02 \x01(\x03H\x00R\ainteger\x12\x18\n" + + "\x06string\x18\x03 \x01(\x04H\x00R\x06string\x12\x14\n" + + "\x04date\x18\x04 \x01(\x04H\x00R\x04date\x12\x16\n" + + "\x05bytes\x18\x05 \x01(\fH\x00R\x05bytes\x12\x14\n" + + "\x04bool\x18\x06 \x01(\bH\x00R\x04bool\x122\n" + + "\x03set\x18\a \x01(\v2\x1e.biscuit.format.schema.TermSetH\x00R\x03set\x122\n" + + "\x04null\x18\b \x01(\v2\x1c.biscuit.format.schema.EmptyH\x00R\x04null\x124\n" + + "\x05array\x18\t \x01(\v2\x1c.biscuit.format.schema.ArrayH\x00R\x05array\x12.\n" + + "\x03map\x18\n" + + " \x01(\v2\x1a.biscuit.format.schema.MapH\x00R\x03mapB\t\n" + + "\aContent\"8\n" + + "\aTermSet\x12-\n" + + "\x03set\x18\x01 \x03(\v2\x1b.biscuit.format.schema.TermR\x03set\":\n" + + "\x05Array\x121\n" + + "\x05array\x18\x01 \x03(\v2\x1b.biscuit.format.schema.TermR\x05array\"@\n" + + "\x03Map\x129\n" + + "\aentries\x18\x01 \x03(\v2\x1f.biscuit.format.schema.MapEntryR\aentries\"n\n" + + "\bMapEntry\x12/\n" + + "\x03key\x18\x01 \x02(\v2\x1d.biscuit.format.schema.MapKeyR\x03key\x121\n" + + "\x05value\x18\x02 \x02(\v2\x1b.biscuit.format.schema.TermR\x05value\"I\n" + + "\x06MapKey\x12\x1a\n" + + "\ainteger\x18\x01 \x01(\x03H\x00R\ainteger\x12\x18\n" + + "\x06string\x18\x02 \x01(\x04H\x00R\x06stringB\t\n" + + "\aContent\"9\n" + + "\n" + + "Expression\x12+\n" + + "\x03ops\x18\x01 \x03(\v2\x19.biscuit.format.schema.OpR\x03ops\"\xf5\x01\n" + + "\x02Op\x123\n" + + "\x05value\x18\x01 \x01(\v2\x1b.biscuit.format.schema.TermH\x00R\x05value\x126\n" + + "\x05unary\x18\x02 \x01(\v2\x1e.biscuit.format.schema.OpUnaryH\x00R\x05unary\x129\n" + + "\x06Binary\x18\x03 \x01(\v2\x1f.biscuit.format.schema.OpBinaryH\x00R\x06Binary\x12<\n" + + "\aclosure\x18\x04 \x01(\v2 .biscuit.format.schema.OpClosureH\x00R\aclosureB\t\n" + + "\aContent\"\x9d\x01\n" + + "\aOpUnary\x127\n" + + "\x04kind\x18\x01 \x02(\x0e2#.biscuit.format.schema.OpUnary.KindR\x04kind\x12\x18\n" + + "\affiName\x18\x02 \x01(\x04R\affiName\"?\n" + + "\x04Kind\x12\n" + + "\n" + + "\x06Negate\x10\x00\x12\n" + + "\n" + + "\x06Parens\x10\x01\x12\n" + + "\n" + + "\x06Length\x10\x02\x12\n" + + "\n" + + "\x06TypeOf\x10\x03\x12\a\n" + + "\x03Ffi\x10\x04\"\xf1\x03\n" + + "\bOpBinary\x128\n" + + "\x04kind\x18\x01 \x02(\x0e2$.biscuit.format.schema.OpBinary.KindR\x04kind\x12\x18\n" + + "\affiName\x18\x02 \x01(\x04R\affiName\"\x90\x03\n" + + "\x04Kind\x12\f\n" + + "\bLessThan\x10\x00\x12\x0f\n" + + "\vGreaterThan\x10\x01\x12\x0f\n" + + "\vLessOrEqual\x10\x02\x12\x12\n" + + "\x0eGreaterOrEqual\x10\x03\x12\t\n" + + "\x05Equal\x10\x04\x12\f\n" + + "\bContains\x10\x05\x12\n" + + "\n" + + "\x06Prefix\x10\x06\x12\n" + + "\n" + + "\x06Suffix\x10\a\x12\t\n" + + "\x05Regex\x10\b\x12\a\n" + + "\x03Add\x10\t\x12\a\n" + + "\x03Sub\x10\n" + + "\x12\a\n" + + "\x03Mul\x10\v\x12\a\n" + + "\x03Div\x10\f\x12\a\n" + + "\x03And\x10\r\x12\x06\n" + + "\x02Or\x10\x0e\x12\x10\n" + + "\fIntersection\x10\x0f\x12\t\n" + + "\x05Union\x10\x10\x12\x0e\n" + + "\n" + + "BitwiseAnd\x10\x11\x12\r\n" + + "\tBitwiseOr\x10\x12\x12\x0e\n" + + "\n" + + "BitwiseXor\x10\x13\x12\f\n" + + "\bNotEqual\x10\x14\x12\x16\n" + + "\x12HeterogeneousEqual\x10\x15\x12\x19\n" + + "\x15HeterogeneousNotEqual\x10\x16\x12\v\n" + + "\aLazyAnd\x10\x17\x12\n" + + "\n" + + "\x06LazyOr\x10\x18\x12\a\n" + + "\x03All\x10\x19\x12\a\n" + + "\x03Any\x10\x1a\x12\a\n" + + "\x03Get\x10\x1b\x12\a\n" + + "\x03Ffi\x10\x1c\x12\t\n" + + "\x05TryOr\x10\x1d\"P\n" + + "\tOpClosure\x12\x16\n" + + "\x06params\x18\x01 \x03(\rR\x06params\x12+\n" + + "\x03ops\x18\x02 \x03(\v2\x19.biscuit.format.schema.OpR\x03ops\"\x94\x01\n" + + "\x06Policy\x125\n" + + "\aqueries\x18\x01 \x03(\v2\x1b.biscuit.format.schema.RuleR\aqueries\x126\n" + + "\x04kind\x18\x02 \x02(\x0e2\".biscuit.format.schema.Policy.KindR\x04kind\"\x1b\n" + + "\x04Kind\x12\t\n" + + "\x05Allow\x10\x00\x12\b\n" + + "\x04Deny\x10\x01\"\x9f\x02\n" + + "\x12AuthorizerPolicies\x12\x18\n" + + "\asymbols\x18\x01 \x03(\tR\asymbols\x12\x18\n" + + "\aversion\x18\x02 \x01(\rR\aversion\x121\n" + + "\x05facts\x18\x03 \x03(\v2\x1b.biscuit.format.schema.FactR\x05facts\x121\n" + + "\x05rules\x18\x04 \x03(\v2\x1b.biscuit.format.schema.RuleR\x05rules\x124\n" + + "\x06checks\x18\x05 \x03(\v2\x1c.biscuit.format.schema.CheckR\x06checks\x129\n" + + "\bpolicies\x18\x06 \x03(\v2\x1d.biscuit.format.schema.PolicyR\bpolicies\"\xe4\x01\n" + + "\x16ThirdPartyBlockRequest\x12N\n" + + "\x11legacyPreviousKey\x18\x01 \x01(\v2 .biscuit.format.schema.PublicKeyR\x11legacyPreviousKey\x12L\n" + + "\x10legacyPublicKeys\x18\x02 \x03(\v2 .biscuit.format.schema.PublicKeyR\x10legacyPublicKeys\x12,\n" + + "\x11previousSignature\x18\x03 \x02(\fR\x11previousSignature\"\x8b\x01\n" + + "\x17ThirdPartyBlockContents\x12\x18\n" + + "\apayload\x18\x01 \x02(\fR\apayload\x12V\n" + + "\x11externalSignature\x18\x02 \x02(\v2(.biscuit.format.schema.ExternalSignatureR\x11externalSignature\"\xb2\x01\n" + + "\x12AuthorizerSnapshot\x128\n" + + "\x06limits\x18\x01 \x02(\v2 .biscuit.format.schema.RunLimitsR\x06limits\x12$\n" + + "\rexecutionTime\x18\x02 \x02(\x04R\rexecutionTime\x12<\n" + + "\x05world\x18\x03 \x02(\v2&.biscuit.format.schema.AuthorizerWorldR\x05world\"g\n" + + "\tRunLimits\x12\x1a\n" + + "\bmaxFacts\x18\x01 \x02(\x04R\bmaxFacts\x12$\n" + + "\rmaxIterations\x18\x02 \x02(\x04R\rmaxIterations\x12\x18\n" + + "\amaxTime\x18\x03 \x02(\x04R\amaxTime\"\xd3\x03\n" + + "\x0fAuthorizerWorld\x12\x18\n" + + "\aversion\x18\x01 \x01(\rR\aversion\x12\x18\n" + + "\asymbols\x18\x02 \x03(\tR\asymbols\x12@\n" + + "\n" + + "publicKeys\x18\x03 \x03(\v2 .biscuit.format.schema.PublicKeyR\n" + + "publicKeys\x12<\n" + + "\x06blocks\x18\x04 \x03(\v2$.biscuit.format.schema.SnapshotBlockR\x06blocks\x12N\n" + + "\x0fauthorizerBlock\x18\x05 \x02(\v2$.biscuit.format.schema.SnapshotBlockR\x0fauthorizerBlock\x12M\n" + + "\x12authorizerPolicies\x18\x06 \x03(\v2\x1d.biscuit.format.schema.PolicyR\x12authorizerPolicies\x12M\n" + + "\x0egeneratedFacts\x18\a \x03(\v2%.biscuit.format.schema.GeneratedFactsR\x0egeneratedFacts\x12\x1e\n" + + "\n" + + "iterations\x18\b \x02(\x04R\n" + + "iterations\"m\n" + + "\x06Origin\x12>\n" + + "\n" + + "authorizer\x18\x01 \x01(\v2\x1c.biscuit.format.schema.EmptyH\x00R\n" + + "authorizer\x12\x18\n" + + "\x06origin\x18\x02 \x01(\rH\x00R\x06originB\t\n" + + "\aContent\"\a\n" + + "\x05Empty\"|\n" + + "\x0eGeneratedFacts\x127\n" + + "\aorigins\x18\x01 \x03(\v2\x1d.biscuit.format.schema.OriginR\aorigins\x121\n" + + "\x05facts\x18\x02 \x03(\v2\x1b.biscuit.format.schema.FactR\x05facts\"\xd7\x02\n" + + "\rSnapshotBlock\x12\x18\n" + + "\acontext\x18\x01 \x01(\tR\acontext\x12\x18\n" + + "\aversion\x18\x02 \x01(\rR\aversion\x121\n" + + "\x05facts\x18\x03 \x03(\v2\x1b.biscuit.format.schema.FactR\x05facts\x121\n" + + "\x05rules\x18\x04 \x03(\v2\x1b.biscuit.format.schema.RuleR\x05rules\x124\n" + + "\x06checks\x18\x05 \x03(\v2\x1c.biscuit.format.schema.CheckR\x06checks\x122\n" + + "\x05scope\x18\x06 \x03(\v2\x1c.biscuit.format.schema.ScopeR\x05scope\x12B\n" + + "\vexternalKey\x18\a \x01(\v2 .biscuit.format.schema.PublicKeyR\vexternalKeyB\x06Z\x04.;pb" var ( file_biscuit_proto_rawDescOnce sync.Once - file_biscuit_proto_rawDescData = file_biscuit_proto_rawDesc + file_biscuit_proto_rawDescData []byte ) func file_biscuit_proto_rawDescGZIP() []byte { file_biscuit_proto_rawDescOnce.Do(func() { - file_biscuit_proto_rawDescData = protoimpl.X.CompressGZIP(file_biscuit_proto_rawDescData) + file_biscuit_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_biscuit_proto_rawDesc), len(file_biscuit_proto_rawDesc))) }) return file_biscuit_proto_rawDescData } -var file_biscuit_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_biscuit_proto_msgTypes = make([]protoimpl.MessageInfo, 17) -var file_biscuit_proto_goTypes = []interface{}{ - (PublicKey_Algorithm)(0), // 0: PublicKey.Algorithm - (OpUnary_Kind)(0), // 1: OpUnary.Kind - (OpBinary_Kind)(0), // 2: OpBinary.Kind - (Policy_Kind)(0), // 3: Policy.Kind - (*Biscuit)(nil), // 4: Biscuit - (*SignedBlock)(nil), // 5: SignedBlock - (*PublicKey)(nil), // 6: PublicKey - (*Proof)(nil), // 7: Proof - (*Block)(nil), // 8: Block - (*FactV2)(nil), // 9: FactV2 - (*RuleV2)(nil), // 10: RuleV2 - (*CheckV2)(nil), // 11: CheckV2 - (*PredicateV2)(nil), // 12: PredicateV2 - (*TermV2)(nil), // 13: TermV2 - (*TermSet)(nil), // 14: TermSet - (*ExpressionV2)(nil), // 15: ExpressionV2 - (*Op)(nil), // 16: Op - (*OpUnary)(nil), // 17: OpUnary - (*OpBinary)(nil), // 18: OpBinary - (*Policy)(nil), // 19: Policy - (*AuthorizerPolicies)(nil), // 20: AuthorizerPolicies +var file_biscuit_proto_enumTypes = make([]protoimpl.EnumInfo, 6) +var file_biscuit_proto_msgTypes = make([]protoimpl.MessageInfo, 33) +var file_biscuit_proto_goTypes = []any{ + (PublicKey_Algorithm)(0), // 0: biscuit.format.schema.PublicKey.Algorithm + (Scope_ScopeType)(0), // 1: biscuit.format.schema.Scope.ScopeType + (Check_Kind)(0), // 2: biscuit.format.schema.Check.Kind + (OpUnary_Kind)(0), // 3: biscuit.format.schema.OpUnary.Kind + (OpBinary_Kind)(0), // 4: biscuit.format.schema.OpBinary.Kind + (Policy_Kind)(0), // 5: biscuit.format.schema.Policy.Kind + (*Biscuit)(nil), // 6: biscuit.format.schema.Biscuit + (*SignedBlock)(nil), // 7: biscuit.format.schema.SignedBlock + (*ExternalSignature)(nil), // 8: biscuit.format.schema.ExternalSignature + (*PublicKey)(nil), // 9: biscuit.format.schema.PublicKey + (*Proof)(nil), // 10: biscuit.format.schema.Proof + (*Block)(nil), // 11: biscuit.format.schema.Block + (*Scope)(nil), // 12: biscuit.format.schema.Scope + (*Fact)(nil), // 13: biscuit.format.schema.Fact + (*Rule)(nil), // 14: biscuit.format.schema.Rule + (*Check)(nil), // 15: biscuit.format.schema.Check + (*Predicate)(nil), // 16: biscuit.format.schema.Predicate + (*Term)(nil), // 17: biscuit.format.schema.Term + (*TermSet)(nil), // 18: biscuit.format.schema.TermSet + (*Array)(nil), // 19: biscuit.format.schema.Array + (*Map)(nil), // 20: biscuit.format.schema.Map + (*MapEntry)(nil), // 21: biscuit.format.schema.MapEntry + (*MapKey)(nil), // 22: biscuit.format.schema.MapKey + (*Expression)(nil), // 23: biscuit.format.schema.Expression + (*Op)(nil), // 24: biscuit.format.schema.Op + (*OpUnary)(nil), // 25: biscuit.format.schema.OpUnary + (*OpBinary)(nil), // 26: biscuit.format.schema.OpBinary + (*OpClosure)(nil), // 27: biscuit.format.schema.OpClosure + (*Policy)(nil), // 28: biscuit.format.schema.Policy + (*AuthorizerPolicies)(nil), // 29: biscuit.format.schema.AuthorizerPolicies + (*ThirdPartyBlockRequest)(nil), // 30: biscuit.format.schema.ThirdPartyBlockRequest + (*ThirdPartyBlockContents)(nil), // 31: biscuit.format.schema.ThirdPartyBlockContents + (*AuthorizerSnapshot)(nil), // 32: biscuit.format.schema.AuthorizerSnapshot + (*RunLimits)(nil), // 33: biscuit.format.schema.RunLimits + (*AuthorizerWorld)(nil), // 34: biscuit.format.schema.AuthorizerWorld + (*Origin)(nil), // 35: biscuit.format.schema.Origin + (*Empty)(nil), // 36: biscuit.format.schema.Empty + (*GeneratedFacts)(nil), // 37: biscuit.format.schema.GeneratedFacts + (*SnapshotBlock)(nil), // 38: biscuit.format.schema.SnapshotBlock } var file_biscuit_proto_depIdxs = []int32{ - 5, // 0: Biscuit.authority:type_name -> SignedBlock - 5, // 1: Biscuit.blocks:type_name -> SignedBlock - 7, // 2: Biscuit.proof:type_name -> Proof - 6, // 3: SignedBlock.nextKey:type_name -> PublicKey - 0, // 4: PublicKey.algorithm:type_name -> PublicKey.Algorithm - 9, // 5: Block.facts_v2:type_name -> FactV2 - 10, // 6: Block.rules_v2:type_name -> RuleV2 - 11, // 7: Block.checks_v2:type_name -> CheckV2 - 12, // 8: FactV2.predicate:type_name -> PredicateV2 - 12, // 9: RuleV2.head:type_name -> PredicateV2 - 12, // 10: RuleV2.body:type_name -> PredicateV2 - 15, // 11: RuleV2.expressions:type_name -> ExpressionV2 - 10, // 12: CheckV2.queries:type_name -> RuleV2 - 13, // 13: PredicateV2.terms:type_name -> TermV2 - 14, // 14: TermV2.set:type_name -> TermSet - 13, // 15: TermSet.set:type_name -> TermV2 - 16, // 16: ExpressionV2.ops:type_name -> Op - 13, // 17: Op.value:type_name -> TermV2 - 17, // 18: Op.unary:type_name -> OpUnary - 18, // 19: Op.Binary:type_name -> OpBinary - 1, // 20: OpUnary.kind:type_name -> OpUnary.Kind - 2, // 21: OpBinary.kind:type_name -> OpBinary.Kind - 10, // 22: Policy.queries:type_name -> RuleV2 - 3, // 23: Policy.kind:type_name -> Policy.Kind - 9, // 24: AuthorizerPolicies.facts:type_name -> FactV2 - 10, // 25: AuthorizerPolicies.rules:type_name -> RuleV2 - 11, // 26: AuthorizerPolicies.checks:type_name -> CheckV2 - 19, // 27: AuthorizerPolicies.policies:type_name -> Policy - 28, // [28:28] is the sub-list for method output_type - 28, // [28:28] is the sub-list for method input_type - 28, // [28:28] is the sub-list for extension type_name - 28, // [28:28] is the sub-list for extension extendee - 0, // [0:28] is the sub-list for field type_name + 7, // 0: biscuit.format.schema.Biscuit.authority:type_name -> biscuit.format.schema.SignedBlock + 7, // 1: biscuit.format.schema.Biscuit.blocks:type_name -> biscuit.format.schema.SignedBlock + 10, // 2: biscuit.format.schema.Biscuit.proof:type_name -> biscuit.format.schema.Proof + 9, // 3: biscuit.format.schema.SignedBlock.nextKey:type_name -> biscuit.format.schema.PublicKey + 8, // 4: biscuit.format.schema.SignedBlock.externalSignature:type_name -> biscuit.format.schema.ExternalSignature + 9, // 5: biscuit.format.schema.ExternalSignature.publicKey:type_name -> biscuit.format.schema.PublicKey + 0, // 6: biscuit.format.schema.PublicKey.algorithm:type_name -> biscuit.format.schema.PublicKey.Algorithm + 13, // 7: biscuit.format.schema.Block.facts:type_name -> biscuit.format.schema.Fact + 14, // 8: biscuit.format.schema.Block.rules:type_name -> biscuit.format.schema.Rule + 15, // 9: biscuit.format.schema.Block.checks:type_name -> biscuit.format.schema.Check + 12, // 10: biscuit.format.schema.Block.scope:type_name -> biscuit.format.schema.Scope + 9, // 11: biscuit.format.schema.Block.publicKeys:type_name -> biscuit.format.schema.PublicKey + 1, // 12: biscuit.format.schema.Scope.scopeType:type_name -> biscuit.format.schema.Scope.ScopeType + 16, // 13: biscuit.format.schema.Fact.predicate:type_name -> biscuit.format.schema.Predicate + 16, // 14: biscuit.format.schema.Rule.head:type_name -> biscuit.format.schema.Predicate + 16, // 15: biscuit.format.schema.Rule.body:type_name -> biscuit.format.schema.Predicate + 23, // 16: biscuit.format.schema.Rule.expressions:type_name -> biscuit.format.schema.Expression + 12, // 17: biscuit.format.schema.Rule.scope:type_name -> biscuit.format.schema.Scope + 14, // 18: biscuit.format.schema.Check.queries:type_name -> biscuit.format.schema.Rule + 2, // 19: biscuit.format.schema.Check.kind:type_name -> biscuit.format.schema.Check.Kind + 17, // 20: biscuit.format.schema.Predicate.terms:type_name -> biscuit.format.schema.Term + 18, // 21: biscuit.format.schema.Term.set:type_name -> biscuit.format.schema.TermSet + 36, // 22: biscuit.format.schema.Term.null:type_name -> biscuit.format.schema.Empty + 19, // 23: biscuit.format.schema.Term.array:type_name -> biscuit.format.schema.Array + 20, // 24: biscuit.format.schema.Term.map:type_name -> biscuit.format.schema.Map + 17, // 25: biscuit.format.schema.TermSet.set:type_name -> biscuit.format.schema.Term + 17, // 26: biscuit.format.schema.Array.array:type_name -> biscuit.format.schema.Term + 21, // 27: biscuit.format.schema.Map.entries:type_name -> biscuit.format.schema.MapEntry + 22, // 28: biscuit.format.schema.MapEntry.key:type_name -> biscuit.format.schema.MapKey + 17, // 29: biscuit.format.schema.MapEntry.value:type_name -> biscuit.format.schema.Term + 24, // 30: biscuit.format.schema.Expression.ops:type_name -> biscuit.format.schema.Op + 17, // 31: biscuit.format.schema.Op.value:type_name -> biscuit.format.schema.Term + 25, // 32: biscuit.format.schema.Op.unary:type_name -> biscuit.format.schema.OpUnary + 26, // 33: biscuit.format.schema.Op.Binary:type_name -> biscuit.format.schema.OpBinary + 27, // 34: biscuit.format.schema.Op.closure:type_name -> biscuit.format.schema.OpClosure + 3, // 35: biscuit.format.schema.OpUnary.kind:type_name -> biscuit.format.schema.OpUnary.Kind + 4, // 36: biscuit.format.schema.OpBinary.kind:type_name -> biscuit.format.schema.OpBinary.Kind + 24, // 37: biscuit.format.schema.OpClosure.ops:type_name -> biscuit.format.schema.Op + 14, // 38: biscuit.format.schema.Policy.queries:type_name -> biscuit.format.schema.Rule + 5, // 39: biscuit.format.schema.Policy.kind:type_name -> biscuit.format.schema.Policy.Kind + 13, // 40: biscuit.format.schema.AuthorizerPolicies.facts:type_name -> biscuit.format.schema.Fact + 14, // 41: biscuit.format.schema.AuthorizerPolicies.rules:type_name -> biscuit.format.schema.Rule + 15, // 42: biscuit.format.schema.AuthorizerPolicies.checks:type_name -> biscuit.format.schema.Check + 28, // 43: biscuit.format.schema.AuthorizerPolicies.policies:type_name -> biscuit.format.schema.Policy + 9, // 44: biscuit.format.schema.ThirdPartyBlockRequest.legacyPreviousKey:type_name -> biscuit.format.schema.PublicKey + 9, // 45: biscuit.format.schema.ThirdPartyBlockRequest.legacyPublicKeys:type_name -> biscuit.format.schema.PublicKey + 8, // 46: biscuit.format.schema.ThirdPartyBlockContents.externalSignature:type_name -> biscuit.format.schema.ExternalSignature + 33, // 47: biscuit.format.schema.AuthorizerSnapshot.limits:type_name -> biscuit.format.schema.RunLimits + 34, // 48: biscuit.format.schema.AuthorizerSnapshot.world:type_name -> biscuit.format.schema.AuthorizerWorld + 9, // 49: biscuit.format.schema.AuthorizerWorld.publicKeys:type_name -> biscuit.format.schema.PublicKey + 38, // 50: biscuit.format.schema.AuthorizerWorld.blocks:type_name -> biscuit.format.schema.SnapshotBlock + 38, // 51: biscuit.format.schema.AuthorizerWorld.authorizerBlock:type_name -> biscuit.format.schema.SnapshotBlock + 28, // 52: biscuit.format.schema.AuthorizerWorld.authorizerPolicies:type_name -> biscuit.format.schema.Policy + 37, // 53: biscuit.format.schema.AuthorizerWorld.generatedFacts:type_name -> biscuit.format.schema.GeneratedFacts + 36, // 54: biscuit.format.schema.Origin.authorizer:type_name -> biscuit.format.schema.Empty + 35, // 55: biscuit.format.schema.GeneratedFacts.origins:type_name -> biscuit.format.schema.Origin + 13, // 56: biscuit.format.schema.GeneratedFacts.facts:type_name -> biscuit.format.schema.Fact + 13, // 57: biscuit.format.schema.SnapshotBlock.facts:type_name -> biscuit.format.schema.Fact + 14, // 58: biscuit.format.schema.SnapshotBlock.rules:type_name -> biscuit.format.schema.Rule + 15, // 59: biscuit.format.schema.SnapshotBlock.checks:type_name -> biscuit.format.schema.Check + 12, // 60: biscuit.format.schema.SnapshotBlock.scope:type_name -> biscuit.format.schema.Scope + 9, // 61: biscuit.format.schema.SnapshotBlock.externalKey:type_name -> biscuit.format.schema.PublicKey + 62, // [62:62] is the sub-list for method output_type + 62, // [62:62] is the sub-list for method input_type + 62, // [62:62] is the sub-list for extension type_name + 62, // [62:62] is the sub-list for extension extendee + 0, // [0:62] is the sub-list for field type_name } func init() { file_biscuit_proto_init() } @@ -1643,237 +3049,47 @@ func file_biscuit_proto_init() { if File_biscuit_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_biscuit_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Biscuit); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SignedBlock); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PublicKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Proof); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Block); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FactV2); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RuleV2); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckV2); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PredicateV2); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TermV2); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TermSet); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExpressionV2); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Op); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OpUnary); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OpBinary); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Policy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_biscuit_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthorizerPolicies); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_biscuit_proto_msgTypes[3].OneofWrappers = []interface{}{ + file_biscuit_proto_msgTypes[4].OneofWrappers = []any{ (*Proof_NextSecret)(nil), (*Proof_FinalSignature)(nil), } - file_biscuit_proto_msgTypes[9].OneofWrappers = []interface{}{ - (*TermV2_Variable)(nil), - (*TermV2_Integer)(nil), - (*TermV2_String_)(nil), - (*TermV2_Date)(nil), - (*TermV2_Bytes)(nil), - (*TermV2_Bool)(nil), - (*TermV2_Set)(nil), - } - file_biscuit_proto_msgTypes[12].OneofWrappers = []interface{}{ + file_biscuit_proto_msgTypes[6].OneofWrappers = []any{ + (*Scope_ScopeType_)(nil), + (*Scope_PublicKey)(nil), + } + file_biscuit_proto_msgTypes[11].OneofWrappers = []any{ + (*Term_Variable)(nil), + (*Term_Integer)(nil), + (*Term_String_)(nil), + (*Term_Date)(nil), + (*Term_Bytes)(nil), + (*Term_Bool)(nil), + (*Term_Set)(nil), + (*Term_Null)(nil), + (*Term_Array)(nil), + (*Term_Map)(nil), + } + file_biscuit_proto_msgTypes[16].OneofWrappers = []any{ + (*MapKey_Integer)(nil), + (*MapKey_String_)(nil), + } + file_biscuit_proto_msgTypes[18].OneofWrappers = []any{ (*Op_Value)(nil), (*Op_Unary)(nil), (*Op_Binary)(nil), + (*Op_Closure)(nil), + } + file_biscuit_proto_msgTypes[29].OneofWrappers = []any{ + (*Origin_Authorizer)(nil), + (*Origin_Origin)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_biscuit_proto_rawDesc, - NumEnums: 4, - NumMessages: 17, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_biscuit_proto_rawDesc), len(file_biscuit_proto_rawDesc)), + NumEnums: 6, + NumMessages: 33, NumExtensions: 0, NumServices: 0, }, @@ -1883,7 +3099,6 @@ func file_biscuit_proto_init() { MessageInfos: file_biscuit_proto_msgTypes, }.Build() File_biscuit_proto = out.File - file_biscuit_proto_rawDesc = nil file_biscuit_proto_goTypes = nil file_biscuit_proto_depIdxs = nil } diff --git a/pb/biscuit.proto b/pb/biscuit.proto index b443c32d..5f76d5c3 100644 --- a/pb/biscuit.proto +++ b/pb/biscuit.proto @@ -1,6 +1,7 @@ syntax = "proto2"; option go_package = ".;pb"; +package biscuit.format.schema; message Biscuit { optional uint32 rootKeyId = 1; @@ -13,6 +14,13 @@ message SignedBlock { required bytes block = 1; required PublicKey nextKey = 2; required bytes signature = 3; + optional ExternalSignature externalSignature = 4; + optional uint32 version = 5; +} + +message ExternalSignature { + required bytes signature = 1; + required PublicKey publicKey = 2; } message PublicKey { @@ -20,12 +28,12 @@ message PublicKey { enum Algorithm { Ed25519 = 0; + SECP256R1 = 1; } required bytes key = 2; } - message Proof { oneof Content { bytes nextSecret = 1; @@ -37,31 +45,53 @@ message Block { repeated string symbols = 1; optional string context = 2; optional uint32 version = 3; - repeated FactV2 facts_v2 = 4; - repeated RuleV2 rules_v2 = 5; - repeated CheckV2 checks_v2 = 6; + repeated Fact facts = 4; + repeated Rule rules = 5; + repeated Check checks = 6; + repeated Scope scope = 7; + repeated PublicKey publicKeys = 8; +} + +message Scope { + enum ScopeType { + Authority = 0; + Previous = 1; + } + + oneof Content { + ScopeType scopeType = 1; + int64 publicKey = 2; + } } -message FactV2 { - required PredicateV2 predicate = 1; +message Fact { + required Predicate predicate = 1; } -message RuleV2 { - required PredicateV2 head = 1; - repeated PredicateV2 body = 2; - repeated ExpressionV2 expressions = 3; +message Rule { + required Predicate head = 1; + repeated Predicate body = 2; + repeated Expression expressions = 3; + repeated Scope scope = 4; } -message CheckV2 { - repeated RuleV2 queries = 1; +message Check { + repeated Rule queries = 1; + optional Kind kind = 2; + + enum Kind { + One = 0; + All = 1; + Reject = 2; + } } -message PredicateV2 { +message Predicate { required uint64 name = 1; - repeated TermV2 terms = 2; + repeated Term terms = 2; } -message TermV2 { +message Term { oneof Content { uint32 variable = 1; int64 integer = 2; @@ -70,22 +100,46 @@ message TermV2 { bytes bytes = 5; bool bool = 6; TermSet set = 7; + Empty null = 8; + Array array = 9; + Map map = 10; } } message TermSet { - repeated TermV2 set = 1; + repeated Term set = 1; } -message ExpressionV2 { +message Array { + repeated Term array = 1; +} + +message Map { + repeated MapEntry entries = 1; +} + +message MapEntry { + required MapKey key = 1; + required Term value = 2; +} + +message MapKey { + oneof Content { + int64 integer = 1; + uint64 string = 2; + } +} + +message Expression { repeated Op ops = 1; } message Op { oneof Content { - TermV2 value = 1; + Term value = 1; OpUnary unary = 2; OpBinary Binary = 3; + OpClosure closure = 4; } } @@ -94,9 +148,12 @@ message OpUnary { Negate = 0; Parens = 1; Length = 2; + TypeOf = 3; + Ffi = 4; } required Kind kind = 1; + optional uint64 ffiName = 2; } message OpBinary { @@ -118,9 +175,28 @@ message OpBinary { Or = 14; Intersection = 15; Union = 16; + BitwiseAnd = 17; + BitwiseOr = 18; + BitwiseXor = 19; + NotEqual = 20; + HeterogeneousEqual = 21; + HeterogeneousNotEqual = 22; + LazyAnd = 23; + LazyOr = 24; + All = 25; + Any = 26; + Get = 27; + Ffi = 28; + TryOr = 29; } required Kind kind = 1; + optional uint64 ffiName = 2; +} + +message OpClosure { + repeated uint32 params = 1; + repeated Op ops = 2; } message Policy { @@ -129,15 +205,74 @@ message Policy { Deny = 1; } - repeated RuleV2 queries = 1; + repeated Rule queries = 1; required Kind kind = 2; } message AuthorizerPolicies { repeated string symbols = 1; optional uint32 version = 2; - repeated FactV2 facts = 3; - repeated RuleV2 rules = 4; - repeated CheckV2 checks = 5; + repeated Fact facts = 3; + repeated Rule rules = 4; + repeated Check checks = 5; repeated Policy policies = 6; } + +message ThirdPartyBlockRequest { + optional PublicKey legacyPreviousKey = 1; + repeated PublicKey legacyPublicKeys = 2; + required bytes previousSignature = 3; + +} + +message ThirdPartyBlockContents { + required bytes payload = 1; + required ExternalSignature externalSignature = 2; +} + +message AuthorizerSnapshot { + required RunLimits limits = 1; + required uint64 executionTime = 2; + required AuthorizerWorld world = 3; +} + +message RunLimits { + required uint64 maxFacts = 1; + required uint64 maxIterations = 2; + required uint64 maxTime = 3; +} + +message AuthorizerWorld { + optional uint32 version = 1; + repeated string symbols = 2; + repeated PublicKey publicKeys = 3; + repeated SnapshotBlock blocks = 4; + required SnapshotBlock authorizerBlock = 5; + repeated Policy authorizerPolicies = 6; + repeated GeneratedFacts generatedFacts = 7; + required uint64 iterations = 8; +} + +message Origin { + oneof Content { + Empty authorizer = 1; + uint32 origin = 2; + } +} + +message Empty {} + +message GeneratedFacts { + repeated Origin origins = 1; + repeated Fact facts = 2; +} + +message SnapshotBlock { + optional string context = 1; + optional uint32 version = 2; + repeated Fact facts = 3; + repeated Rule rules = 4; + repeated Check checks = 5; + repeated Scope scope = 6; + optional PublicKey externalKey = 7; +} diff --git a/samples/data/current/README.md b/samples/data/current/README.md index dfb46a6a..9b319e63 100644 --- a/samples/data/current/README.md +++ b/samples/data/current/README.md @@ -1,7 +1,7 @@ # Biscuit samples and expected results -root secret key: 12aca40167fbdd1a11037e9fd440e3d510d9d9dea70a6646aa4aaf84d718d75a -root public key: acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189 +root secret key: 99e87b0e9158531eeeb503ff15266e2b23c2a2507b138c9d1b1f2ab458df2d61 +root public key: 1055c750b1a1505937af1537c626ba3263995c33a64758aaafb1275b0312e284 ------------------------------ @@ -13,6 +13,8 @@ symbols: ["file1", "file2"] public keys: [] +block version: 3 + ``` right("file1", "read"); right("file2", "read"); @@ -24,6 +26,8 @@ symbols: ["0"] public keys: [] +block version: 3 + ``` check if resource($0), operation("read"), right($0, "read"); ``` @@ -38,51 +42,48 @@ allow if true; ``` revocation ids: -- `36d2d7cf28796c69a0ed6dfa0fde5b3ffb2f637f0ba19aa1da858353e88678ad945ebaaa566a050b8abe8adb5b873855900b157e1e5f1cc11047a14385e5a203` -- `b694af382e2115df7d02bb88a75b9c0cdcb9e51c23dea082c306b1b7a26dfe9a3ca7ba7ca3a8089e7b88bb3718ff0294c2a0dc6b5b810f64462e89393ff35e05` +- `7595a112a1eb5b81a6e398852e6118b7f5b8cbbff452778e655100e5fb4faa8d3a2af52fe2c4f9524879605675fae26adbc4783e0cafc43522fa82385f396c03` +- `45f4c14f9d9e8fa044d68be7a2ec8cddb835f575c7b913ec59bd636c70acae9a90db9064ba0b3084290ed0c422bbb7170092a884f5e0202b31e9235bbcc1650d` authorizer world: ``` World { - facts: { - ( - "resource(\"file1\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "right(\"file1\", \"read\")", - { - Some( - 0, - ), - }, - ), - ( - "right(\"file1\", \"write\")", - { - Some( - 0, - ), - }, - ), - ( - "right(\"file2\", \"read\")", - { + facts: [ + "resource(\"file1\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), -} - rules: {} - checks: { - "check if resource($0), operation(\"read\"), right($0, \"read\")", -} - policies: { + facts: [ + "right(\"file1\", \"read\")", + "right(\"file1\", \"write\")", + "right(\"file2\", \"read\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 1, + ), + checks: [ + "check if resource($0), operation(\"read\"), right($0, \"read\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -99,6 +100,8 @@ symbols: ["file1"] public keys: [] +block version: 3 + ``` right("file1", "read"); ``` @@ -108,6 +111,8 @@ symbols: ["0"] public keys: [] +block version: 3 + ``` check if resource($0), operation("read"), right($0, "read"); ``` @@ -127,6 +132,8 @@ symbols: ["file1", "file2"] public keys: [] +block version: 3 + ``` right("file1", "read"); right("file2", "read"); @@ -138,13 +145,15 @@ symbols: ["0"] public keys: [] +block version: 3 + ``` check if resource($0), operation("read"), right($0, "read"); ``` ### validation -result: `Err(Format(InvalidSignatureSize(16)))` +result: `Err(Format(BlockSignatureDeserializationError("block signature deserialization error: [117, 149, 161, 18, 161, 235, 91, 129, 166, 227, 152, 133, 46, 97, 24, 183]")))` ------------------------------ @@ -157,6 +166,8 @@ symbols: ["file1", "file2"] public keys: [] +block version: 3 + ``` right("file1", "read"); right("file2", "read"); @@ -168,6 +179,8 @@ symbols: ["0"] public keys: [] +block version: 3 + ``` check if resource($0), operation("read"), right($0, "read"); ``` @@ -187,6 +200,8 @@ symbols: ["file1", "file2"] public keys: [] +block version: 3 + ``` right("file1", "read"); right("file2", "read"); @@ -198,6 +213,8 @@ symbols: ["0"] public keys: [] +block version: 3 + ``` check if resource($0), operation("read"), right($0, "read"); ``` @@ -217,6 +234,8 @@ symbols: ["file1", "file2"] public keys: [] +block version: 3 + ``` right("file1", "read"); right("file2", "read"); @@ -228,6 +247,8 @@ symbols: ["0"] public keys: [] +block version: 3 + ``` check if resource($0), operation("read"), right($0, "read"); ``` @@ -237,6 +258,8 @@ symbols: [] public keys: [] +block version: 3 + ``` check if resource("file1"); ``` @@ -256,6 +279,8 @@ symbols: ["user_id", "alice", "file1"] public keys: [] +block version: 3 + ``` user_id("alice"); owner("alice", "file1"); @@ -266,6 +291,8 @@ symbols: ["0", "1"] public keys: [] +block version: 3 + ``` right($0, "read") <- resource($0), user_id($1), owner($1, $0); check if resource($0), operation("read"), right($0, "read"); @@ -276,6 +303,8 @@ symbols: ["file2"] public keys: [] +block version: 3 + ``` owner("alice", "file2"); ``` @@ -291,65 +320,68 @@ allow if true; ``` revocation ids: -- `9ff0d3b8dcd5235b5d88e17a21d5c789953e3bf4769ee40f34d4bc276b8672858504f6ae8098c43328a1e60589d7efc0e5fd2ec70a229904a1c493262d498c09` -- `9e82a5f203e17d0515af7486599c1608d82a41c8e8cfe4457cb30c0eb62273d89970a2316223ccfdb64a49214762e80e82938531a2e0dc462f14ff52205e9107` -- `c24b1da5ece026338fd3175648e443b97dce52659efe47881583cd35574670b21abdb345ebd0adf095620d8d7b805028fdcb480c24170d34e023e3a8df29fb04` +- `4d86c9af808dc2e0583f47282e6f5df3e09dc264d5231ec360b4519e15ddaeec60b25a9bbcb22e8d192f4d36a0da3f9243711e30535b00ee55c53cb1395f230a` +- `63208c668c66f3ba6927140ba37533593b25e03459447805d4b2a8b75adeef45794c3d7249afe506ed77ccee276160bb4052a4009302bd34871a440f070b4509` +- `d8da982888eae8c038e4894a8c06fc57d8e5f06ad2e972b9cf4bde49ad60804558a0d1938192596c702d8e4f7f12ec19201d7c33d0cd77774a0d879a33880d02` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "owner(\"alice\", \"file1\")", - { + facts: [ + "operation(\"read\")", + "resource(\"file2\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), - ( - "owner(\"alice\", \"file2\")", - { + facts: [ + "owner(\"alice\", \"file1\")", + "user_id(\"alice\")", + ], + }, + Facts { + origin: { Some( 2, ), }, - ), - ( - "resource(\"file2\")", - { - None, - }, - ), - ( - "user_id(\"alice\")", - { - Some( - 0, - ), - }, - ), -} - rules: { - ( - "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0)", - Some( + facts: [ + "owner(\"alice\", \"file2\")", + ], + }, +] + rules: [ + Rules { + origin: Some( 1, ), - ), -} - checks: { - "check if resource($0), operation(\"read\"), right($0, \"read\")", -} - policies: { + rules: [ + "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0)", + ], + }, +] + checks: [ + Checks { + origin: Some( + 1, + ), + checks: [ + "check if resource($0), operation(\"read\"), right($0, \"read\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -366,6 +398,8 @@ symbols: ["file1"] public keys: [] +block version: 3 + ``` right("file1", "read"); ``` @@ -375,6 +409,8 @@ symbols: ["0"] public keys: [] +block version: 3 + ``` check if resource($0), operation("read"), right($0, "read"); ``` @@ -384,6 +420,8 @@ symbols: ["file2"] public keys: [] +block version: 3 + ``` right("file2", "read"); ``` @@ -399,50 +437,58 @@ allow if true; ``` revocation ids: -- `ba4d8f66dd4e3fef1f35d75be6df25fc41fbe237f645ea4434678add9dc356be23462eb1ada51bbb446995539f43b5d04581190ce2de66ea6194563efe88d603` -- `3a69659a56d933ea7bf2dc4ccab997ed0bec6ce26b178ec24a9ec0d2fc006bcf31eae762f17cb5862457459b3d5ae9c17845dcf45f8cf0acd774e06f6b7d620d` -- `c0f06ebdf58b5e17b150e7306a9361667a6a6d9945c1d478b4e8d9fac1869bd7726ef57e5cb9de95fe48718984e7dce617d5394caf25822cd646310affb2a202` +- `a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00` +- `77df45442be86a416aa02fd9d98d6d4703c634a9e3b1d293b41f5dc97849afbe7faeec8c22a210574888acc008fb64fe691ec9e8d2655586f970d9a6b6577000` +- `b31398aefe97d3db41ebc445760f216fb3aa7bf7439adcfc3a07489bfcc163970af3f4e20f5460aa24cf841101a5ab114d21acc0ee8d442bae7793b121284900` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "resource(\"file2\")", - { - None, - }, - ), - ( - "right(\"file1\", \"read\")", - { + facts: [ + "operation(\"read\")", + "resource(\"file2\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), - ( - "right(\"file2\", \"read\")", - { + facts: [ + "right(\"file1\", \"read\")", + ], + }, + Facts { + origin: { Some( 2, ), }, - ), -} - rules: {} - checks: { - "check if resource($0), operation(\"read\"), right($0, \"read\")", -} - policies: { + facts: [ + "right(\"file2\", \"read\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 1, + ), + checks: [ + "check if resource($0), operation(\"read\"), right($0, \"read\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -459,14 +505,18 @@ symbols: [] public keys: [] +block version: 3 + ``` ``` 1: -symbols: ["file1", "expiration"] +symbols: ["file1"] public keys: [] +block version: 3 + ``` check if resource("file1"); check if time($time), $time <= 2018-12-20T00:00:00Z; @@ -484,40 +534,39 @@ allow if true; ``` revocation ids: -- `ceb1a909c91d558a962c23d9d1c60aa06279f9dff1cc546ca6b2b6bf17db6fe4a03a04e9c1ed9131b7c6f3e609d5f17abab289909ae46f5e66f8876a5946a20c` -- `73e270352f08a98007b383ac85192f878a098c7ae55bbd1b7da67a44d9e94a5192aa02277707ec6747ec973aa0d7e270cd73bb0b46df2d8e434e4b9a06571208` +- `c248907bb6e5f433bbb5edf6367b399ebefca0d321d0b2ea9fc67f66dc1064ce926adb0c05d90c3e8a2833328b3578f79c4e1bca43583d9bcfb2ba6c37303d00` +- `a4edf7aaea8658bb9ae19b3ffe2adcc77cc9f16c249aeb0a85a584b5362f89f27f7c67ac0af16d7170673d6d1fb1563d1934b25ec5a461f6c01fa49805cd5e07` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { - None, - }, - ), - ( - "resource(\"file1\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "time(2020-12-21T09:23:12Z)", - { - None, - }, - ), -} - rules: {} - checks: { - "check if resource(\"file1\")", - "check if time($time), $time <= 2018-12-20T00:00:00Z", -} - policies: { + facts: [ + "operation(\"read\")", + "resource(\"file1\")", + "time(2020-12-21T09:23:12Z)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 1, + ), + checks: [ + "check if resource(\"file1\")", + "check if time($time), $time <= 2018-12-20T00:00:00Z", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -534,6 +583,8 @@ symbols: ["file1"] public keys: [] +block version: 3 + ``` right("file1", "read"); ``` @@ -543,6 +594,8 @@ symbols: ["file2"] public keys: [] +block version: 3 + ``` right("file2", "read"); ``` @@ -560,49 +613,57 @@ allow if true; ``` revocation ids: -- `ba4d8f66dd4e3fef1f35d75be6df25fc41fbe237f645ea4434678add9dc356be23462eb1ada51bbb446995539f43b5d04581190ce2de66ea6194563efe88d603` -- `d1d56ea3c9469186fe32f56a2c488b31b2dead6701ce833d521d2b1f223355edb058839c68ea6b50af02e2ffa4b92d80116b25f1cb0623b6685cb3415677970a` +- `a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00` +- `966eceb2aa937c41b25368808bab6e0698c02a4038de669d007c9c3d43602638a640083558d1576ac80cf3eb2ac6a7585527e0f6c1a65402f0935cf7f4df8005` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { - None, - }, - ), - ( - "resource(\"file2\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "right(\"file1\", \"read\")", - { + facts: [ + "operation(\"read\")", + "resource(\"file2\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), - ( - "right(\"file2\", \"read\")", - { + facts: [ + "right(\"file1\", \"read\")", + ], + }, + Facts { + origin: { Some( 1, ), }, - ), -} - rules: {} - checks: { - "check if right($0, $1), resource($0), operation($1)", -} - policies: { + facts: [ + "right(\"file2\", \"read\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 18446744073709551615, + ), + checks: [ + "check if right($0, $1), resource($0), operation($1)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -619,6 +680,8 @@ symbols: ["file1"] public keys: [] +block version: 3 + ``` right("file1", "read"); ``` @@ -636,40 +699,46 @@ allow if true; ``` revocation ids: -- `ba4d8f66dd4e3fef1f35d75be6df25fc41fbe237f645ea4434678add9dc356be23462eb1ada51bbb446995539f43b5d04581190ce2de66ea6194563efe88d603` +- `a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "resource(\"file2\")", - { - None, - }, - ), - ( - "right(\"file1\", \"read\")", - { + facts: [ + "operation(\"read\")", + "resource(\"file2\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), -} - rules: {} - checks: { - "check if right($0, $1), resource($0), operation($1)", -} - policies: { + facts: [ + "right(\"file1\", \"read\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 18446744073709551615, + ), + checks: [ + "check if right($0, $1), resource($0), operation($1)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -686,6 +755,8 @@ symbols: ["file1"] public keys: [] +block version: 3 + ``` check if resource("file1"); ``` @@ -701,32 +772,36 @@ allow if true; ``` revocation ids: -- `bc15caa9476568fef796c13385d0cf455df66a0b1aa2be7980549f69aa5a4a7864555d94ddd64c652c7c24c191298dd5c0ca1aadb638ffd91971d15edee0aa07` +- `6a8f90dad67ae2ac188460463914ae7326fda431c80785755f4edcc15f1a53911f7366e606ad80cbbeba94672e42713e88632a932128f1d796ce9ba7d7a0b80a` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { - None, - }, - ), - ( - "resource(\"file1\")", - { + facts: [ + Facts { + origin: { None, }, - ), -} - rules: {} - checks: { - "check if resource(\"file1\")", -} - policies: { + facts: [ + "operation(\"read\")", + "resource(\"file1\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if resource(\"file1\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -742,32 +817,36 @@ allow if true; ``` revocation ids: -- `bc15caa9476568fef796c13385d0cf455df66a0b1aa2be7980549f69aa5a4a7864555d94ddd64c652c7c24c191298dd5c0ca1aadb638ffd91971d15edee0aa07` +- `6a8f90dad67ae2ac188460463914ae7326fda431c80785755f4edcc15f1a53911f7366e606ad80cbbeba94672e42713e88632a932128f1d796ce9ba7d7a0b80a` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { - None, - }, - ), - ( - "resource(\"file2\")", - { + facts: [ + Facts { + origin: { None, }, - ), -} - rules: {} - checks: { - "check if resource(\"file1\")", -} - policies: { + facts: [ + "operation(\"read\")", + "resource(\"file2\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if resource(\"file1\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -784,6 +863,8 @@ symbols: ["file1", "file2"] public keys: [] +block version: 3 + ``` right("file1", "read"); right("file2", "read"); @@ -794,9 +875,11 @@ symbols: ["valid_date", "0", "1"] public keys: [] +block version: 3 + ``` 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); +valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, !{"file1"}.contains($1); check if valid_date($0), resource($0); ``` @@ -811,71 +894,69 @@ allow if true; ``` revocation ids: -- `58a9aead6684468383ba121d1d1ba6a2dd087f41240ecb3b8229587b7717630d5db86e230c4aa3a6da802f04483da06ae4cb71c7c35f30207550be4450787601` -- `745941a089e3e4efc479ac8d934fc0f95d9add8dca119c68e2ef34dfb285385396ad9b2d2cf6633894c234b1b9c854978be6788ca05262e3d2362e82f984b605` +- `c46d071ff3f33434223c8305fdad529f62bf78bb5d9cbfc2a345d4bca6bf314014840e18ba353f86fdb9073d58b12b8c872ac1f8e593c2e9064b90f6c2ede006` +- `a0c4c163a0b3ca406df4ece3d1371356190df04208eccef72f77e875ed0531b5d37e243d6f388b1967776a5dfd16ef228f19c5bdd6d2820f145c5ed3c3dcdc00` authorizer world: ``` World { - facts: { - ( - "resource(\"file1\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "right(\"file1\", \"read\")", - { + facts: [ + "resource(\"file1\")", + "time(2020-12-21T09:23:12Z)", + ], + }, + Facts { + origin: { + None, Some( - 0, + 1, ), }, - ), - ( - "right(\"file2\", \"read\")", - { + facts: [ + "valid_date(\"file1\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), - ( - "time(2020-12-21T09:23:12Z)", - { - None, - }, - ), - ( - "valid_date(\"file1\")", - { - None, - Some( - 1, - ), - }, - ), -} - rules: { - ( - "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z", - Some( + facts: [ + "right(\"file1\", \"read\")", + "right(\"file2\", \"read\")", + ], + }, +] + rules: [ + Rules { + origin: Some( 1, ), - ), - ( - "valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1)", - Some( + 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: [ + Checks { + origin: Some( 1, ), - ), -} - checks: { - "check if valid_date($0), resource($0)", -} - policies: { + checks: [ + "check if valid_date($0), resource($0)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -891,62 +972,58 @@ allow if true; ``` revocation ids: -- `58a9aead6684468383ba121d1d1ba6a2dd087f41240ecb3b8229587b7717630d5db86e230c4aa3a6da802f04483da06ae4cb71c7c35f30207550be4450787601` -- `745941a089e3e4efc479ac8d934fc0f95d9add8dca119c68e2ef34dfb285385396ad9b2d2cf6633894c234b1b9c854978be6788ca05262e3d2362e82f984b605` +- `c46d071ff3f33434223c8305fdad529f62bf78bb5d9cbfc2a345d4bca6bf314014840e18ba353f86fdb9073d58b12b8c872ac1f8e593c2e9064b90f6c2ede006` +- `a0c4c163a0b3ca406df4ece3d1371356190df04208eccef72f77e875ed0531b5d37e243d6f388b1967776a5dfd16ef228f19c5bdd6d2820f145c5ed3c3dcdc00` authorizer world: ``` World { - facts: { - ( - "resource(\"file2\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "right(\"file1\", \"read\")", - { - Some( - 0, - ), - }, - ), - ( - "right(\"file2\", \"read\")", - { + facts: [ + "resource(\"file2\")", + "time(2020-12-21T09:23:12Z)", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), - ( - "time(2020-12-21T09:23:12Z)", - { - None, - }, - ), -} - rules: { - ( - "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z", - Some( + facts: [ + "right(\"file1\", \"read\")", + "right(\"file2\", \"read\")", + ], + }, +] + rules: [ + Rules { + origin: Some( 1, ), - ), - ( - "valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1)", - Some( + 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: [ + Checks { + origin: Some( 1, ), - ), -} - checks: { - "check if valid_date($0), resource($0)", -} - policies: { + checks: [ + "check if valid_date($0), resource($0)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -963,6 +1040,8 @@ symbols: ["0", "file[0-9]+.txt"] public keys: [] +block version: 3 + ``` check if resource($0), $0.matches("file[0-9]+.txt"); ``` @@ -977,26 +1056,35 @@ allow if true; ``` revocation ids: -- `7d2e7c6bc4878efcdb7f704948e668fcf5338cb1e4eeb5f0434944ace98597652f062d67e2ebdb47fe2c7b17d40f0d8a2386cb2d753fb430168be5e0b5fd410b` +- `da42718ad2631c12d3a44b7710dcc76c6c7809c6bc3a2d7eb0378c4154eae10e0884a8d54a2cd25ca3dfe01091d816ebbb9d246227baf7a359a787cb2344ad07` authorizer world: ``` World { - facts: { - ( - "resource(\"file1\")", - { + facts: [ + Facts { + origin: { None, }, - ), -} - rules: {} - checks: { - "check if resource($0), $0.matches(\"file[0-9]+.txt\")", -} - policies: { + facts: [ + "resource(\"file1\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if resource($0), $0.matches(\"file[0-9]+.txt\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1011,26 +1099,35 @@ allow if true; ``` revocation ids: -- `7d2e7c6bc4878efcdb7f704948e668fcf5338cb1e4eeb5f0434944ace98597652f062d67e2ebdb47fe2c7b17d40f0d8a2386cb2d753fb430168be5e0b5fd410b` +- `da42718ad2631c12d3a44b7710dcc76c6c7809c6bc3a2d7eb0378c4154eae10e0884a8d54a2cd25ca3dfe01091d816ebbb9d246227baf7a359a787cb2344ad07` authorizer world: ``` World { - facts: { - ( - "resource(\"file123.txt\")", - { + facts: [ + Facts { + origin: { None, }, - ), -} - rules: {} - checks: { - "check if resource($0), $0.matches(\"file[0-9]+.txt\")", -} - policies: { + facts: [ + "resource(\"file123.txt\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if resource($0), $0.matches(\"file[0-9]+.txt\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1047,6 +1144,8 @@ symbols: ["must_be_present", "hello"] public keys: [] +block version: 3 + ``` must_be_present("hello"); ``` @@ -1061,28 +1160,37 @@ allow if true; ``` revocation ids: -- `e2c762315434ccc9194e012e47e75afb3329a46488a468d75d776b5a502ee5930d04750ae7b1836617fe07051bd92d4ce8336d662da4ca9ce9e9d4f4af5be70d` +- `b0d466d31e015fa85a075fa875f7e1c9017edd503fee9f62a5f033e1fcfa811074b6e39dfe5af2f452043db97a3f98650592a370f5685b62c5d6abf9dd10b603` authorizer world: ``` World { - facts: { - ( - "must_be_present(\"hello\")", - { + facts: [ + Facts { + origin: { Some( 0, ), }, - ), -} - rules: {} - checks: { - "check if must_be_present($0) or must_be_present($0)", -} - policies: { + facts: [ + "must_be_present(\"hello\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 18446744073709551615, + ), + checks: [ + "check if must_be_present($0) or must_be_present($0)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1099,6 +1207,8 @@ symbols: ["hello"] public keys: [] +block version: 3 + ``` check if resource("hello"); ``` @@ -1108,6 +1218,8 @@ symbols: ["test"] public keys: [] +block version: 3 + ``` query("test"); ``` @@ -1120,29 +1232,38 @@ allow if true; ``` revocation ids: -- `812958ef3b43273b2c8e88bb13d0f91f0a8f5bf95544f79dafdaff07d89bd551baca72f83589b9e89120b0dc41c0f4b10678f03dd1b3ac0422e16074ff396b08` -- `51c0e278bed1085afe45519aa60d5b4b9e13f1819dadb38fb5854ed3a599bfe18485d8f396219540bd17bfb9f46ab3c407a4ac51ebf88734b4f2fb56b24a6e01` +- `ce6f804f4390e693a8853d9a4a10bd4f3c94b86b7c6d671993a6e19346bc4d20bbb52cc945e5d0d02e4e75fa5da2caa99764050190353564a0a0b4b276809402` +- `916d566cc724e0773046fc5266e9d0d804311435b8d6955b332f823ab296be9a78dfea190447732ac9f6217234cf5726becf88f65169c6de56a766af55451b0f` authorizer world: ``` World { - facts: { - ( - "query(\"test\")", - { + facts: [ + Facts { + origin: { Some( 1, ), }, - ), -} - rules: {} - checks: { - "check if resource(\"hello\")", -} - policies: { + facts: [ + "query(\"test\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if resource(\"hello\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1155,50 +1276,52 @@ result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedB ### token authority: -symbols: ["hello world", "hello", "world", "aaabde", "a*c?.e", "abd", "aaa", "b", "de", "abcD12", "abc", "def"] +symbols: ["hello world", "hello", "world", "aaabde", "a*c?.e", "abd", "aaa", "b", "de", "abcD12", "é", "abc", "def"] public keys: [] +block version: 3 + ``` check if true; check if !false; -check if !false && true; -check if false || true; -check if (true || false) && true; -check if true == true; -check if false == false; +check if true === true; +check if false === false; check if 1 < 2; check if 2 > 1; check if 1 <= 2; check if 1 <= 1; check if 2 >= 1; check if 2 >= 2; -check if 3 == 3; -check if 1 + 2 * 3 - 4 / 2 == 5; -check if "hello world".starts_with("hello") && "hello world".ends_with("world"); +check if 3 === 3; +check if 1 + 2 * 3 - 4 / 2 === 5; +check if "hello world".starts_with("hello"), "hello world".ends_with("world"); check if "aaabde".matches("a*c?.e"); check if "aaabde".contains("abd"); -check if "aaabde" == "aaa" + "b" + "de"; -check if "abcD12" == "abcD12"; +check if "aaabde" === "aaa" + "b" + "de"; +check if "abcD12" === "abcD12"; +check if "abcD12".length() === 6; +check if "é".length() === 2; check if 2019-12-04T09:46:41Z < 2020-12-04T09:46:41Z; check if 2020-12-04T09:46:41Z > 2019-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 >= 2020-12-04T09:46:41Z; -check if 2020-12-04T09:46:41Z == 2020-12-04T09:46:41Z; -check if hex:12ab == hex:12ab; -check if [1, 2].contains(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 ["abc", "def"].contains("abc"); -check if [hex:12ab, hex:34de].contains(hex:34de); -check if [1, 2].contains([2]); -check if [1, 2] == [1, 2]; -check if [1, 2].intersection([2, 3]) == [2]; -check if [1, 2].union([2, 3]) == [1, 2, 3]; -check if [1, 2, 3].intersection([1, 2]).contains(1); -check if [1, 2, 3].intersection([1, 2]).length() == 2; +check if 2020-12-04T09:46:41Z === 2020-12-04T09:46:41Z; +check if hex:12ab === hex:12ab; +check if {1, 2}.contains(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 {"abc", "def"}.contains("abc"); +check if {hex:12ab, hex:34de}.contains(hex:34de); +check if {1, 2}.contains({2}); +check if {1, 2} === {1, 2}; +check if {1, 2}.intersection({2, 3}) === {2}; +check if {1, 2}.union({2, 3}) === {1, 2, 3}; +check if {1, 2, 3}.intersection({1, 2}).contains(1); +check if {1, 2, 3}.intersection({1, 2}).length() === 2; +check if {,}.length() === 0; ``` ### validation @@ -1209,56 +1332,64 @@ allow if true; ``` revocation ids: -- `a0fdd27c0d21292a4d944a86a9e97cfee7513969a209729ebcff2dec50b8725816dad3b9d7fc004d3f6dc705399c303c1a76a8b955a5f23d2045132b68b4d50b` +- `fa358e4e3bea896415b1859e6cd347e64e1918fb86e31ae3fe208628321576a47f7a269760357e291c827ec9cbe322074f6860a546207a64e133c83a214bb505` authorizer world: ``` 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 \"hello world\".starts_with(\"hello\") && \"hello world\".ends_with(\"world\")", - "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 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: { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if !false", + "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 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 false === false", + "check if hex:12ab === hex:12ab", + "check if true", + "check if true === true", + "check if {\"abc\", \"def\"}.contains(\"abc\")", + "check if {,}.length() === 0", + "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)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1275,6 +1406,8 @@ symbols: [] public keys: [] +block version: 3 + ``` check if operation("read"); ``` @@ -1284,6 +1417,8 @@ symbols: ["unbound", "any1", "any2"] public keys: [] +block version: 3 + ``` operation($unbound, "read") <- operation($any1, $any2); ``` @@ -1303,6 +1438,8 @@ symbols: [] public keys: [] +block version: 3 + ``` check if operation("read"); ``` @@ -1312,6 +1449,8 @@ symbols: ["any"] public keys: [] +block version: 3 + ``` operation("read") <- operation($any); ``` @@ -1326,43 +1465,56 @@ allow if true; ``` revocation ids: -- `6d79797e655457166810826d7c398bc75ac4896d8de80650298796faf0aaf67f2abb80c46efdd915a210c9401bc41c75f3a7c19bebe4c02be9c991fae62b8808` -- `f7d3f3eadd83cc30aa3c0a9b8288d44b9107b5a099e52da6447fdb7aca5d00cd58add7b7b12b3fb73bd9b664f33ed207d91efcda2d05523cb9b8db0e9bca0502` +- `a44210c6a01e55eadefc7d8540c2e6eff80ab6eeedde4751de734f9d780435780680d3f42d826b7e0f0dcf4a5ba303fd4c116984bb30978813d46ed867924307` +- `d3f8822a9b9bc0ee3933283c493ca9e711be5dd8339b5fe2eba1de3805aad4e84d3e2fb4affb4a743f1289915c167582b9425343635e45b70573ea1ee7a1ea03` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "operation(\"write\")", + ], + }, + Facts { + origin: { None, Some( 1, ), }, - ), - ( - "operation(\"write\")", - { - None, - }, - ), -} - rules: { - ( - "operation(\"read\") <- operation($any)", - Some( + facts: [ + "operation(\"read\")", + ], + }, +] + rules: [ + Rules { + origin: Some( 1, ), - ), -} - checks: { - "check if operation(\"read\")", -} - policies: { + rules: [ + "operation(\"read\") <- operation($any)", + ], + }, +] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if operation(\"read\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1379,6 +1531,8 @@ symbols: ["file1", "file2"] public keys: [] +block version: 3 + ``` right("file1", "read"); right("file2", "read"); @@ -1390,6 +1544,8 @@ symbols: ["0"] public keys: [] +block version: 3 + ``` check if resource($0), operation("read"), right($0, "read"); ``` @@ -1405,57 +1561,49 @@ allow if true; ``` revocation ids: -- `36d2d7cf28796c69a0ed6dfa0fde5b3ffb2f637f0ba19aa1da858353e88678ad945ebaaa566a050b8abe8adb5b873855900b157e1e5f1cc11047a14385e5a203` -- `b694af382e2115df7d02bb88a75b9c0cdcb9e51c23dea082c306b1b7a26dfe9a3ca7ba7ca3a8089e7b88bb3718ff0294c2a0dc6b5b810f64462e89393ff35e05` +- `7595a112a1eb5b81a6e398852e6118b7f5b8cbbff452778e655100e5fb4faa8d3a2af52fe2c4f9524879605675fae26adbc4783e0cafc43522fa82385f396c03` +- `45f4c14f9d9e8fa044d68be7a2ec8cddb835f575c7b913ec59bd636c70acae9a90db9064ba0b3084290ed0c422bbb7170092a884f5e0202b31e9235bbcc1650d` authorizer world: ``` World { - facts: { - ( - "operation(\"read\")", - { - None, - }, - ), - ( - "resource(\"file1\")", - { + facts: [ + Facts { + origin: { None, }, - ), - ( - "right(\"file1\", \"read\")", - { - Some( - 0, - ), - }, - ), - ( - "right(\"file1\", \"write\")", - { + facts: [ + "operation(\"read\")", + "resource(\"file1\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), - ( - "right(\"file2\", \"read\")", - { - Some( - 0, - ), - }, - ), -} - rules: {} - checks: { - "check if resource($0), operation(\"read\"), right($0, \"read\")", -} - policies: { + facts: [ + "right(\"file1\", \"read\")", + "right(\"file1\", \"write\")", + "right(\"file2\", \"read\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 1, + ), + checks: [ + "check if resource($0), operation(\"read\"), right($0, \"read\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1472,6 +1620,8 @@ symbols: ["ns::fact_123", "hello é\t😁"] public keys: [] +block version: 3 + ``` ns::fact_123("hello é 😁"); ``` @@ -1486,28 +1636,37 @@ allow if true; ``` revocation ids: -- `6a945aca807c25971cc4b711cd6364141fdaf4cee013022416f22986240238cc029b5ae41eb5c5b8a461b0d6063329132b5bac91ca8b51e82829a2b6a273150d` +- `d4b2f417b6e906434fdf5058afcabfcb98d3628f814f1c9dd7e64250d9beec4465aff51bd0cb2e85d0e67dc9f613c2a42af6158c678bc6f8b4684cd3a2d0d302` authorizer world: ``` World { - facts: { - ( - "ns::fact_123(\"hello é\t😁\")", - { + facts: [ + Facts { + origin: { Some( 0, ), }, - ), -} - rules: {} - checks: { - "check if ns::fact_123(\"hello é\t😁\")", -} - policies: { + facts: [ + "ns::fact_123(\"hello é\t😁\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 18446744073709551615, + ), + checks: [ + "check if ns::fact_123(\"hello é\t😁\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1524,6 +1683,8 @@ symbols: [] public keys: [] +block version: 3 + ``` read(0); write(1); @@ -1565,324 +1726,161 @@ allow if true; ``` revocation ids: -- `23183284bdad88fbf5b4cbaed2218cf0a38d7e360f3ac401d6337eecf36e8da1ce15eda6d11fe94c20c344f687327d9338a0e863f98c9a14576739533d2fb804` +- `75ce48d496fd28f99905901783a1ba46d7ff8d69f9d364d1546fd73006026eae51849ad1190a4ae521a0a1269f9c6951e226afba8fcd24fa50f679162439ae09` authorizer world: ``` World { - facts: { - ( - "admin(13)", - { - Some( - 0, - ), - }, - ), - ( - "client(18)", - { - Some( - 0, - ), - }, - ), - ( - "client_ip(19)", - { - Some( - 0, - ), - }, - ), - ( - "cluster(23)", - { + facts: [ + Facts { + origin: { Some( 0, ), }, - ), - ( - "domain(20)", - { + 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: [ + Checks { + origin: Some( + 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)` + + +------------------------------ + +## execution scope: test023_execution_scope.bc +### token + +authority: +symbols: ["authority_fact"] + +public keys: [] + +block version: 3 + +``` +authority_fact(1); +``` + +1: +symbols: ["block1_fact"] + +public keys: [] + +block version: 3 + +``` +block1_fact(1); +``` + +2: +symbols: ["var"] + +public keys: [] + +block version: 3 + +``` +check if authority_fact($var); +check if block1_fact($var); +``` + +### validation + +authorizer code: +``` +allow if true; +``` + +revocation ids: +- `f9b49866caef5ece7be14ec5a9b36d98ca81d06b306eb0b4c57cd7436af176f40ee972f40903f87ec4460ab8b1adfcbfa9b19b20a6955a1e8dae7d88b2076005` +- `889054b9119e4440e54da1b63266a98d0f6646cde195fef206efd8b133cfb2ee7be49b32a9a5925ece452e64f9e6f6d80dab422e916c599675dd68cdea053802` +- `0a85ffbf27e08aa23665ba0d96a985b274d747556c9f016fd7f590c641ed0e4133291521aa442b320ee9ce80f5ad701b914a0c87b3dfa0cc92629dce94201806` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { Some( 0, ), }, - ), - ( - "email(14)", - { + facts: [ + "authority_fact(1)", + ], + }, + Facts { + origin: { Some( - 0, + 1, ), }, - ), - ( - "group(15)", - { - Some( - 0, - ), - }, - ), - ( - "hostname(25)", - { - Some( - 0, - ), - }, - ), - ( - "ip_address(17)", - { - Some( - 0, - ), - }, - ), - ( - "member(16)", - { - Some( - 0, - ), - }, - ), - ( - "namespace(9)", - { - Some( - 0, - ), - }, - ), - ( - "node(24)", - { - Some( - 0, - ), - }, - ), - ( - "nonce(26)", - { - Some( - 0, - ), - }, - ), - ( - "operation(3)", - { - Some( - 0, - ), - }, - ), - ( - "owner(7)", - { - Some( - 0, - ), - }, - ), - ( - "path(21)", - { - Some( - 0, - ), - }, - ), - ( - "query(27)", - { - Some( - 0, - ), - }, - ), - ( - "read(0)", - { - Some( - 0, - ), - }, - ), - ( - "resource(2)", - { - Some( - 0, - ), - }, - ), - ( - "right(4)", - { - Some( - 0, - ), - }, - ), - ( - "role(6)", - { - Some( - 0, - ), - }, - ), - ( - "service(12)", - { - Some( - 0, - ), - }, - ), - ( - "team(11)", - { - Some( - 0, - ), - }, - ), - ( - "tenant(8)", - { - Some( - 0, - ), - }, - ), - ( - "time(5)", - { - Some( - 0, - ), - }, - ), - ( - "user(10)", - { - Some( - 0, - ), - }, - ), - ( - "version(22)", - { - Some( - 0, - ), - }, - ), - ( - "write(1)", - { - Some( - 0, - ), - }, - ), -} - 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)` - - ------------------------------- - -## execution scope: test023_execution_scope.bc -### token - -authority: -symbols: ["authority_fact"] - -public keys: [] - -``` -authority_fact(1); -``` - -1: -symbols: ["block1_fact"] - -public keys: [] - -``` -block1_fact(1); -``` - -2: -symbols: ["var"] - -public keys: [] - -``` -check if authority_fact($var); -check if block1_fact($var); -``` - -### validation - -authorizer code: -``` -allow if true; -``` - -revocation ids: -- `8c94b6f3a2cbe086a7df1135f04c7b88b4a8d6b4f595cd963e8f2a36b9c1edb551f1b0360f7995eec8ea8c846847fba53932f5e70aaee7783a852c83c08dd80b` -- `ce286369809e4f4a6e2d6b95ba6c19af28c3694ffd408d09ee292c0233a3d73e3257151d6099177ae61aa71cfb91f85b3ccac80952bf5d34c9e807c5e4cf2c04` -- `9bc1209ffa1e11d5fd3fe3811e55893e6c5a94d56e5835e83f7a84142db50642899b92705a32ab64a375e36e665564607cbf50d6366682b5381849f8e8b3340a` - -authorizer world: -``` -World { - facts: { - ( - "authority_fact(1)", - { - Some( - 0, - ), - }, - ), - ( - "block1_fact(1)", - { - Some( - 1, - ), - }, - ), -} - rules: {} - checks: { - "check if authority_fact($var)", - "check if block1_fact($var)", -} - policies: { + facts: [ + "block1_fact(1)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 2, + ), + checks: [ + "check if authority_fact($var)", + "check if block1_fact($var)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1899,6 +1897,8 @@ symbols: [] public keys: ["ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"] +block version: 4 + ``` right("read"); check if group("admin") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189; @@ -1911,6 +1911,8 @@ public keys: [] external signature by: "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189" +block version: 5 + ``` group("admin"); check if right("read"); @@ -1924,38 +1926,56 @@ allow if true; ``` revocation ids: -- `f5e36f36c18a9a7d3660366a9dccf1eeefbb2a639571e5aba63714cf02e412d222f7aadec14aef59cb5cf104e0d3bdba439c4147249e2d703498b2f0610e1008` -- `79217fcc94823ccbfc1cdbd6aaf770890659bb94d48ca14dddff70e9d0d386a4755e452e732a071c8e9884ca280ead059c473b3bd4ea5f82e99ee3c484518004` +- `470e4bf7aa2a01ab39c98150bd06aa15b4aa5d86509044a8809a8634cd8cf2b42269a51a774b65d10bac9369d013070b00187925196a8e680108473f11cf8f03` +- `901b2af4dacf33458d2d91ac484b60bad948e8d10faa9695b096054d5b46e832a977b60b17464cacf545ad0801f549ea454675f0ac88c413406925e2af83ff08` authorizer world: ``` World { - facts: { - ( - "group(\"admin\")", - { + facts: [ + Facts { + origin: { Some( - 1, + 0, ), }, - ), - ( - "right(\"read\")", - { + facts: [ + "right(\"read\")", + ], + }, + Facts { + origin: { Some( - 0, + 1, ), }, - ), -} - rules: {} - checks: { - "check if group(\"admin\") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", - "check if right(\"read\")", -} - policies: { + facts: [ + "group(\"admin\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if group(\"admin\") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", + ], + }, + Checks { + origin: Some( + 1, + ), + checks: [ + "check if right(\"read\")", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -1972,8 +1992,10 @@ symbols: ["allowed_operations", "A", "B", "op", "allowed"] public keys: [] +block version: 4 + ``` -allowed_operations(["A", "B"]); +allowed_operations({"A", "B"}); check all operation($op), allowed_operations($allowed), $allowed.contains($op); ``` @@ -1988,40 +2010,46 @@ allow if true; ``` revocation ids: -- `96f15d9598d682d387d9f01b4df28f6f29e6e2a0d2cdd699266a685e983f64c8349054a77ca7e940d6775da79ed53d41373863e3a35b86181d132148a8d5980a` +- `c456817012e1d523c6d145b6d6a3475d9f7dd4383c535454ff3f745ecf4234984ce09b9dec0551f3d783abe850f826ce43b12f1fd91999a4753a56ecf4c56d0d` authorizer world: ``` World { - facts: { - ( - "allowed_operations([\"A\", \"B\"])", - { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "operation(\"A\")", + "operation(\"B\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), - ( - "operation(\"A\")", - { - None, - }, - ), - ( - "operation(\"B\")", - { - None, - }, - ), -} - rules: {} - checks: { - "check all operation($op), allowed_operations($allowed), $allowed.contains($op)", -} - policies: { + facts: [ + "allowed_operations({\"A\", \"B\"})", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check all operation($op), allowed_operations($allowed), $allowed.contains($op)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -2037,40 +2065,46 @@ allow if true; ``` revocation ids: -- `96f15d9598d682d387d9f01b4df28f6f29e6e2a0d2cdd699266a685e983f64c8349054a77ca7e940d6775da79ed53d41373863e3a35b86181d132148a8d5980a` +- `c456817012e1d523c6d145b6d6a3475d9f7dd4383c535454ff3f745ecf4234984ce09b9dec0551f3d783abe850f826ce43b12f1fd91999a4753a56ecf4c56d0d` authorizer world: ``` World { - facts: { - ( - "allowed_operations([\"A\", \"B\"])", - { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "operation(\"A\")", + "operation(\"invalid\")", + ], + }, + Facts { + origin: { Some( 0, ), }, - ), - ( - "operation(\"A\")", - { - None, - }, - ), - ( - "operation(\"invalid\")", - { - None, - }, - ), -} - rules: {} - checks: { - "check all operation($op), allowed_operations($allowed), $allowed.contains($op)", -} - policies: { + facts: [ + "allowed_operations({\"A\", \"B\"})", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check all operation($op), allowed_operations($allowed), $allowed.contains($op)", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -2087,6 +2121,8 @@ symbols: [] public keys: ["ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"] +block version: 4 + ``` query(0); check if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189; @@ -2095,10 +2131,12 @@ check if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755 1: symbols: [] -public keys: ["ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463"] +public keys: ["ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"] external signature by: "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189" +block version: 5 + ``` query(1); query(1, 2) <- query(1), query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463; @@ -2109,10 +2147,12 @@ check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5 2: symbols: [] -public keys: [] +public keys: ["ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"] external signature by: "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463" +block version: 5 + ``` query(2); check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463; @@ -2122,10 +2162,12 @@ check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5 3: symbols: [] -public keys: [] +public keys: ["ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189"] external signature by: "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463" +block version: 5 + ``` query(3); check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463; @@ -2135,7 +2177,9 @@ check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5 4: symbols: [] -public keys: ["ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136"] +public keys: ["ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", "ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136"] + +block version: 4 ``` query(4); @@ -2156,35 +2200,38 @@ allow if true; ``` revocation ids: -- `0e823acf10d97afef5d327d08ecde17fad1808388dedf678770b60521170180f4ad3b4dc81494d92122658f3bbfe2567ad5493b2bf0fc6570f2be52566320d03` -- `35bacaf3a817a26ffcb6a2b5658ef60665b63696c00061f5cef75fe3dac315595f0e24c20533916d90077b708e62396bf4b50dcd774092b43100f9271cd9830a` -- `3198c7f606e1611e6a6df503b74a9ac5769dd11b3a1c6c4d5f0e3dbf92671d009e0ec648fadc49442e9c94455258c8502ed2d5031a57436f2521520a0b9ac009` -- `16f8e0231f514816282621730510e41e0ba1a41d1944634f13fe4aaf28d0565e658fa624186fafc0bd996af39b638a31904b637e24ecc791f3d7210f9b83d90e` -- `68db0a0319dd91ee6638fe5fe380f9037c63b37fd0674b9df01cae5e40fcfe37a04498cba34a92433c6f9d3c423be5a5fbee49136b734f9d98d1b7962c1e730b` +- `3771cefe71beb21ead35a59c8116ee82627a5717c0295f35980662abccb159fe1b37848cb1818e548656bd4fd882d0094a2daab631c76b2b72e3a093914bfe04` +- `7113d4dbb3b688b80e941f365a2c6342d480c77ed03937bccf85dc5cc3554c7517887b1b0c9021388a71e6ca9047aabaaad5ae5b511a2880902568444a98e50b` +- `d0e3fc4bbd1b7320022800af909585aa906f677c4ca79c275a10b6779f669384c464ee84a1b04f13877a25761a874748362c065f4d15a8cab5c5e16c34074403` +- `29b7e0a1f118a6185814a552660c516c43482044e280e7a8de85b8e7e54947e0ae82eb39d7b524d4b72cb9812a7a4b8871964f8f825b1c1ed85d344c05281d0d` +- `c0a505d4d921a8b2d0b885917d42e2bca87b5302d13249a61af6f3802af44d691c40a624f901d677724740cb974a188aeb1c3992c1565ac0fbec3aa4f68dac0a` authorizer world: ``` World { - facts: { - ( - "query(0)", - { + facts: [ + Facts { + origin: { Some( 0, ), }, - ), - ( - "query(1)", - { + facts: [ + "query(0)", + ], + }, + Facts { + origin: { Some( 1, ), }, - ), - ( - "query(1, 2)", - { + facts: [ + "query(1)", + ], + }, + Facts { + origin: { Some( 1, ), @@ -2192,54 +2239,111 @@ World { 2, ), }, - ), - ( - "query(2)", - { + facts: [ + "query(1, 2)", + ], + }, + Facts { + origin: { Some( 2, ), }, - ), - ( - "query(3)", - { + facts: [ + "query(2)", + ], + }, + Facts { + origin: { Some( 3, ), }, - ), - ( - "query(4)", - { + facts: [ + "query(3)", + ], + }, + Facts { + origin: { Some( 4, ), }, - ), -} - rules: { - ( - "query(1, 2) <- query(1), query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", - Some( + facts: [ + "query(4)", + ], + }, +] + rules: [ + Rules { + origin: Some( 1, ), - ), -} - checks: { - "check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", - "check if query(1, 2) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189, ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", - "check if query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", - "check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", - "check if query(4) trusting ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136", - "check if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", -} - policies: { - "allow if true", - "deny if query(0) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", - "deny if query(1, 2)", + rules: [ + "query(1, 2) <- query(1), query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", + ], + }, +] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", + ], + }, + Checks { + origin: Some( + 1, + ), + checks: [ + "check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", + "check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", + ], + }, + Checks { + origin: Some( + 2, + ), + checks: [ + "check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", + "check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", + ], + }, + Checks { + origin: Some( + 3, + ), + checks: [ + "check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", + "check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", + ], + }, + Checks { + origin: Some( + 4, + ), + checks: [ + "check if query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", + "check if query(4) trusting ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136", + ], + }, + Checks { + origin: Some( + 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", +] } ``` @@ -2256,10 +2360,12 @@ symbols: [] public keys: [] +block version: 4 + ``` -check if true || 10000000000 * 10000000000 != 0; -check if true || 9223372036854775807 + 1 != 0; -check if true || -9223372036854775808 - 1 != 0; +check if 10000000000 * 10000000000 !== 0; +check if 9223372036854775807 + 1 !== 0; +check if -9223372036854775808 - 1 !== 0; ``` ### validation @@ -2270,21 +2376,28 @@ allow if true; ``` revocation ids: -- `c554195c11cd462ca550f833833fad64213bdbef31d5e4b48ae6c2dc072d5218792bbf0da612f7ec9d20dc04c505d8c6ebdeee96ae95307546227efca713c70b` +- `fb5e7ac2bb892f5cf2fb59677cfad1f96deabbc8e158e3fd1b5ee7c4b6949c999e2169187cbee53b943eebdadaaf68832747baa8cffa2ff9f78025a1f55f440c` authorizer world: ``` World { - facts: {} - rules: {} - checks: { - "check if true || -9223372036854775808 - 1 != 0", - "check if true || 10000000000 * 10000000000 != 0", - "check if true || 9223372036854775807 + 1 != 0", -} - policies: { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if -9223372036854775808 - 1 !== 0", + "check if 10000000000 * 10000000000 !== 0", + "check if 9223372036854775807 + 1 !== 0", + ], + }, +] + policies: [ "allow if true", -} +] } ``` @@ -2301,13 +2414,15 @@ symbols: ["abcD12x", "abcD12"] public keys: [] +block version: 4 + ``` -check if 1 != 3; -check if 1 | 2 ^ 3 == 0; -check if "abcD12x" != "abcD12"; -check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z; -check if hex:12abcd != hex:12ab; -check if [1, 4] != [1, 2]; +check if 1 !== 3; +check if 1 | 2 ^ 3 === 0; +check if "abcD12x" !== "abcD12"; +check if 2022-12-04T09:46:41Z !== 2020-12-04T09:46:41Z; +check if hex:12abcd !== hex:12ab; +check if {1, 4} !== {1, 2}; ``` ### validation @@ -2318,26 +2433,1177 @@ allow if true; ``` revocation ids: -- `56ff3e571202e641dfb84955adb6700b61e42e1100412b3e0e957f1693875fbb8fdeaeb008092b2f42c5c7ded97cde638eeaf3ab73df678273f6ba970916ad00` +- `117fa653744c859561555e6a6f5990e3a8e7817f91b87aa6991b6d64297158b4e884c92d10f49f74c96069df722aa676839b72751ca9d1fe83a7025b591de00b` authorizer world: ``` World { - facts: {} - rules: {} - 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: { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 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 hex:12abcd !== hex:12ab", + "check if {1, 4} !== {1, 2}", + ], + }, +] + policies: [ "allow if true", +] } +``` + +result: `Ok(0)` + + +------------------------------ + +## test reject if: test029_reject_if.bc +### token + +authority: +symbols: ["test"] + +public keys: [] + +block version: 6 + +``` +reject if test($test), $test; +``` + +### validation + +authorizer code: +``` +test(false); + +allow if true; +``` + +revocation ids: +- `8d175329f7cf161f3cb5badc52f0e22e520956cdb565edbed963e9b047b20a314a7de1c9eba6b7bbf622636516ab3cc7f91572ae9461d3152825e0ece5127a0a` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "test(false)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "reject if test($test), $test", + ], + }, +] + policies: [ + "allow if true", +] } ``` result: `Ok(0)` +### validation for "rejection" + +authorizer code: +``` +test(true); + +allow if true; +``` + +revocation ids: +- `8d175329f7cf161f3cb5badc52f0e22e520956cdb565edbed963e9b047b20a314a7de1c9eba6b7bbf622636516ab3cc7f91572ae9461d3152825e0ece5127a0a` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "test(true)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "reject if test($test), $test", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedBlockCheck { block_id: 0, check_id: 0, rule: "reject if test($test), $test" })] }))` + + +------------------------------ + +## test null: test030_null.bc +### token + +authority: +symbols: ["fact", "value"] + +public keys: [] + +block version: 6 + +``` +check if fact(null, $value), $value == null; +reject if fact(null, $value), $value != null; +``` + +### validation + +authorizer code: +``` +fact(null, null); + +allow if true; +``` + +revocation ids: +- `fe50d65706a5945c76569d1ff2be8ece24276857631e96efa05959f73bb4ea8c772945738a01da77a1661aef2b8233b4f4e49ae220f2c81fd0b8da59c212750b` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "fact(null, null)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if fact(null, $value), $value == null", + "reject if fact(null, $value), $value != null", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` +### validation for "rejection1" + +authorizer code: +``` +fact(null, 1); + +allow if true; +``` + +revocation ids: +- `fe50d65706a5945c76569d1ff2be8ece24276857631e96efa05959f73bb4ea8c772945738a01da77a1661aef2b8233b4f4e49ae220f2c81fd0b8da59c212750b` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "fact(null, 1)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if fact(null, $value), $value == null", + "reject if fact(null, $value), $value != null", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedBlockCheck { block_id: 0, check_id: 0, rule: "check if fact(null, $value), $value == null" }), Block(FailedBlockCheck { block_id: 0, check_id: 1, rule: "reject if fact(null, $value), $value != null" })] }))` +### validation for "rejection2" + +authorizer code: +``` +fact(null, true); + +allow if true; +``` + +revocation ids: +- `fe50d65706a5945c76569d1ff2be8ece24276857631e96efa05959f73bb4ea8c772945738a01da77a1661aef2b8233b4f4e49ae220f2c81fd0b8da59c212750b` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "fact(null, true)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if fact(null, $value), $value == null", + "reject if fact(null, $value), $value != null", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedBlockCheck { block_id: 0, check_id: 0, rule: "check if fact(null, $value), $value == null" }), Block(FailedBlockCheck { block_id: 0, check_id: 1, rule: "reject if fact(null, $value), $value != null" })] }))` +### validation for "rejection3" + +authorizer code: +``` +fact(null, "abcd"); + +allow if true; +``` + +revocation ids: +- `fe50d65706a5945c76569d1ff2be8ece24276857631e96efa05959f73bb4ea8c772945738a01da77a1661aef2b8233b4f4e49ae220f2c81fd0b8da59c212750b` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "fact(null, \"abcd\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if fact(null, $value), $value == null", + "reject if fact(null, $value), $value != null", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedBlockCheck { block_id: 0, check_id: 0, rule: "check if fact(null, $value), $value == null" }), Block(FailedBlockCheck { block_id: 0, check_id: 1, rule: "reject if fact(null, $value), $value != null" })] }))` + + +------------------------------ + +## test heterogeneous equal: test031_heterogeneous_equal.bc +### token + +authority: +symbols: ["abcD12", "abcD12x", "fact", "value", "fact2"] + +public keys: [] + +block version: 6 + +``` +check if true == true; +check if false == false; +check if false != true; +check if 1 != true; +check if 1 == 1; +check if 1 != 3; +check if 1 != true; +check if "abcD12" == "abcD12"; +check if "abcD12x" != "abcD12"; +check if "abcD12x" != true; +check if 2022-12-04T09:46:41Z == 2022-12-04T09:46:41Z; +check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z; +check if 2022-12-04T09:46:41Z != true; +check if hex:12abcd == hex:12abcd; +check if hex:12abcd != hex:12ab; +check if hex:12abcd != true; +check if {1, 2} == {1, 2}; +check if {1, 4} != {1, 2}; +check if {1, 4} != true; +check if fact(1, $value), 1 == $value; +check if fact2(1, $value), 1 != $value; +``` + +### validation + +authorizer code: +``` +fact(1, 1); +fact2(1, 2); + +allow if true; +``` + +revocation ids: +- `be50b2040f4b5fe278b87815910d249eeb9ca5238cae4ea538e22afda11f576e868cbfe7e6b0a03b02ae0f22239ec908947d4bad5a878e4b9f7bd7de73e5c90a` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "fact(1, 1)", + "fact2(1, 2)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if \"abcD12\" == \"abcD12\"", + "check if \"abcD12x\" != \"abcD12\"", + "check if \"abcD12x\" != true", + "check if 1 != 3", + "check if 1 != true", + "check if 1 != true", + "check if 1 == 1", + "check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z", + "check if 2022-12-04T09:46:41Z != true", + "check if 2022-12-04T09:46:41Z == 2022-12-04T09:46:41Z", + "check if fact(1, $value), 1 == $value", + "check if fact2(1, $value), 1 != $value", + "check if false != true", + "check if false == false", + "check if hex:12abcd != hex:12ab", + "check if hex:12abcd != true", + "check if hex:12abcd == hex:12abcd", + "check if true == true", + "check if {1, 2} == {1, 2}", + "check if {1, 4} != true", + "check if {1, 4} != {1, 2}", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` +### validation for "evaluate to false" + +authorizer code: +``` +fact(1, 2); +fact2(1, 1); + +check if false != false; + +allow if true; +``` + +revocation ids: +- `be50b2040f4b5fe278b87815910d249eeb9ca5238cae4ea538e22afda11f576e868cbfe7e6b0a03b02ae0f22239ec908947d4bad5a878e4b9f7bd7de73e5c90a` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "fact(1, 2)", + "fact2(1, 1)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if \"abcD12\" == \"abcD12\"", + "check if \"abcD12x\" != \"abcD12\"", + "check if \"abcD12x\" != true", + "check if 1 != 3", + "check if 1 != true", + "check if 1 != true", + "check if 1 == 1", + "check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z", + "check if 2022-12-04T09:46:41Z != true", + "check if 2022-12-04T09:46:41Z == 2022-12-04T09:46:41Z", + "check if fact(1, $value), 1 == $value", + "check if fact2(1, $value), 1 != $value", + "check if false != true", + "check if false == false", + "check if hex:12abcd != hex:12ab", + "check if hex:12abcd != true", + "check if hex:12abcd == hex:12abcd", + "check if true == true", + "check if {1, 2} == {1, 2}", + "check if {1, 4} != true", + "check if {1, 4} != {1, 2}", + ], + }, + Checks { + origin: Some( + 18446744073709551615, + ), + checks: [ + "check if false != false", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Authorizer(FailedAuthorizerCheck { check_id: 0, rule: "check if false != false" }), Block(FailedBlockCheck { block_id: 0, check_id: 19, rule: "check if fact(1, $value), 1 == $value" }), Block(FailedBlockCheck { block_id: 0, check_id: 20, rule: "check if fact2(1, $value), 1 != $value" })] }))` + + +------------------------------ + +## test laziness and closures: test032_laziness_closures.bc +### token + +authority: +symbols: ["x", "p", "q"] + +public keys: [] + +block version: 6 + +``` +check if !false && true; +check if false || true; +check if (true || false) && true; +check if !(false && "x".intersection("x")); +check if true || "x".intersection("x"); +check if {1, 2, 3}.all($p -> $p > 0); +check if !{1, 2, 3}.all($p -> $p == 2); +check if {1, 2, 3}.any($p -> $p > 2); +check if !{1, 2, 3}.any($p -> $p > 3); +check if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q)); +``` + +### validation + +authorizer code: +``` +allow if true; +``` + +revocation ids: +- `2cd348b6df5f08b900903fd8d3fbea0bb89b665c331a2aa2131e0b8ecb38b3550275d4ccd8db35da6c4433eed1d456cfb761e3fcc7845894d891e986ca044b02` + +authorizer world: +``` +World { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if !(false && \"x\".intersection(\"x\"))", + "check if !false && true", + "check if !{1, 2, 3}.all($p -> $p == 2)", + "check if !{1, 2, 3}.any($p -> $p > 3)", + "check if (true || false) && true", + "check if false || true", + "check if true || \"x\".intersection(\"x\")", + "check if {1, 2, 3}.all($p -> $p > 0)", + "check if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q))", + "check if {1, 2, 3}.any($p -> $p > 2)", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` +### validation for "shadowing" + +authorizer code: +``` +allow if [true].any($p -> [true].all($p -> $p)); +``` + +revocation ids: +- `2cd348b6df5f08b900903fd8d3fbea0bb89b665c331a2aa2131e0b8ecb38b3550275d4ccd8db35da6c4433eed1d456cfb761e3fcc7845894d891e986ca044b02` + +authorizer world: +``` +World { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if !(false && \"x\".intersection(\"x\"))", + "check if !false && true", + "check if !{1, 2, 3}.all($p -> $p == 2)", + "check if !{1, 2, 3}.any($p -> $p > 3)", + "check if (true || false) && true", + "check if false || true", + "check if true || \"x\".intersection(\"x\")", + "check if {1, 2, 3}.all($p -> $p > 0)", + "check if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q))", + "check if {1, 2, 3}.any($p -> $p > 2)", + ], + }, +] + policies: [ + "allow if [true].any($p -> [true].all($p -> $p))", +] +} +``` + +result: `Err(Execution(ShadowedVariable))` + + +------------------------------ + +## test .type(): test033_typeof.bc +### token + +authority: +symbols: ["integer", "string", "test", "date", "bytes", "bool", "set", "null", "array", "map", "a", "t"] + +public keys: [] + +block version: 6 + +``` +integer(1); +string("test"); +date(2023-12-28T00:00:00Z); +bytes(hex:aa); +bool(true); +set({false, true}); +null(null); +array([1, 2, 3]); +map({"a": true}); +check if 1.type() == "integer"; +check if integer($t), $t.type() == "integer"; +check if "test".type() == "string"; +check if string($t), $t.type() == "string"; +check if (2023-12-28T00:00:00Z).type() == "date"; +check if date($t), $t.type() == "date"; +check if hex:aa.type() == "bytes"; +check if bytes($t), $t.type() == "bytes"; +check if true.type() == "bool"; +check if bool($t), $t.type() == "bool"; +check if {false, true}.type() == "set"; +check if set($t), $t.type() == "set"; +check if null.type() == "null"; +check if null($t), $t.type() == "null"; +check if array($t), $t.type() == "array"; +check if map($t), $t.type() == "map"; +``` + +### validation + +authorizer code: +``` +allow if true; +``` + +revocation ids: +- `e60875c6ef7917c227a5e4b2cabfe250a85fa0598eb3cf7987ded0da2b69a559a1665bd312aeecde78e76aeb28ea1c1a03ec9b7dec8aeb519e7867ef8ff9b402` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + Some( + 0, + ), + }, + facts: [ + "array([1, 2, 3])", + "bool(true)", + "bytes(hex:aa)", + "date(2023-12-28T00:00:00Z)", + "integer(1)", + "map({\"a\": true})", + "null(null)", + "set({false, true})", + "string(\"test\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if \"test\".type() == \"string\"", + "check if (2023-12-28T00:00:00Z).type() == \"date\"", + "check if 1.type() == \"integer\"", + "check if array($t), $t.type() == \"array\"", + "check if bool($t), $t.type() == \"bool\"", + "check if bytes($t), $t.type() == \"bytes\"", + "check if date($t), $t.type() == \"date\"", + "check if hex:aa.type() == \"bytes\"", + "check if integer($t), $t.type() == \"integer\"", + "check if map($t), $t.type() == \"map\"", + "check if null($t), $t.type() == \"null\"", + "check if null.type() == \"null\"", + "check if set($t), $t.type() == \"set\"", + "check if string($t), $t.type() == \"string\"", + "check if true.type() == \"bool\"", + "check if {false, true}.type() == \"set\"", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` + + +------------------------------ + +## test array and map operations: test034_array_map.bc +### token + +authority: +symbols: ["a", "b", "c", "p", "d", "A", "kv", "id", "roles"] + +public keys: [] + +block version: 6 + +``` +check if [1, 2, 1].length() == 3; +check if ["a", "b"] != true; +check if ["a", "b"] != [1, 2, 3]; +check if ["a", "b"] == ["a", "b"]; +check if ["a", "b"] === ["a", "b"]; +check if ["a", "b"] !== ["a", "c"]; +check if ["a", "b", "c"].contains("c"); +check if [1, 2, 3].starts_with([1, 2]); +check if [4, 5, 6].ends_with([6]); +check if [1, 2, "a"].get(2) == "a"; +check if [1, 2].get(3) == null; +check if [1, 2, 3].all($p -> $p > 0); +check if [1, 2, 3].any($p -> $p > 2); +check if {"a": 1, "b": 2, "c": 3, "d": 4}.length() == 4; +check if {1: "a", 2: "b"} != true; +check if {1: "a", 2: "b"} != {"a": 1, "b": 2}; +check if {1: "a", 2: "b"} == {1: "a", 2: "b"}; +check if {1: "a", 2: "b"} !== {"a": 1, "b": 2}; +check if {1: "a", 2: "b"} === {1: "a", 2: "b"}; +check if {"a": 1, "b": 2, "c": 3, "d": 4}.contains("d"); +check if {1: "A", "a": 1, "b": 2}.get("a") == 1; +check if {1: "A", "a": 1, "b": 2}.get(1) == "A"; +check if {1: "A", "a": 1, "b": 2}.get("c") == null; +check if {1: "A", "a": 1, "b": 2}.get(2) == null; +check if {"a": 1, "b": 2}.all($kv -> $kv.get(0) != "c" && $kv.get(1) < 3); +check if {1: "A", "a": 1, "b": 2}.any($kv -> $kv.get(0) == 1 && $kv.get(1) == "A"); +check if {"user": {"id": 1, "roles": ["admin"]}}.get("user").get("roles").contains("admin"); +``` + +### validation + +authorizer code: +``` +allow if true; +``` + +revocation ids: +- `b22238a06ca9c015d3c49d4ebaa7e8ab6e0d69119b3264033618e726d62fc6f4757a7bebc25f255444aba39994554a62a53ecc13b68802efab8da85ace62390d` + +authorizer world: +``` +World { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if [\"a\", \"b\", \"c\"].contains(\"c\")", + "check if [\"a\", \"b\"] != [1, 2, 3]", + "check if [\"a\", \"b\"] != true", + "check if [\"a\", \"b\"] !== [\"a\", \"c\"]", + "check if [\"a\", \"b\"] == [\"a\", \"b\"]", + "check if [\"a\", \"b\"] === [\"a\", \"b\"]", + "check if [1, 2, \"a\"].get(2) == \"a\"", + "check if [1, 2, 1].length() == 3", + "check if [1, 2, 3].all($p -> $p > 0)", + "check if [1, 2, 3].any($p -> $p > 2)", + "check if [1, 2, 3].starts_with([1, 2])", + "check if [1, 2].get(3) == null", + "check if [4, 5, 6].ends_with([6])", + "check if {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4}.contains(\"d\")", + "check if {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4}.length() == 4", + "check if {\"a\": 1, \"b\": 2}.all($kv -> $kv.get(0) != \"c\" && $kv.get(1) < 3)", + "check if {\"user\": {\"id\": 1, \"roles\": [\"admin\"]}}.get(\"user\").get(\"roles\").contains(\"admin\")", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.any($kv -> $kv.get(0) == 1 && $kv.get(1) == \"A\")", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.get(\"a\") == 1", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.get(\"c\") == null", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.get(1) == \"A\"", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.get(2) == null", + "check if {1: \"a\", 2: \"b\"} != true", + "check if {1: \"a\", 2: \"b\"} != {\"a\": 1, \"b\": 2}", + "check if {1: \"a\", 2: \"b\"} !== {\"a\": 1, \"b\": 2}", + "check if {1: \"a\", 2: \"b\"} == {1: \"a\", 2: \"b\"}", + "check if {1: \"a\", 2: \"b\"} === {1: \"a\", 2: \"b\"}", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` + + +------------------------------ + +## test ffi calls (v6 blocks): test035_ffi.bc +### token + +authority: +symbols: ["test", "a", "equal strings"] + +public keys: [] + +block version: 6 + +``` +check if true.extern::test(), "a".extern::test("a") == "equal strings"; +``` + +### validation + +authorizer code: +``` +allow if true; +``` + +revocation ids: +- `d1719fd101c2695d2dac4df67569918363f691b6167670e1dbbf8026f639a7aa1ec2e13707f4d34cadbb2adce5c6e8a816577dd069a8717e0f5cb4ea3cec5b04` + +authorizer world: +``` +World { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if true.extern::test(), \"a\".extern::test(\"a\") == \"equal strings\"", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` + + +------------------------------ + +## ECDSA secp256r1 signatures: test036_secp256r1.bc +### token + +authority: +symbols: ["file1", "file2"] + +public keys: [] + +block version: 3 + +``` +right("file1", "read"); +right("file2", "read"); +right("file1", "write"); +``` + +1: +symbols: ["0"] + +public keys: [] + +block version: 3 + +``` +check if resource($0), operation("read"), right($0, "read"); +``` + +### validation + +authorizer code: +``` +resource("file1"); +operation("read"); + +allow if true; +``` + +revocation ids: +- `628b9a6d74cc80b3ece50befd1f5f0f025c0a35d51708b2e77c11aed5f968b93b4096c87ed8169605716de934e155443f140334d71708fcc4247e5a0a518b30d` +- `3046022100b60674854a12814cc36c8aab9600c1d9f9d3160e2334b72c0feede5a56213ea5022100a4f4bbf2dc33b309267af39fce76612017ddb6171e9cd2a3aa8a853f45f1675f` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "operation(\"read\")", + "resource(\"file1\")", + ], + }, + Facts { + origin: { + Some( + 0, + ), + }, + facts: [ + "right(\"file1\", \"read\")", + "right(\"file1\", \"write\")", + "right(\"file2\", \"read\")", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 1, + ), + checks: [ + "check if resource($0), operation(\"read\"), right($0, \"read\")", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` + + +------------------------------ + +## ECDSA secp256r1 signature on third-party block: test037_secp256r1_third_party.bc +### token + +authority: +symbols: ["file1", "file2", "from_third"] + +public keys: ["secp256r1/025e918fd4463832aea2823dfd9716a36b4d9b1377bd53dd82ddf4c0bc75ed6bbf"] + +block version: 4 + +``` +right("file1", "read"); +right("file2", "read"); +right("file1", "write"); +check if from_third(true) trusting secp256r1/025e918fd4463832aea2823dfd9716a36b4d9b1377bd53dd82ddf4c0bc75ed6bbf; +``` + +1: +symbols: ["from_third", "0"] + +public keys: [] + +external signature by: "secp256r1/025e918fd4463832aea2823dfd9716a36b4d9b1377bd53dd82ddf4c0bc75ed6bbf" + +block version: 5 + +``` +from_third(true); +check if resource($0), operation("read"), right($0, "read"); +``` + +### validation + +authorizer code: +``` +resource("file1"); +operation("read"); + +allow if true; +``` + +revocation ids: +- `70f5402208516fd44cfc9df3dfcfc0a327ee9004f1801ed0a7abdcbbae923d566ddcd2d4a14f4622b35732c4e538af04075cc67ab0888fa2d8923cc668187f0f` +- `30450220793f95665d9af646339503a073670ea2c352459d2a2c2e14c57565f6c7eaf6bc022100cccadfc37e46755f52bb054ed206d7335067885df599a69431db40e33f33d4cf` + +authorizer world: +``` +World { + facts: [ + Facts { + origin: { + None, + }, + facts: [ + "operation(\"read\")", + "resource(\"file1\")", + ], + }, + Facts { + origin: { + Some( + 0, + ), + }, + facts: [ + "right(\"file1\", \"read\")", + "right(\"file1\", \"write\")", + "right(\"file2\", \"read\")", + ], + }, + Facts { + origin: { + Some( + 1, + ), + }, + facts: [ + "from_third(true)", + ], + }, +] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if from_third(true) trusting secp256r1/025e918fd4463832aea2823dfd9716a36b4d9b1377bd53dd82ddf4c0bc75ed6bbf", + ], + }, + Checks { + origin: Some( + 1, + ), + checks: [ + "check if resource($0), operation(\"read\"), right($0, \"read\")", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` + + +------------------------------ + +## test try operation: test038_try_op.bc +### token + +authority: +symbols: [] + +public keys: [] + +block version: 6 + +``` +check if (true === 12).try_or(true); +check if ((true === 12).try_or(true === 12)).try_or(true); +reject if (true == 12).try_or(true); +``` + +### validation + +authorizer code: +``` +allow if true; +``` + +revocation ids: +- `79674155cd5349604e89b00792aeaebfa0a512bd45edc289305ebec107f627d3d8c09847646a0d06c2390a4354771b2ebdc2cc66971f2d74ef744e4e81197600` + +authorizer world: +``` +World { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if ((true === 12).try_or(true === 12)).try_or(true)", + "check if (true === 12).try_or(true)", + "reject if (true == 12).try_or(true)", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Ok(0)` +### validation for "right-hand side does not catch errors" + +authorizer code: +``` +check if true.try_or(true === 12); + +allow if true; +``` + +revocation ids: +- `79674155cd5349604e89b00792aeaebfa0a512bd45edc289305ebec107f627d3d8c09847646a0d06c2390a4354771b2ebdc2cc66971f2d74ef744e4e81197600` + +authorizer world: +``` +World { + facts: [] + rules: [] + checks: [ + Checks { + origin: Some( + 0, + ), + checks: [ + "check if ((true === 12).try_or(true === 12)).try_or(true)", + "check if (true === 12).try_or(true)", + "reject if (true == 12).try_or(true)", + ], + }, + Checks { + origin: Some( + 18446744073709551615, + ), + checks: [ + "check if true.try_or(true === 12)", + ], + }, +] + policies: [ + "allow if true", +] +} +``` + +result: `Err(Execution(InvalidType))` diff --git a/samples/data/current/samples.json b/samples/data/current/samples.json index a8a16ffa..28a97c5f 100644 --- a/samples/data/current/samples.json +++ b/samples/data/current/samples.json @@ -1,6 +1,6 @@ { - "root_private_key": "12aca40167fbdd1a11037e9fd440e3d510d9d9dea70a6646aa4aaf84d718d75a", - "root_public_key": "acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", + "root_private_key": "99e87b0e9158531eeeb503ff15266e2b23c2a2507b138c9d1b1f2ab458df2d61", + "root_public_key": "1055c750b1a1505937af1537c626ba3263995c33a64758aaafb1275b0312e284", "testcases": [ { "title": "basic token", @@ -13,7 +13,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n" + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n", + "version": 3 }, { "symbols": [ @@ -21,41 +22,41 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n" + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "resource(\"file1\")", - [ + { + "origin": [ null + ], + "facts": [ + "resource(\"file1\")" ] - ], - [ - "right(\"file1\", \"read\")", - [ + }, + { + "origin": [ 0 + ], + "facts": [ + "right(\"file1\", \"read\")", + "right(\"file1\", \"write\")", + "right(\"file2\", \"read\")" ] - ], - [ - "right(\"file1\", \"write\")", - [ - 0 - ] - ], - [ - "right(\"file2\", \"read\")", - [ - 0 - ] - ] + } ], "rules": [], "checks": [ - "check if resource($0), operation(\"read\"), right($0, \"read\")" + { + "origin": 1, + "checks": [ + "check if resource($0), operation(\"read\"), right($0, \"read\")" + ] + } ], "policies": [ "allow if true" @@ -83,8 +84,8 @@ }, "authorizer_code": "resource(\"file1\");\n\nallow if true;\n", "revocation_ids": [ - "36d2d7cf28796c69a0ed6dfa0fde5b3ffb2f637f0ba19aa1da858353e88678ad945ebaaa566a050b8abe8adb5b873855900b157e1e5f1cc11047a14385e5a203", - "b694af382e2115df7d02bb88a75b9c0cdcb9e51c23dea082c306b1b7a26dfe9a3ca7ba7ca3a8089e7b88bb3718ff0294c2a0dc6b5b810f64462e89393ff35e05" + "7595a112a1eb5b81a6e398852e6118b7f5b8cbbff452778e655100e5fb4faa8d3a2af52fe2c4f9524879605675fae26adbc4783e0cafc43522fa82385f396c03", + "45f4c14f9d9e8fa044d68be7a2ec8cddb835f575c7b913ec59bd636c70acae9a90db9064ba0b3084290ed0c422bbb7170092a884f5e0202b31e9235bbcc1650d" ] } } @@ -99,7 +100,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\n" + "code": "right(\"file1\", \"read\");\n", + "version": 3 }, { "symbols": [ @@ -107,7 +109,8 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n" + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 } ], "validations": { @@ -138,7 +141,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n" + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n", + "version": 3 }, { "symbols": [ @@ -146,7 +150,8 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n" + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 } ], "validations": { @@ -155,7 +160,7 @@ "result": { "Err": { "Format": { - "InvalidSignatureSize": 16 + "BlockSignatureDeserializationError": "block signature deserialization error: [117, 149, 161, 18, 161, 235, 91, 129, 166, 227, 152, 133, 46, 97, 24, 183]" } } }, @@ -175,7 +180,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n" + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n", + "version": 3 }, { "symbols": [ @@ -183,7 +189,8 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n" + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 } ], "validations": { @@ -214,7 +221,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n" + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n", + "version": 3 }, { "symbols": [ @@ -222,7 +230,8 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n" + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 } ], "validations": { @@ -253,7 +262,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n" + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n", + "version": 3 }, { "symbols": [ @@ -261,13 +271,15 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n" + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 }, { "symbols": [], "public_keys": [], "external_key": null, - "code": "check if resource(\"file1\");\n" + "code": "check if resource(\"file1\");\n", + "version": 3 } ], "validations": { @@ -299,7 +311,8 @@ ], "public_keys": [], "external_key": null, - "code": "user_id(\"alice\");\nowner(\"alice\", \"file1\");\n" + "code": "user_id(\"alice\");\nowner(\"alice\", \"file1\");\n", + "version": 3 }, { "symbols": [ @@ -308,7 +321,8 @@ ], "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" + "code": "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0);\ncheck if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 }, { "symbols": [ @@ -316,52 +330,56 @@ ], "public_keys": [], "external_key": null, - "code": "owner(\"alice\", \"file2\");\n" + "code": "owner(\"alice\", \"file2\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "operation(\"read\")", - [ + { + "origin": [ null - ] - ], - [ - "owner(\"alice\", \"file1\")", - [ + ], + "facts": [ + "operation(\"read\")", + "resource(\"file2\")" + ] + }, + { + "origin": [ 0 - ] - ], - [ - "owner(\"alice\", \"file2\")", - [ + ], + "facts": [ + "owner(\"alice\", \"file1\")", + "user_id(\"alice\")" + ] + }, + { + "origin": [ 2 + ], + "facts": [ + "owner(\"alice\", \"file2\")" ] - ], - [ - "resource(\"file2\")", - [ - null - ] - ], - [ - "user_id(\"alice\")", - [ - 0 - ] - ] + } ], "rules": [ - [ - "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0)", - 1 - ] + { + "origin": 1, + "rules": [ + "right($0, \"read\") <- resource($0), user_id($1), owner($1, $0)" + ] + } ], "checks": [ - "check if resource($0), operation(\"read\"), right($0, \"read\")" + { + "origin": 1, + "checks": [ + "check if resource($0), operation(\"read\"), right($0, \"read\")" + ] + } ], "policies": [ "allow if true" @@ -389,9 +407,9 @@ }, "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n", "revocation_ids": [ - "9ff0d3b8dcd5235b5d88e17a21d5c789953e3bf4769ee40f34d4bc276b8672858504f6ae8098c43328a1e60589d7efc0e5fd2ec70a229904a1c493262d498c09", - "9e82a5f203e17d0515af7486599c1608d82a41c8e8cfe4457cb30c0eb62273d89970a2316223ccfdb64a49214762e80e82938531a2e0dc462f14ff52205e9107", - "c24b1da5ece026338fd3175648e443b97dce52659efe47881583cd35574670b21abdb345ebd0adf095620d8d7b805028fdcb480c24170d34e023e3a8df29fb04" + "4d86c9af808dc2e0583f47282e6f5df3e09dc264d5231ec360b4519e15ddaeec60b25a9bbcb22e8d192f4d36a0da3f9243711e30535b00ee55c53cb1395f230a", + "63208c668c66f3ba6927140ba37533593b25e03459447805d4b2a8b75adeef45794c3d7249afe506ed77ccee276160bb4052a4009302bd34871a440f070b4509", + "d8da982888eae8c038e4894a8c06fc57d8e5f06ad2e972b9cf4bde49ad60804558a0d1938192596c702d8e4f7f12ec19201d7c33d0cd77774a0d879a33880d02" ] } } @@ -406,7 +424,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\n" + "code": "right(\"file1\", \"read\");\n", + "version": 3 }, { "symbols": [ @@ -414,7 +433,8 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n" + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 }, { "symbols": [ @@ -422,41 +442,48 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file2\", \"read\");\n" + "code": "right(\"file2\", \"read\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "operation(\"read\")", - [ - null - ] - ], - [ - "resource(\"file2\")", - [ + { + "origin": [ null - ] - ], - [ - "right(\"file1\", \"read\")", - [ + ], + "facts": [ + "operation(\"read\")", + "resource(\"file2\")" + ] + }, + { + "origin": [ 0 + ], + "facts": [ + "right(\"file1\", \"read\")" ] - ], - [ - "right(\"file2\", \"read\")", - [ + }, + { + "origin": [ 2 + ], + "facts": [ + "right(\"file2\", \"read\")" ] - ] + } ], "rules": [], "checks": [ - "check if resource($0), operation(\"read\"), right($0, \"read\")" + { + "origin": 1, + "checks": [ + "check if resource($0), operation(\"read\"), right($0, \"read\")" + ] + } ], "policies": [ "allow if true" @@ -484,9 +511,9 @@ }, "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n", "revocation_ids": [ - "ba4d8f66dd4e3fef1f35d75be6df25fc41fbe237f645ea4434678add9dc356be23462eb1ada51bbb446995539f43b5d04581190ce2de66ea6194563efe88d603", - "3a69659a56d933ea7bf2dc4ccab997ed0bec6ce26b178ec24a9ec0d2fc006bcf31eae762f17cb5862457459b3d5ae9c17845dcf45f8cf0acd774e06f6b7d620d", - "c0f06ebdf58b5e17b150e7306a9361667a6a6d9945c1d478b4e8d9fac1869bd7726ef57e5cb9de95fe48718984e7dce617d5394caf25822cd646310affb2a202" + "a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00", + "77df45442be86a416aa02fd9d98d6d4703c634a9e3b1d293b41f5dc97849afbe7faeec8c22a210574888acc008fb64fe691ec9e8d2655586f970d9a6b6577000", + "b31398aefe97d3db41ebc445760f216fb3aa7bf7439adcfc3a07489bfcc163970af3f4e20f5460aa24cf841101a5ab114d21acc0ee8d442bae7793b121284900" ] } } @@ -499,45 +526,43 @@ "symbols": [], "public_keys": [], "external_key": null, - "code": "" + "code": "", + "version": 3 }, { "symbols": [ - "file1", - "expiration" + "file1" ], "public_keys": [], "external_key": null, - "code": "check if resource(\"file1\");\ncheck if time($time), $time <= 2018-12-20T00:00:00Z;\n" + "code": "check if resource(\"file1\");\ncheck if time($time), $time <= 2018-12-20T00:00:00Z;\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "operation(\"read\")", - [ - null - ] - ], - [ - "resource(\"file1\")", - [ + { + "origin": [ null + ], + "facts": [ + "operation(\"read\")", + "resource(\"file1\")", + "time(2020-12-21T09:23:12Z)" ] - ], - [ - "time(2020-12-21T09:23:12Z)", - [ - null - ] - ] + } ], "rules": [], "checks": [ - "check if resource(\"file1\")", - "check if time($time), $time <= 2018-12-20T00:00:00Z" + { + "origin": 1, + "checks": [ + "check if resource(\"file1\")", + "check if time($time), $time <= 2018-12-20T00:00:00Z" + ] + } ], "policies": [ "allow if true" @@ -565,8 +590,8 @@ }, "authorizer_code": "resource(\"file1\");\noperation(\"read\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n", "revocation_ids": [ - "ceb1a909c91d558a962c23d9d1c60aa06279f9dff1cc546ca6b2b6bf17db6fe4a03a04e9c1ed9131b7c6f3e609d5f17abab289909ae46f5e66f8876a5946a20c", - "73e270352f08a98007b383ac85192f878a098c7ae55bbd1b7da67a44d9e94a5192aa02277707ec6747ec973aa0d7e270cd73bb0b46df2d8e434e4b9a06571208" + "c248907bb6e5f433bbb5edf6367b399ebefca0d321d0b2ea9fc67f66dc1064ce926adb0c05d90c3e8a2833328b3578f79c4e1bca43583d9bcfb2ba6c37303d00", + "a4edf7aaea8658bb9ae19b3ffe2adcc77cc9f16c249aeb0a85a584b5362f89f27f7c67ac0af16d7170673d6d1fb1563d1934b25ec5a461f6c01fa49805cd5e07" ] } } @@ -581,7 +606,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\n" + "code": "right(\"file1\", \"read\");\n", + "version": 3 }, { "symbols": [ @@ -589,41 +615,48 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file2\", \"read\");\n" + "code": "right(\"file2\", \"read\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "operation(\"read\")", - [ - null - ] - ], - [ - "resource(\"file2\")", - [ + { + "origin": [ null - ] - ], - [ - "right(\"file1\", \"read\")", - [ + ], + "facts": [ + "operation(\"read\")", + "resource(\"file2\")" + ] + }, + { + "origin": [ 0 + ], + "facts": [ + "right(\"file1\", \"read\")" ] - ], - [ - "right(\"file2\", \"read\")", - [ + }, + { + "origin": [ 1 + ], + "facts": [ + "right(\"file2\", \"read\")" ] - ] + } ], "rules": [], "checks": [ - "check if right($0, $1), resource($0), operation($1)" + { + "origin": 18446744073709551615, + "checks": [ + "check if right($0, $1), resource($0), operation($1)" + ] + } ], "policies": [ "allow if true" @@ -650,8 +683,8 @@ }, "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\ncheck if right($0, $1), resource($0), operation($1);\n\nallow if true;\n", "revocation_ids": [ - "ba4d8f66dd4e3fef1f35d75be6df25fc41fbe237f645ea4434678add9dc356be23462eb1ada51bbb446995539f43b5d04581190ce2de66ea6194563efe88d603", - "d1d56ea3c9469186fe32f56a2c488b31b2dead6701ce833d521d2b1f223355edb058839c68ea6b50af02e2ffa4b92d80116b25f1cb0623b6685cb3415677970a" + "a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00", + "966eceb2aa937c41b25368808bab6e0698c02a4038de669d007c9c3d43602638a640083558d1576ac80cf3eb2ac6a7585527e0f6c1a65402f0935cf7f4df8005" ] } } @@ -666,35 +699,40 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\n" + "code": "right(\"file1\", \"read\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "operation(\"read\")", - [ - null - ] - ], - [ - "resource(\"file2\")", - [ + { + "origin": [ null - ] - ], - [ - "right(\"file1\", \"read\")", - [ + ], + "facts": [ + "operation(\"read\")", + "resource(\"file2\")" + ] + }, + { + "origin": [ 0 + ], + "facts": [ + "right(\"file1\", \"read\")" ] - ] + } ], "rules": [], "checks": [ - "check if right($0, $1), resource($0), operation($1)" + { + "origin": 18446744073709551615, + "checks": [ + "check if right($0, $1), resource($0), operation($1)" + ] + } ], "policies": [ "allow if true" @@ -721,7 +759,7 @@ }, "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\ncheck if right($0, $1), resource($0), operation($1);\n\nallow if true;\n", "revocation_ids": [ - "ba4d8f66dd4e3fef1f35d75be6df25fc41fbe237f645ea4434678add9dc356be23462eb1ada51bbb446995539f43b5d04581190ce2de66ea6194563efe88d603" + "a80c985ddef895518c216f64c65dcd50a5d97d012a94453d79159aed2981654b1fe9748c686c5667604026a94fb8db8a1d02de747df61e99fa9a63ff2878ad00" ] } } @@ -736,29 +774,32 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource(\"file1\");\n" + "code": "check if resource(\"file1\");\n", + "version": 3 } ], "validations": { "file1": { "world": { "facts": [ - [ - "operation(\"read\")", - [ - null - ] - ], - [ - "resource(\"file1\")", - [ + { + "origin": [ null + ], + "facts": [ + "operation(\"read\")", + "resource(\"file1\")" ] - ] + } ], "rules": [], "checks": [ - "check if resource(\"file1\")" + { + "origin": 0, + "checks": [ + "check if resource(\"file1\")" + ] + } ], "policies": [ "allow if true" @@ -769,28 +810,30 @@ }, "authorizer_code": "resource(\"file1\");\noperation(\"read\");\n\nallow if true;\n", "revocation_ids": [ - "bc15caa9476568fef796c13385d0cf455df66a0b1aa2be7980549f69aa5a4a7864555d94ddd64c652c7c24c191298dd5c0ca1aadb638ffd91971d15edee0aa07" + "6a8f90dad67ae2ac188460463914ae7326fda431c80785755f4edcc15f1a53911f7366e606ad80cbbeba94672e42713e88632a932128f1d796ce9ba7d7a0b80a" ] }, "file2": { "world": { "facts": [ - [ - "operation(\"read\")", - [ - null - ] - ], - [ - "resource(\"file2\")", - [ + { + "origin": [ null + ], + "facts": [ + "operation(\"read\")", + "resource(\"file2\")" ] - ] + } ], "rules": [], "checks": [ - "check if resource(\"file1\")" + { + "origin": 0, + "checks": [ + "check if resource(\"file1\")" + ] + } ], "policies": [ "allow if true" @@ -818,7 +861,7 @@ }, "authorizer_code": "resource(\"file2\");\noperation(\"read\");\n\nallow if true;\n", "revocation_ids": [ - "bc15caa9476568fef796c13385d0cf455df66a0b1aa2be7980549f69aa5a4a7864555d94ddd64c652c7c24c191298dd5c0ca1aadb638ffd91971d15edee0aa07" + "6a8f90dad67ae2ac188460463914ae7326fda431c80785755f4edcc15f1a53911f7366e606ad80cbbeba94672e42713e88632a932128f1d796ce9ba7d7a0b80a" ] } } @@ -834,7 +877,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\n" + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\n", + "version": 3 }, { "symbols": [ @@ -844,57 +888,58 @@ ], "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" + "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", + "version": 3 } ], "validations": { "file1": { "world": { "facts": [ - [ - "resource(\"file1\")", - [ - null - ] - ], - [ - "right(\"file1\", \"read\")", - [ - 0 - ] - ], - [ - "right(\"file2\", \"read\")", - [ - 0 - ] - ], - [ - "time(2020-12-21T09:23:12Z)", - [ + { + "origin": [ null - ] - ], - [ - "valid_date(\"file1\")", - [ + ], + "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": [ - [ - "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z", - 1 - ], - [ - "valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1)", - 1 - ] + { + "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": [ - "check if valid_date($0), resource($0)" + { + "origin": 1, + "checks": [ + "check if valid_date($0), resource($0)" + ] + } ], "policies": [ "allow if true" @@ -905,50 +950,48 @@ }, "authorizer_code": "resource(\"file1\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n", "revocation_ids": [ - "58a9aead6684468383ba121d1d1ba6a2dd087f41240ecb3b8229587b7717630d5db86e230c4aa3a6da802f04483da06ae4cb71c7c35f30207550be4450787601", - "745941a089e3e4efc479ac8d934fc0f95d9add8dca119c68e2ef34dfb285385396ad9b2d2cf6633894c234b1b9c854978be6788ca05262e3d2362e82f984b605" + "c46d071ff3f33434223c8305fdad529f62bf78bb5d9cbfc2a345d4bca6bf314014840e18ba353f86fdb9073d58b12b8c872ac1f8e593c2e9064b90f6c2ede006", + "a0c4c163a0b3ca406df4ece3d1371356190df04208eccef72f77e875ed0531b5d37e243d6f388b1967776a5dfd16ef228f19c5bdd6d2820f145c5ed3c3dcdc00" ] }, "file2": { "world": { "facts": [ - [ - "resource(\"file2\")", - [ + { + "origin": [ null - ] - ], - [ - "right(\"file1\", \"read\")", - [ - 0 - ] - ], - [ - "right(\"file2\", \"read\")", - [ + ], + "facts": [ + "resource(\"file2\")", + "time(2020-12-21T09:23:12Z)" + ] + }, + { + "origin": [ 0 + ], + "facts": [ + "right(\"file1\", \"read\")", + "right(\"file2\", \"read\")" ] - ], - [ - "time(2020-12-21T09:23:12Z)", - [ - null - ] - ] + } ], "rules": [ - [ - "valid_date(\"file1\") <- time($0), resource(\"file1\"), $0 <= 2030-12-31T12:59:59Z", - 1 - ], - [ - "valid_date($1) <- time($0), resource($1), $0 <= 1999-12-31T12:59:59Z, ![\"file1\"].contains($1)", - 1 - ] + { + "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": [ - "check if valid_date($0), resource($0)" + { + "origin": 1, + "checks": [ + "check if valid_date($0), resource($0)" + ] + } ], "policies": [ "allow if true" @@ -976,8 +1019,8 @@ }, "authorizer_code": "resource(\"file2\");\ntime(2020-12-21T09:23:12Z);\n\nallow if true;\n", "revocation_ids": [ - "58a9aead6684468383ba121d1d1ba6a2dd087f41240ecb3b8229587b7717630d5db86e230c4aa3a6da802f04483da06ae4cb71c7c35f30207550be4450787601", - "745941a089e3e4efc479ac8d934fc0f95d9add8dca119c68e2ef34dfb285385396ad9b2d2cf6633894c234b1b9c854978be6788ca05262e3d2362e82f984b605" + "c46d071ff3f33434223c8305fdad529f62bf78bb5d9cbfc2a345d4bca6bf314014840e18ba353f86fdb9073d58b12b8c872ac1f8e593c2e9064b90f6c2ede006", + "a0c4c163a0b3ca406df4ece3d1371356190df04208eccef72f77e875ed0531b5d37e243d6f388b1967776a5dfd16ef228f19c5bdd6d2820f145c5ed3c3dcdc00" ] } } @@ -993,23 +1036,31 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), $0.matches(\"file[0-9]+.txt\");\n" + "code": "check if resource($0), $0.matches(\"file[0-9]+.txt\");\n", + "version": 3 } ], "validations": { "file1": { "world": { "facts": [ - [ - "resource(\"file1\")", - [ + { + "origin": [ null + ], + "facts": [ + "resource(\"file1\")" ] - ] + } ], "rules": [], "checks": [ - "check if resource($0), $0.matches(\"file[0-9]+.txt\")" + { + "origin": 0, + "checks": [ + "check if resource($0), $0.matches(\"file[0-9]+.txt\")" + ] + } ], "policies": [ "allow if true" @@ -1037,22 +1088,29 @@ }, "authorizer_code": "resource(\"file1\");\n\nallow if true;\n", "revocation_ids": [ - "7d2e7c6bc4878efcdb7f704948e668fcf5338cb1e4eeb5f0434944ace98597652f062d67e2ebdb47fe2c7b17d40f0d8a2386cb2d753fb430168be5e0b5fd410b" + "da42718ad2631c12d3a44b7710dcc76c6c7809c6bc3a2d7eb0378c4154eae10e0884a8d54a2cd25ca3dfe01091d816ebbb9d246227baf7a359a787cb2344ad07" ] }, "file123": { "world": { "facts": [ - [ - "resource(\"file123.txt\")", - [ + { + "origin": [ null + ], + "facts": [ + "resource(\"file123.txt\")" ] - ] + } ], "rules": [], "checks": [ - "check if resource($0), $0.matches(\"file[0-9]+.txt\")" + { + "origin": 0, + "checks": [ + "check if resource($0), $0.matches(\"file[0-9]+.txt\")" + ] + } ], "policies": [ "allow if true" @@ -1063,7 +1121,7 @@ }, "authorizer_code": "resource(\"file123.txt\");\n\nallow if true;\n", "revocation_ids": [ - "7d2e7c6bc4878efcdb7f704948e668fcf5338cb1e4eeb5f0434944ace98597652f062d67e2ebdb47fe2c7b17d40f0d8a2386cb2d753fb430168be5e0b5fd410b" + "da42718ad2631c12d3a44b7710dcc76c6c7809c6bc3a2d7eb0378c4154eae10e0884a8d54a2cd25ca3dfe01091d816ebbb9d246227baf7a359a787cb2344ad07" ] } } @@ -1079,23 +1137,31 @@ ], "public_keys": [], "external_key": null, - "code": "must_be_present(\"hello\");\n" + "code": "must_be_present(\"hello\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "must_be_present(\"hello\")", - [ + { + "origin": [ 0 + ], + "facts": [ + "must_be_present(\"hello\")" ] - ] + } ], "rules": [], "checks": [ - "check if must_be_present($0) or must_be_present($0)" + { + "origin": 18446744073709551615, + "checks": [ + "check if must_be_present($0) or must_be_present($0)" + ] + } ], "policies": [ "allow if true" @@ -1106,7 +1172,7 @@ }, "authorizer_code": "check if must_be_present($0) or must_be_present($0);\n\nallow if true;\n", "revocation_ids": [ - "e2c762315434ccc9194e012e47e75afb3329a46488a468d75d776b5a502ee5930d04750ae7b1836617fe07051bd92d4ce8336d662da4ca9ce9e9d4f4af5be70d" + "b0d466d31e015fa85a075fa875f7e1c9017edd503fee9f62a5f033e1fcfa811074b6e39dfe5af2f452043db97a3f98650592a370f5685b62c5d6abf9dd10b603" ] } } @@ -1121,7 +1187,8 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource(\"hello\");\n" + "code": "check if resource(\"hello\");\n", + "version": 3 }, { "symbols": [ @@ -1129,23 +1196,31 @@ ], "public_keys": [], "external_key": null, - "code": "query(\"test\");\n" + "code": "query(\"test\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "query(\"test\")", - [ + { + "origin": [ 1 + ], + "facts": [ + "query(\"test\")" ] - ] + } ], "rules": [], "checks": [ - "check if resource(\"hello\")" + { + "origin": 0, + "checks": [ + "check if resource(\"hello\")" + ] + } ], "policies": [ "allow if true" @@ -1173,8 +1248,8 @@ }, "authorizer_code": "allow if true;\n", "revocation_ids": [ - "812958ef3b43273b2c8e88bb13d0f91f0a8f5bf95544f79dafdaff07d89bd551baca72f83589b9e89120b0dc41c0f4b10678f03dd1b3ac0422e16074ff396b08", - "51c0e278bed1085afe45519aa60d5b4b9e13f1819dadb38fb5854ed3a599bfe18485d8f396219540bd17bfb9f46ab3c407a4ac51ebf88734b4f2fb56b24a6e01" + "ce6f804f4390e693a8853d9a4a10bd4f3c94b86b7c6d671993a6e19346bc4d20bbb52cc945e5d0d02e4e75fa5da2caa99764050190353564a0a0b4b276809402", + "916d566cc724e0773046fc5266e9d0d804311435b8d6955b332f823ab296be9a78dfea190447732ac9f6217234cf5726becf88f65169c6de56a766af55451b0f" ] } } @@ -1195,12 +1270,14 @@ "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 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" + "code": "check if true;\ncheck if !false;\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;\ncheck if {,}.length() === 0;\n", + "version": 3 } ], "validations": { @@ -1209,44 +1286,50 @@ "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 \"hello world\".starts_with(\"hello\") && \"hello world\".ends_with(\"world\")", - "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 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" + { + "origin": 0, + "checks": [ + "check if !false", + "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 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 false === false", + "check if hex:12ab === hex:12ab", + "check if true", + "check if true === true", + "check if {\"abc\", \"def\"}.contains(\"abc\")", + "check if {,}.length() === 0", + "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)" + ] + } ], "policies": [ "allow if true" @@ -1257,7 +1340,7 @@ }, "authorizer_code": "allow if true;\n", "revocation_ids": [ - "a0fdd27c0d21292a4d944a86a9e97cfee7513969a209729ebcff2dec50b8725816dad3b9d7fc004d3f6dc705399c303c1a76a8b955a5f23d2045132b68b4d50b" + "fa358e4e3bea896415b1859e6cd347e64e1918fb86e31ae3fe208628321576a47f7a269760357e291c827ec9cbe322074f6860a546207a64e133c83a214bb505" ] } } @@ -1270,7 +1353,8 @@ "symbols": [], "public_keys": [], "external_key": null, - "code": "check if operation(\"read\");\n" + "code": "check if operation(\"read\");\n", + "version": 3 }, { "symbols": [ @@ -1280,7 +1364,8 @@ ], "public_keys": [], "external_key": null, - "code": "operation($unbound, \"read\") <- operation($any1, $any2);\n" + "code": "operation($unbound, \"read\") <- operation($any1, $any2);\n", + "version": 3 } ], "validations": { @@ -1298,8 +1383,8 @@ }, "authorizer_code": "", "revocation_ids": [ - "6d79797e655457166810826d7c398bc75ac4896d8de80650298796faf0aaf67f2abb80c46efdd915a210c9401bc41c75f3a7c19bebe4c02be9c991fae62b8808", - "b25cea85ce06b97df471896c7c709b3962dd6e97074a66a2da2fe6721c250c418b4c55455f7209362752343873bb4105d18ef6a880ecb9c0b41d98f0b7d31505" + "a44210c6a01e55eadefc7d8540c2e6eff80ab6eeedde4751de734f9d780435780680d3f42d826b7e0f0dcf4a5ba303fd4c116984bb30978813d46ed867924307", + "b0a33e3f4cd0994c0766c196c4d11c15e5a0f9bfba79a3a2b35ddd04ddb890282a7c63336ada5c680b9f9c940c1fa7127d2699754cbc77c21e1a2d85c5ef700c" ] } } @@ -1312,7 +1397,8 @@ "symbols": [], "public_keys": [], "external_key": null, - "code": "check if operation(\"read\");\n" + "code": "check if operation(\"read\");\n", + "version": 3 }, { "symbols": [ @@ -1320,35 +1406,47 @@ ], "public_keys": [], "external_key": null, - "code": "operation(\"read\") <- operation($any);\n" + "code": "operation(\"read\") <- operation($any);\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "operation(\"read\")", - [ + { + "origin": [ + null + ], + "facts": [ + "operation(\"write\")" + ] + }, + { + "origin": [ null, 1 + ], + "facts": [ + "operation(\"read\")" ] - ], - [ - "operation(\"write\")", - [ - null - ] - ] + } ], "rules": [ - [ - "operation(\"read\") <- operation($any)", - 1 - ] + { + "origin": 1, + "rules": [ + "operation(\"read\") <- operation($any)" + ] + } ], "checks": [ - "check if operation(\"read\")" + { + "origin": 0, + "checks": [ + "check if operation(\"read\")" + ] + } ], "policies": [ "allow if true" @@ -1376,8 +1474,8 @@ }, "authorizer_code": "operation(\"write\");\n\nallow if true;\n", "revocation_ids": [ - "6d79797e655457166810826d7c398bc75ac4896d8de80650298796faf0aaf67f2abb80c46efdd915a210c9401bc41c75f3a7c19bebe4c02be9c991fae62b8808", - "f7d3f3eadd83cc30aa3c0a9b8288d44b9107b5a099e52da6447fdb7aca5d00cd58add7b7b12b3fb73bd9b664f33ed207d91efcda2d05523cb9b8db0e9bca0502" + "a44210c6a01e55eadefc7d8540c2e6eff80ab6eeedde4751de734f9d780435780680d3f42d826b7e0f0dcf4a5ba303fd4c116984bb30978813d46ed867924307", + "d3f8822a9b9bc0ee3933283c493ca9e711be5dd8339b5fe2eba1de3805aad4e84d3e2fb4affb4a743f1289915c167582b9425343635e45b70573ea1ee7a1ea03" ] } } @@ -1393,7 +1491,8 @@ ], "public_keys": [], "external_key": null, - "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n" + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n", + "version": 3 }, { "symbols": [ @@ -1401,47 +1500,42 @@ ], "public_keys": [], "external_key": null, - "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n" + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "operation(\"read\")", - [ - null - ] - ], - [ - "resource(\"file1\")", - [ + { + "origin": [ null - ] - ], - [ - "right(\"file1\", \"read\")", - [ - 0 - ] - ], - [ - "right(\"file1\", \"write\")", - [ - 0 - ] - ], - [ - "right(\"file2\", \"read\")", - [ + ], + "facts": [ + "operation(\"read\")", + "resource(\"file1\")" + ] + }, + { + "origin": [ 0 + ], + "facts": [ + "right(\"file1\", \"read\")", + "right(\"file1\", \"write\")", + "right(\"file2\", \"read\")" ] - ] + } ], "rules": [], "checks": [ - "check if resource($0), operation(\"read\"), right($0, \"read\")" + { + "origin": 1, + "checks": [ + "check if resource($0), operation(\"read\"), right($0, \"read\")" + ] + } ], "policies": [ "allow if true" @@ -1452,8 +1546,8 @@ }, "authorizer_code": "resource(\"file1\");\noperation(\"read\");\n\nallow if true;\n", "revocation_ids": [ - "36d2d7cf28796c69a0ed6dfa0fde5b3ffb2f637f0ba19aa1da858353e88678ad945ebaaa566a050b8abe8adb5b873855900b157e1e5f1cc11047a14385e5a203", - "b694af382e2115df7d02bb88a75b9c0cdcb9e51c23dea082c306b1b7a26dfe9a3ca7ba7ca3a8089e7b88bb3718ff0294c2a0dc6b5b810f64462e89393ff35e05" + "7595a112a1eb5b81a6e398852e6118b7f5b8cbbff452778e655100e5fb4faa8d3a2af52fe2c4f9524879605675fae26adbc4783e0cafc43522fa82385f396c03", + "45f4c14f9d9e8fa044d68be7a2ec8cddb835f575c7b913ec59bd636c70acae9a90db9064ba0b3084290ed0c422bbb7170092a884f5e0202b31e9235bbcc1650d" ] } } @@ -1469,23 +1563,31 @@ ], "public_keys": [], "external_key": null, - "code": "ns::fact_123(\"hello é\t😁\");\n" + "code": "ns::fact_123(\"hello é\t😁\");\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "ns::fact_123(\"hello é\t😁\")", - [ + { + "origin": [ 0 + ], + "facts": [ + "ns::fact_123(\"hello é\t😁\")" ] - ] + } ], "rules": [], "checks": [ - "check if ns::fact_123(\"hello é\t😁\")" + { + "origin": 18446744073709551615, + "checks": [ + "check if ns::fact_123(\"hello é\t😁\")" + ] + } ], "policies": [ "allow if true" @@ -1496,7 +1598,7 @@ }, "authorizer_code": "check if ns::fact_123(\"hello é\t😁\");\n\nallow if true;\n", "revocation_ids": [ - "6a945aca807c25971cc4b711cd6364141fdaf4cee013022416f22986240238cc029b5ae41eb5c5b8a461b0d6063329132b5bac91ca8b51e82829a2b6a273150d" + "d4b2f417b6e906434fdf5058afcabfcb98d3628f814f1c9dd7e64250d9beec4465aff51bd0cb2e85d0e67dc9f613c2a42af6158c678bc6f8b4684cd3a2d0d302" ] } } @@ -1509,185 +1611,58 @@ "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" + "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", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "admin(13)", - [ - 0 - ] - ], - [ - "client(18)", - [ - 0 - ] - ], - [ - "client_ip(19)", - [ - 0 - ] - ], - [ - "cluster(23)", - [ - 0 - ] - ], - [ - "domain(20)", - [ - 0 - ] - ], - [ - "email(14)", - [ - 0 - ] - ], - [ - "group(15)", - [ - 0 - ] - ], - [ - "hostname(25)", - [ - 0 - ] - ], - [ - "ip_address(17)", - [ - 0 - ] - ], - [ - "member(16)", - [ - 0 - ] - ], - [ - "namespace(9)", - [ - 0 - ] - ], - [ - "node(24)", - [ - 0 - ] - ], - [ - "nonce(26)", - [ - 0 - ] - ], - [ - "operation(3)", - [ - 0 - ] - ], - [ - "owner(7)", - [ - 0 - ] - ], - [ - "path(21)", - [ - 0 - ] - ], - [ - "query(27)", - [ - 0 - ] - ], - [ - "read(0)", - [ - 0 - ] - ], - [ - "resource(2)", - [ - 0 - ] - ], - [ - "right(4)", - [ - 0 - ] - ], - [ - "role(6)", - [ - 0 - ] - ], - [ - "service(12)", - [ - 0 - ] - ], - [ - "team(11)", - [ - 0 - ] - ], - [ - "tenant(8)", - [ - 0 - ] - ], - [ - "time(5)", - [ - 0 - ] - ], - [ - "user(10)", - [ - 0 - ] - ], - [ - "version(22)", - [ - 0 - ] - ], - [ - "write(1)", - [ + { + "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": [ - "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)" + { + "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" @@ -1698,7 +1673,7 @@ }, "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": [ - "23183284bdad88fbf5b4cbaed2218cf0a38d7e360f3ac401d6337eecf36e8da1ce15eda6d11fe94c20c344f687327d9338a0e863f98c9a14576739533d2fb804" + "75ce48d496fd28f99905901783a1ba46d7ff8d69f9d364d1546fd73006026eae51849ad1190a4ae521a0a1269f9c6951e226afba8fcd24fa50f679162439ae09" ] } } @@ -1713,7 +1688,8 @@ ], "public_keys": [], "external_key": null, - "code": "authority_fact(1);\n" + "code": "authority_fact(1);\n", + "version": 3 }, { "symbols": [ @@ -1721,7 +1697,8 @@ ], "public_keys": [], "external_key": null, - "code": "block1_fact(1);\n" + "code": "block1_fact(1);\n", + "version": 3 }, { "symbols": [ @@ -1729,30 +1706,40 @@ ], "public_keys": [], "external_key": null, - "code": "check if authority_fact($var);\ncheck if block1_fact($var);\n" + "code": "check if authority_fact($var);\ncheck if block1_fact($var);\n", + "version": 3 } ], "validations": { "": { "world": { "facts": [ - [ - "authority_fact(1)", - [ + { + "origin": [ 0 + ], + "facts": [ + "authority_fact(1)" ] - ], - [ - "block1_fact(1)", - [ + }, + { + "origin": [ 1 + ], + "facts": [ + "block1_fact(1)" ] - ] + } ], "rules": [], "checks": [ - "check if authority_fact($var)", - "check if block1_fact($var)" + { + "origin": 2, + "checks": [ + "check if authority_fact($var)", + "check if block1_fact($var)" + ] + } ], "policies": [ "allow if true" @@ -1780,9 +1767,9 @@ }, "authorizer_code": "allow if true;\n", "revocation_ids": [ - "8c94b6f3a2cbe086a7df1135f04c7b88b4a8d6b4f595cd963e8f2a36b9c1edb551f1b0360f7995eec8ea8c846847fba53932f5e70aaee7783a852c83c08dd80b", - "ce286369809e4f4a6e2d6b95ba6c19af28c3694ffd408d09ee292c0233a3d73e3257151d6099177ae61aa71cfb91f85b3ccac80952bf5d34c9e807c5e4cf2c04", - "9bc1209ffa1e11d5fd3fe3811e55893e6c5a94d56e5835e83f7a84142db50642899b92705a32ab64a375e36e665564607cbf50d6366682b5381849f8e8b3340a" + "f9b49866caef5ece7be14ec5a9b36d98ca81d06b306eb0b4c57cd7436af176f40ee972f40903f87ec4460ab8b1adfcbfa9b19b20a6955a1e8dae7d88b2076005", + "889054b9119e4440e54da1b63266a98d0f6646cde195fef206efd8b133cfb2ee7be49b32a9a5925ece452e64f9e6f6d80dab422e916c599675dd68cdea053802", + "0a85ffbf27e08aa23665ba0d96a985b274d747556c9f016fd7f590c641ed0e4133291521aa442b320ee9ce80f5ad701b914a0c87b3dfa0cc92629dce94201806" ] } } @@ -1797,36 +1784,52 @@ "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189" ], "external_key": null, - "code": "right(\"read\");\ncheck if group(\"admin\") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n" + "code": "right(\"read\");\ncheck if group(\"admin\") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n", + "version": 4 }, { "symbols": [], "public_keys": [], "external_key": "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", - "code": "group(\"admin\");\ncheck if right(\"read\");\n" + "code": "group(\"admin\");\ncheck if right(\"read\");\n", + "version": 5 } ], "validations": { "": { "world": { "facts": [ - [ - "group(\"admin\")", - [ - 1 - ] - ], - [ - "right(\"read\")", - [ + { + "origin": [ 0 + ], + "facts": [ + "right(\"read\")" + ] + }, + { + "origin": [ + 1 + ], + "facts": [ + "group(\"admin\")" ] - ] + } ], "rules": [], "checks": [ - "check if group(\"admin\") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", - "check if right(\"read\")" + { + "origin": 0, + "checks": [ + "check if group(\"admin\") trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189" + ] + }, + { + "origin": 1, + "checks": [ + "check if right(\"read\")" + ] + } ], "policies": [ "allow if true" @@ -1837,8 +1840,8 @@ }, "authorizer_code": "allow if true;\n", "revocation_ids": [ - "f5e36f36c18a9a7d3660366a9dccf1eeefbb2a639571e5aba63714cf02e412d222f7aadec14aef59cb5cf104e0d3bdba439c4147249e2d703498b2f0610e1008", - "79217fcc94823ccbfc1cdbd6aaf770890659bb94d48ca14dddff70e9d0d386a4755e452e732a071c8e9884ca280ead059c473b3bd4ea5f82e99ee3c484518004" + "470e4bf7aa2a01ab39c98150bd06aa15b4aa5d86509044a8809a8634cd8cf2b42269a51a774b65d10bac9369d013070b00187925196a8e680108473f11cf8f03", + "901b2af4dacf33458d2d91ac484b60bad948e8d10faa9695b096054d5b46e832a977b60b17464cacf545ad0801f549ea454675f0ac88c413406925e2af83ff08" ] } } @@ -1857,35 +1860,40 @@ ], "public_keys": [], "external_key": null, - "code": "allowed_operations([\"A\", \"B\"]);\ncheck all operation($op), allowed_operations($allowed), $allowed.contains($op);\n" + "code": "allowed_operations({\"A\", \"B\"});\ncheck all operation($op), allowed_operations($allowed), $allowed.contains($op);\n", + "version": 4 } ], "validations": { "A, B": { "world": { "facts": [ - [ - "allowed_operations([\"A\", \"B\"])", - [ - 0 - ] - ], - [ - "operation(\"A\")", - [ - null - ] - ], - [ - "operation(\"B\")", - [ + { + "origin": [ null + ], + "facts": [ + "operation(\"A\")", + "operation(\"B\")" + ] + }, + { + "origin": [ + 0 + ], + "facts": [ + "allowed_operations({\"A\", \"B\"})" ] - ] + } ], "rules": [], "checks": [ - "check all operation($op), allowed_operations($allowed), $allowed.contains($op)" + { + "origin": 0, + "checks": [ + "check all operation($op), allowed_operations($allowed), $allowed.contains($op)" + ] + } ], "policies": [ "allow if true" @@ -1896,34 +1904,38 @@ }, "authorizer_code": "operation(\"A\");\noperation(\"B\");\n\nallow if true;\n", "revocation_ids": [ - "96f15d9598d682d387d9f01b4df28f6f29e6e2a0d2cdd699266a685e983f64c8349054a77ca7e940d6775da79ed53d41373863e3a35b86181d132148a8d5980a" + "c456817012e1d523c6d145b6d6a3475d9f7dd4383c535454ff3f745ecf4234984ce09b9dec0551f3d783abe850f826ce43b12f1fd91999a4753a56ecf4c56d0d" ] }, "A, invalid": { "world": { "facts": [ - [ - "allowed_operations([\"A\", \"B\"])", - [ - 0 - ] - ], - [ - "operation(\"A\")", - [ - null - ] - ], - [ - "operation(\"invalid\")", - [ + { + "origin": [ null + ], + "facts": [ + "operation(\"A\")", + "operation(\"invalid\")" + ] + }, + { + "origin": [ + 0 + ], + "facts": [ + "allowed_operations({\"A\", \"B\"})" ] - ] + } ], "rules": [], "checks": [ - "check all operation($op), allowed_operations($allowed), $allowed.contains($op)" + { + "origin": 0, + "checks": [ + "check all operation($op), allowed_operations($allowed), $allowed.contains($op)" + ] + } ], "policies": [ "allow if true" @@ -1951,7 +1963,7 @@ }, "authorizer_code": "operation(\"A\");\noperation(\"invalid\");\n\nallow if true;\n", "revocation_ids": [ - "96f15d9598d682d387d9f01b4df28f6f29e6e2a0d2cdd699266a685e983f64c8349054a77ca7e940d6775da79ed53d41373863e3a35b86181d132148a8d5980a" + "c456817012e1d523c6d145b6d6a3475d9f7dd4383c535454ff3f745ecf4234984ce09b9dec0551f3d783abe850f826ce43b12f1fd91999a4753a56ecf4c56d0d" ] } } @@ -1966,98 +1978,159 @@ "ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189" ], "external_key": null, - "code": "query(0);\ncheck if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n" + "code": "query(0);\ncheck if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n", + "version": 4 }, { "symbols": [], "public_keys": [ - "ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463" + "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" + "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", + "version": 5 }, { "symbols": [], - "public_keys": [], + "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" + "code": "query(2);\ncheck if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\ncheck if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n", + "version": 5 }, { "symbols": [], - "public_keys": [], + "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" + "code": "query(3);\ncheck if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\ncheck if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\n", + "version": 5 }, { "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" + "code": "query(4);\ncheck if query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\ncheck if query(4) trusting ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136;\n", + "version": 4 } ], "validations": { "": { "world": { "facts": [ - [ - "query(0)", - [ + { + "origin": [ 0 + ], + "facts": [ + "query(0)" ] - ], - [ - "query(1)", - [ + }, + { + "origin": [ 1 + ], + "facts": [ + "query(1)" ] - ], - [ - "query(1, 2)", - [ + }, + { + "origin": [ 1, 2 + ], + "facts": [ + "query(1, 2)" ] - ], - [ - "query(2)", - [ + }, + { + "origin": [ 2 + ], + "facts": [ + "query(2)" ] - ], - [ - "query(3)", - [ + }, + { + "origin": [ 3 + ], + "facts": [ + "query(3)" ] - ], - [ - "query(4)", - [ + }, + { + "origin": [ 4 + ], + "facts": [ + "query(4)" ] - ] + } ], "rules": [ - [ - "query(1, 2) <- query(1), query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", - 1 - ] + { + "origin": 1, + "rules": [ + "query(1, 2) <- query(1), query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463" + ] + } ], "checks": [ - "check if query(1) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", - "check if query(1, 2) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189, ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", - "check if query(2) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", - "check if query(2), query(3) trusting ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463", - "check if query(4) trusting ed25519/f98da8c1cf907856431bfc3dc87531e0eaadba90f919edc232405b85877ef136", - "check if true trusting previous, ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189" + { + "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": [ - "allow if true", - "deny if query(0) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", + "deny if query(3)", "deny if query(1, 2)", - "deny if query(3)" + "deny if query(0) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189", + "allow if true" ] }, "result": { @@ -2065,11 +2138,11 @@ }, "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": [ - "0e823acf10d97afef5d327d08ecde17fad1808388dedf678770b60521170180f4ad3b4dc81494d92122658f3bbfe2567ad5493b2bf0fc6570f2be52566320d03", - "35bacaf3a817a26ffcb6a2b5658ef60665b63696c00061f5cef75fe3dac315595f0e24c20533916d90077b708e62396bf4b50dcd774092b43100f9271cd9830a", - "3198c7f606e1611e6a6df503b74a9ac5769dd11b3a1c6c4d5f0e3dbf92671d009e0ec648fadc49442e9c94455258c8502ed2d5031a57436f2521520a0b9ac009", - "16f8e0231f514816282621730510e41e0ba1a41d1944634f13fe4aaf28d0565e658fa624186fafc0bd996af39b638a31904b637e24ecc791f3d7210f9b83d90e", - "68db0a0319dd91ee6638fe5fe380f9037c63b37fd0674b9df01cae5e40fcfe37a04498cba34a92433c6f9d3c423be5a5fbee49136b734f9d98d1b7962c1e730b" + "3771cefe71beb21ead35a59c8116ee82627a5717c0295f35980662abccb159fe1b37848cb1818e548656bd4fd882d0094a2daab631c76b2b72e3a093914bfe04", + "7113d4dbb3b688b80e941f365a2c6342d480c77ed03937bccf85dc5cc3554c7517887b1b0c9021388a71e6ca9047aabaaad5ae5b511a2880902568444a98e50b", + "d0e3fc4bbd1b7320022800af909585aa906f677c4ca79c275a10b6779f669384c464ee84a1b04f13877a25761a874748362c065f4d15a8cab5c5e16c34074403", + "29b7e0a1f118a6185814a552660c516c43482044e280e7a8de85b8e7e54947e0ae82eb39d7b524d4b72cb9812a7a4b8871964f8f825b1c1ed85d344c05281d0d", + "c0a505d4d921a8b2d0b885917d42e2bca87b5302d13249a61af6f3802af44d691c40a624f901d677724740cb974a188aeb1c3992c1565ac0fbec3aa4f68dac0a" ] } } @@ -2082,7 +2155,8 @@ "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" + "code": "check if 10000000000 * 10000000000 !== 0;\ncheck if 9223372036854775807 + 1 !== 0;\ncheck if -9223372036854775808 - 1 !== 0;\n", + "version": 4 } ], "validations": { @@ -2091,9 +2165,14 @@ "facts": [], "rules": [], "checks": [ - "check if true || -9223372036854775808 - 1 != 0", - "check if true || 10000000000 * 10000000000 != 0", - "check if true || 9223372036854775807 + 1 != 0" + { + "origin": 0, + "checks": [ + "check if -9223372036854775808 - 1 !== 0", + "check if 10000000000 * 10000000000 !== 0", + "check if 9223372036854775807 + 1 !== 0" + ] + } ], "policies": [ "allow if true" @@ -2106,7 +2185,7 @@ }, "authorizer_code": "allow if true;\n", "revocation_ids": [ - "c554195c11cd462ca550f833833fad64213bdbef31d5e4b48ae6c2dc072d5218792bbf0da612f7ec9d20dc04c505d8c6ebdeee96ae95307546227efca713c70b" + "fb5e7ac2bb892f5cf2fb59677cfad1f96deabbc8e158e3fd1b5ee7c4b6949c999e2169187cbee53b943eebdadaaf68832747baa8cffa2ff9f78025a1f55f440c" ] } } @@ -2122,7 +2201,8 @@ ], "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" + "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", + "version": 4 } ], "validations": { @@ -2131,12 +2211,17 @@ "facts": [], "rules": [], "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" + { + "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 hex:12abcd !== hex:12ab", + "check if {1, 4} !== {1, 2}" + ] + } ], "policies": [ "allow if true" @@ -2147,7 +2232,1024 @@ }, "authorizer_code": "allow if true;\n", "revocation_ids": [ - "56ff3e571202e641dfb84955adb6700b61e42e1100412b3e0e957f1693875fbb8fdeaeb008092b2f42c5c7ded97cde638eeaf3ab73df678273f6ba970916ad00" + "117fa653744c859561555e6a6f5990e3a8e7817f91b87aa6991b6d64297158b4e884c92d10f49f74c96069df722aa676839b72751ca9d1fe83a7025b591de00b" + ] + } + } + }, + { + "title": "test reject if", + "filename": "test029_reject_if.bc", + "token": [ + { + "symbols": [ + "test" + ], + "public_keys": [], + "external_key": null, + "code": "reject if test($test), $test;\n", + "version": 6 + } + ], + "validations": { + "": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "test(false)" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "reject if test($test), $test" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Ok": 0 + }, + "authorizer_code": "test(false);\n\nallow if true;\n", + "revocation_ids": [ + "8d175329f7cf161f3cb5badc52f0e22e520956cdb565edbed963e9b047b20a314a7de1c9eba6b7bbf622636516ab3cc7f91572ae9461d3152825e0ece5127a0a" + ] + }, + "rejection": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "test(true)" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "reject if test($test), $test" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Err": { + "FailedLogic": { + "Unauthorized": { + "policy": { + "Allow": 0 + }, + "checks": [ + { + "Block": { + "block_id": 0, + "check_id": 0, + "rule": "reject if test($test), $test" + } + } + ] + } + } + } + }, + "authorizer_code": "test(true);\n\nallow if true;\n", + "revocation_ids": [ + "8d175329f7cf161f3cb5badc52f0e22e520956cdb565edbed963e9b047b20a314a7de1c9eba6b7bbf622636516ab3cc7f91572ae9461d3152825e0ece5127a0a" + ] + } + } + }, + { + "title": "test null", + "filename": "test030_null.bc", + "token": [ + { + "symbols": [ + "fact", + "value" + ], + "public_keys": [], + "external_key": null, + "code": "check if fact(null, $value), $value == null;\nreject if fact(null, $value), $value != null;\n", + "version": 6 + } + ], + "validations": { + "": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "fact(null, null)" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if fact(null, $value), $value == null", + "reject if fact(null, $value), $value != null" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Ok": 0 + }, + "authorizer_code": "fact(null, null);\n\nallow if true;\n", + "revocation_ids": [ + "fe50d65706a5945c76569d1ff2be8ece24276857631e96efa05959f73bb4ea8c772945738a01da77a1661aef2b8233b4f4e49ae220f2c81fd0b8da59c212750b" + ] + }, + "rejection1": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "fact(null, 1)" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if fact(null, $value), $value == null", + "reject if fact(null, $value), $value != null" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Err": { + "FailedLogic": { + "Unauthorized": { + "policy": { + "Allow": 0 + }, + "checks": [ + { + "Block": { + "block_id": 0, + "check_id": 0, + "rule": "check if fact(null, $value), $value == null" + } + }, + { + "Block": { + "block_id": 0, + "check_id": 1, + "rule": "reject if fact(null, $value), $value != null" + } + } + ] + } + } + } + }, + "authorizer_code": "fact(null, 1);\n\nallow if true;\n", + "revocation_ids": [ + "fe50d65706a5945c76569d1ff2be8ece24276857631e96efa05959f73bb4ea8c772945738a01da77a1661aef2b8233b4f4e49ae220f2c81fd0b8da59c212750b" + ] + }, + "rejection2": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "fact(null, true)" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if fact(null, $value), $value == null", + "reject if fact(null, $value), $value != null" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Err": { + "FailedLogic": { + "Unauthorized": { + "policy": { + "Allow": 0 + }, + "checks": [ + { + "Block": { + "block_id": 0, + "check_id": 0, + "rule": "check if fact(null, $value), $value == null" + } + }, + { + "Block": { + "block_id": 0, + "check_id": 1, + "rule": "reject if fact(null, $value), $value != null" + } + } + ] + } + } + } + }, + "authorizer_code": "fact(null, true);\n\nallow if true;\n", + "revocation_ids": [ + "fe50d65706a5945c76569d1ff2be8ece24276857631e96efa05959f73bb4ea8c772945738a01da77a1661aef2b8233b4f4e49ae220f2c81fd0b8da59c212750b" + ] + }, + "rejection3": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "fact(null, \"abcd\")" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if fact(null, $value), $value == null", + "reject if fact(null, $value), $value != null" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Err": { + "FailedLogic": { + "Unauthorized": { + "policy": { + "Allow": 0 + }, + "checks": [ + { + "Block": { + "block_id": 0, + "check_id": 0, + "rule": "check if fact(null, $value), $value == null" + } + }, + { + "Block": { + "block_id": 0, + "check_id": 1, + "rule": "reject if fact(null, $value), $value != null" + } + } + ] + } + } + } + }, + "authorizer_code": "fact(null, \"abcd\");\n\nallow if true;\n", + "revocation_ids": [ + "fe50d65706a5945c76569d1ff2be8ece24276857631e96efa05959f73bb4ea8c772945738a01da77a1661aef2b8233b4f4e49ae220f2c81fd0b8da59c212750b" + ] + } + } + }, + { + "title": "test heterogeneous equal", + "filename": "test031_heterogeneous_equal.bc", + "token": [ + { + "symbols": [ + "abcD12", + "abcD12x", + "fact", + "value", + "fact2" + ], + "public_keys": [], + "external_key": null, + "code": "check if true == true;\ncheck if false == false;\ncheck if false != true;\ncheck if 1 != true;\ncheck if 1 == 1;\ncheck if 1 != 3;\ncheck if 1 != true;\ncheck if \"abcD12\" == \"abcD12\";\ncheck if \"abcD12x\" != \"abcD12\";\ncheck if \"abcD12x\" != true;\ncheck if 2022-12-04T09:46:41Z == 2022-12-04T09:46:41Z;\ncheck if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z;\ncheck if 2022-12-04T09:46:41Z != true;\ncheck if hex:12abcd == hex:12abcd;\ncheck if hex:12abcd != hex:12ab;\ncheck if hex:12abcd != true;\ncheck if {1, 2} == {1, 2};\ncheck if {1, 4} != {1, 2};\ncheck if {1, 4} != true;\ncheck if fact(1, $value), 1 == $value;\ncheck if fact2(1, $value), 1 != $value;\n", + "version": 6 + } + ], + "validations": { + "": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "fact(1, 1)", + "fact2(1, 2)" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if \"abcD12\" == \"abcD12\"", + "check if \"abcD12x\" != \"abcD12\"", + "check if \"abcD12x\" != true", + "check if 1 != 3", + "check if 1 != true", + "check if 1 != true", + "check if 1 == 1", + "check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z", + "check if 2022-12-04T09:46:41Z != true", + "check if 2022-12-04T09:46:41Z == 2022-12-04T09:46:41Z", + "check if fact(1, $value), 1 == $value", + "check if fact2(1, $value), 1 != $value", + "check if false != true", + "check if false == false", + "check if hex:12abcd != hex:12ab", + "check if hex:12abcd != true", + "check if hex:12abcd == hex:12abcd", + "check if true == true", + "check if {1, 2} == {1, 2}", + "check if {1, 4} != true", + "check if {1, 4} != {1, 2}" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Ok": 0 + }, + "authorizer_code": "fact(1, 1);\nfact2(1, 2);\n\nallow if true;\n", + "revocation_ids": [ + "be50b2040f4b5fe278b87815910d249eeb9ca5238cae4ea538e22afda11f576e868cbfe7e6b0a03b02ae0f22239ec908947d4bad5a878e4b9f7bd7de73e5c90a" + ] + }, + "evaluate to false": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "fact(1, 2)", + "fact2(1, 1)" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if \"abcD12\" == \"abcD12\"", + "check if \"abcD12x\" != \"abcD12\"", + "check if \"abcD12x\" != true", + "check if 1 != 3", + "check if 1 != true", + "check if 1 != true", + "check if 1 == 1", + "check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z", + "check if 2022-12-04T09:46:41Z != true", + "check if 2022-12-04T09:46:41Z == 2022-12-04T09:46:41Z", + "check if fact(1, $value), 1 == $value", + "check if fact2(1, $value), 1 != $value", + "check if false != true", + "check if false == false", + "check if hex:12abcd != hex:12ab", + "check if hex:12abcd != true", + "check if hex:12abcd == hex:12abcd", + "check if true == true", + "check if {1, 2} == {1, 2}", + "check if {1, 4} != true", + "check if {1, 4} != {1, 2}" + ] + }, + { + "origin": 18446744073709551615, + "checks": [ + "check if false != false" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Err": { + "FailedLogic": { + "Unauthorized": { + "policy": { + "Allow": 0 + }, + "checks": [ + { + "Authorizer": { + "check_id": 0, + "rule": "check if false != false" + } + }, + { + "Block": { + "block_id": 0, + "check_id": 19, + "rule": "check if fact(1, $value), 1 == $value" + } + }, + { + "Block": { + "block_id": 0, + "check_id": 20, + "rule": "check if fact2(1, $value), 1 != $value" + } + } + ] + } + } + } + }, + "authorizer_code": "fact(1, 2);\nfact2(1, 1);\n\ncheck if false != false;\n\nallow if true;\n", + "revocation_ids": [ + "be50b2040f4b5fe278b87815910d249eeb9ca5238cae4ea538e22afda11f576e868cbfe7e6b0a03b02ae0f22239ec908947d4bad5a878e4b9f7bd7de73e5c90a" + ] + } + } + }, + { + "title": "test laziness and closures", + "filename": "test032_laziness_closures.bc", + "token": [ + { + "symbols": [ + "x", + "p", + "q" + ], + "public_keys": [], + "external_key": null, + "code": "check if !false && true;\ncheck if false || true;\ncheck if (true || false) && true;\ncheck if !(false && \"x\".intersection(\"x\"));\ncheck if true || \"x\".intersection(\"x\");\ncheck if {1, 2, 3}.all($p -> $p > 0);\ncheck if !{1, 2, 3}.all($p -> $p == 2);\ncheck if {1, 2, 3}.any($p -> $p > 2);\ncheck if !{1, 2, 3}.any($p -> $p > 3);\ncheck if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q));\n", + "version": 6 + } + ], + "validations": { + "": { + "world": { + "facts": [], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if !(false && \"x\".intersection(\"x\"))", + "check if !false && true", + "check if !{1, 2, 3}.all($p -> $p == 2)", + "check if !{1, 2, 3}.any($p -> $p > 3)", + "check if (true || false) && true", + "check if false || true", + "check if true || \"x\".intersection(\"x\")", + "check if {1, 2, 3}.all($p -> $p > 0)", + "check if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q))", + "check if {1, 2, 3}.any($p -> $p > 2)" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Ok": 0 + }, + "authorizer_code": "allow if true;\n", + "revocation_ids": [ + "2cd348b6df5f08b900903fd8d3fbea0bb89b665c331a2aa2131e0b8ecb38b3550275d4ccd8db35da6c4433eed1d456cfb761e3fcc7845894d891e986ca044b02" + ] + }, + "shadowing": { + "world": { + "facts": [], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if !(false && \"x\".intersection(\"x\"))", + "check if !false && true", + "check if !{1, 2, 3}.all($p -> $p == 2)", + "check if !{1, 2, 3}.any($p -> $p > 3)", + "check if (true || false) && true", + "check if false || true", + "check if true || \"x\".intersection(\"x\")", + "check if {1, 2, 3}.all($p -> $p > 0)", + "check if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q))", + "check if {1, 2, 3}.any($p -> $p > 2)" + ] + } + ], + "policies": [ + "allow if [true].any($p -> [true].all($p -> $p))" + ] + }, + "result": { + "Err": { + "Execution": "ShadowedVariable" + } + }, + "authorizer_code": "allow if [true].any($p -> [true].all($p -> $p));\n", + "revocation_ids": [ + "2cd348b6df5f08b900903fd8d3fbea0bb89b665c331a2aa2131e0b8ecb38b3550275d4ccd8db35da6c4433eed1d456cfb761e3fcc7845894d891e986ca044b02" + ] + } + } + }, + { + "title": "test .type()", + "filename": "test033_typeof.bc", + "token": [ + { + "symbols": [ + "integer", + "string", + "test", + "date", + "bytes", + "bool", + "set", + "null", + "array", + "map", + "a", + "t" + ], + "public_keys": [], + "external_key": null, + "code": "integer(1);\nstring(\"test\");\ndate(2023-12-28T00:00:00Z);\nbytes(hex:aa);\nbool(true);\nset({false, true});\nnull(null);\narray([1, 2, 3]);\nmap({\"a\": true});\ncheck if 1.type() == \"integer\";\ncheck if integer($t), $t.type() == \"integer\";\ncheck if \"test\".type() == \"string\";\ncheck if string($t), $t.type() == \"string\";\ncheck if (2023-12-28T00:00:00Z).type() == \"date\";\ncheck if date($t), $t.type() == \"date\";\ncheck if hex:aa.type() == \"bytes\";\ncheck if bytes($t), $t.type() == \"bytes\";\ncheck if true.type() == \"bool\";\ncheck if bool($t), $t.type() == \"bool\";\ncheck if {false, true}.type() == \"set\";\ncheck if set($t), $t.type() == \"set\";\ncheck if null.type() == \"null\";\ncheck if null($t), $t.type() == \"null\";\ncheck if array($t), $t.type() == \"array\";\ncheck if map($t), $t.type() == \"map\";\n", + "version": 6 + } + ], + "validations": { + "": { + "world": { + "facts": [ + { + "origin": [ + 0 + ], + "facts": [ + "array([1, 2, 3])", + "bool(true)", + "bytes(hex:aa)", + "date(2023-12-28T00:00:00Z)", + "integer(1)", + "map({\"a\": true})", + "null(null)", + "set({false, true})", + "string(\"test\")" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if \"test\".type() == \"string\"", + "check if (2023-12-28T00:00:00Z).type() == \"date\"", + "check if 1.type() == \"integer\"", + "check if array($t), $t.type() == \"array\"", + "check if bool($t), $t.type() == \"bool\"", + "check if bytes($t), $t.type() == \"bytes\"", + "check if date($t), $t.type() == \"date\"", + "check if hex:aa.type() == \"bytes\"", + "check if integer($t), $t.type() == \"integer\"", + "check if map($t), $t.type() == \"map\"", + "check if null($t), $t.type() == \"null\"", + "check if null.type() == \"null\"", + "check if set($t), $t.type() == \"set\"", + "check if string($t), $t.type() == \"string\"", + "check if true.type() == \"bool\"", + "check if {false, true}.type() == \"set\"" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Ok": 0 + }, + "authorizer_code": "allow if true;\n", + "revocation_ids": [ + "e60875c6ef7917c227a5e4b2cabfe250a85fa0598eb3cf7987ded0da2b69a559a1665bd312aeecde78e76aeb28ea1c1a03ec9b7dec8aeb519e7867ef8ff9b402" + ] + } + } + }, + { + "title": "test array and map operations", + "filename": "test034_array_map.bc", + "token": [ + { + "symbols": [ + "a", + "b", + "c", + "p", + "d", + "A", + "kv", + "id", + "roles" + ], + "public_keys": [], + "external_key": null, + "code": "check if [1, 2, 1].length() == 3;\ncheck if [\"a\", \"b\"] != true;\ncheck if [\"a\", \"b\"] != [1, 2, 3];\ncheck if [\"a\", \"b\"] == [\"a\", \"b\"];\ncheck if [\"a\", \"b\"] === [\"a\", \"b\"];\ncheck if [\"a\", \"b\"] !== [\"a\", \"c\"];\ncheck if [\"a\", \"b\", \"c\"].contains(\"c\");\ncheck if [1, 2, 3].starts_with([1, 2]);\ncheck if [4, 5, 6].ends_with([6]);\ncheck if [1, 2, \"a\"].get(2) == \"a\";\ncheck if [1, 2].get(3) == null;\ncheck if [1, 2, 3].all($p -> $p > 0);\ncheck if [1, 2, 3].any($p -> $p > 2);\ncheck if {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4}.length() == 4;\ncheck if {1: \"a\", 2: \"b\"} != true;\ncheck if {1: \"a\", 2: \"b\"} != {\"a\": 1, \"b\": 2};\ncheck if {1: \"a\", 2: \"b\"} == {1: \"a\", 2: \"b\"};\ncheck if {1: \"a\", 2: \"b\"} !== {\"a\": 1, \"b\": 2};\ncheck if {1: \"a\", 2: \"b\"} === {1: \"a\", 2: \"b\"};\ncheck if {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4}.contains(\"d\");\ncheck if {1: \"A\", \"a\": 1, \"b\": 2}.get(\"a\") == 1;\ncheck if {1: \"A\", \"a\": 1, \"b\": 2}.get(1) == \"A\";\ncheck if {1: \"A\", \"a\": 1, \"b\": 2}.get(\"c\") == null;\ncheck if {1: \"A\", \"a\": 1, \"b\": 2}.get(2) == null;\ncheck if {\"a\": 1, \"b\": 2}.all($kv -> $kv.get(0) != \"c\" && $kv.get(1) < 3);\ncheck if {1: \"A\", \"a\": 1, \"b\": 2}.any($kv -> $kv.get(0) == 1 && $kv.get(1) == \"A\");\ncheck if {\"user\": {\"id\": 1, \"roles\": [\"admin\"]}}.get(\"user\").get(\"roles\").contains(\"admin\");\n", + "version": 6 + } + ], + "validations": { + "": { + "world": { + "facts": [], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if [\"a\", \"b\", \"c\"].contains(\"c\")", + "check if [\"a\", \"b\"] != [1, 2, 3]", + "check if [\"a\", \"b\"] != true", + "check if [\"a\", \"b\"] !== [\"a\", \"c\"]", + "check if [\"a\", \"b\"] == [\"a\", \"b\"]", + "check if [\"a\", \"b\"] === [\"a\", \"b\"]", + "check if [1, 2, \"a\"].get(2) == \"a\"", + "check if [1, 2, 1].length() == 3", + "check if [1, 2, 3].all($p -> $p > 0)", + "check if [1, 2, 3].any($p -> $p > 2)", + "check if [1, 2, 3].starts_with([1, 2])", + "check if [1, 2].get(3) == null", + "check if [4, 5, 6].ends_with([6])", + "check if {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4}.contains(\"d\")", + "check if {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4}.length() == 4", + "check if {\"a\": 1, \"b\": 2}.all($kv -> $kv.get(0) != \"c\" && $kv.get(1) < 3)", + "check if {\"user\": {\"id\": 1, \"roles\": [\"admin\"]}}.get(\"user\").get(\"roles\").contains(\"admin\")", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.any($kv -> $kv.get(0) == 1 && $kv.get(1) == \"A\")", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.get(\"a\") == 1", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.get(\"c\") == null", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.get(1) == \"A\"", + "check if {1: \"A\", \"a\": 1, \"b\": 2}.get(2) == null", + "check if {1: \"a\", 2: \"b\"} != true", + "check if {1: \"a\", 2: \"b\"} != {\"a\": 1, \"b\": 2}", + "check if {1: \"a\", 2: \"b\"} !== {\"a\": 1, \"b\": 2}", + "check if {1: \"a\", 2: \"b\"} == {1: \"a\", 2: \"b\"}", + "check if {1: \"a\", 2: \"b\"} === {1: \"a\", 2: \"b\"}" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Ok": 0 + }, + "authorizer_code": "allow if true;\n", + "revocation_ids": [ + "b22238a06ca9c015d3c49d4ebaa7e8ab6e0d69119b3264033618e726d62fc6f4757a7bebc25f255444aba39994554a62a53ecc13b68802efab8da85ace62390d" + ] + } + } + }, + { + "title": "test ffi calls (v6 blocks)", + "filename": "test035_ffi.bc", + "token": [ + { + "symbols": [ + "test", + "a", + "equal strings" + ], + "public_keys": [], + "external_key": null, + "code": "check if true.extern::test(), \"a\".extern::test(\"a\") == \"equal strings\";\n", + "version": 6 + } + ], + "validations": { + "": { + "world": { + "facts": [], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if true.extern::test(), \"a\".extern::test(\"a\") == \"equal strings\"" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Ok": 0 + }, + "authorizer_code": "allow if true;\n", + "revocation_ids": [ + "d1719fd101c2695d2dac4df67569918363f691b6167670e1dbbf8026f639a7aa1ec2e13707f4d34cadbb2adce5c6e8a816577dd069a8717e0f5cb4ea3cec5b04" + ] + } + } + }, + { + "title": "ECDSA secp256r1 signatures", + "filename": "test036_secp256r1.bc", + "token": [ + { + "symbols": [ + "file1", + "file2" + ], + "public_keys": [], + "external_key": null, + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\n", + "version": 3 + }, + { + "symbols": [ + "0" + ], + "public_keys": [], + "external_key": null, + "code": "check if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 3 + } + ], + "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": [ + "628b9a6d74cc80b3ece50befd1f5f0f025c0a35d51708b2e77c11aed5f968b93b4096c87ed8169605716de934e155443f140334d71708fcc4247e5a0a518b30d", + "3046022100b60674854a12814cc36c8aab9600c1d9f9d3160e2334b72c0feede5a56213ea5022100a4f4bbf2dc33b309267af39fce76612017ddb6171e9cd2a3aa8a853f45f1675f" + ] + } + } + }, + { + "title": "ECDSA secp256r1 signature on third-party block", + "filename": "test037_secp256r1_third_party.bc", + "token": [ + { + "symbols": [ + "file1", + "file2", + "from_third" + ], + "public_keys": [ + "secp256r1/025e918fd4463832aea2823dfd9716a36b4d9b1377bd53dd82ddf4c0bc75ed6bbf" + ], + "external_key": null, + "code": "right(\"file1\", \"read\");\nright(\"file2\", \"read\");\nright(\"file1\", \"write\");\ncheck if from_third(true) trusting secp256r1/025e918fd4463832aea2823dfd9716a36b4d9b1377bd53dd82ddf4c0bc75ed6bbf;\n", + "version": 4 + }, + { + "symbols": [ + "from_third", + "0" + ], + "public_keys": [], + "external_key": "secp256r1/025e918fd4463832aea2823dfd9716a36b4d9b1377bd53dd82ddf4c0bc75ed6bbf", + "code": "from_third(true);\ncheck if resource($0), operation(\"read\"), right($0, \"read\");\n", + "version": 5 + } + ], + "validations": { + "": { + "world": { + "facts": [ + { + "origin": [ + null + ], + "facts": [ + "operation(\"read\")", + "resource(\"file1\")" + ] + }, + { + "origin": [ + 0 + ], + "facts": [ + "right(\"file1\", \"read\")", + "right(\"file1\", \"write\")", + "right(\"file2\", \"read\")" + ] + }, + { + "origin": [ + 1 + ], + "facts": [ + "from_third(true)" + ] + } + ], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if from_third(true) trusting secp256r1/025e918fd4463832aea2823dfd9716a36b4d9b1377bd53dd82ddf4c0bc75ed6bbf" + ] + }, + { + "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": [ + "70f5402208516fd44cfc9df3dfcfc0a327ee9004f1801ed0a7abdcbbae923d566ddcd2d4a14f4622b35732c4e538af04075cc67ab0888fa2d8923cc668187f0f", + "30450220793f95665d9af646339503a073670ea2c352459d2a2c2e14c57565f6c7eaf6bc022100cccadfc37e46755f52bb054ed206d7335067885df599a69431db40e33f33d4cf" + ] + } + } + }, + { + "title": "test try operation", + "filename": "test038_try_op.bc", + "token": [ + { + "symbols": [], + "public_keys": [], + "external_key": null, + "code": "check if (true === 12).try_or(true);\ncheck if ((true === 12).try_or(true === 12)).try_or(true);\nreject if (true == 12).try_or(true);\n", + "version": 6 + } + ], + "validations": { + "": { + "world": { + "facts": [], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if ((true === 12).try_or(true === 12)).try_or(true)", + "check if (true === 12).try_or(true)", + "reject if (true == 12).try_or(true)" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Ok": 0 + }, + "authorizer_code": "allow if true;\n", + "revocation_ids": [ + "79674155cd5349604e89b00792aeaebfa0a512bd45edc289305ebec107f627d3d8c09847646a0d06c2390a4354771b2ebdc2cc66971f2d74ef744e4e81197600" + ] + }, + "right-hand side does not catch errors": { + "world": { + "facts": [], + "rules": [], + "checks": [ + { + "origin": 0, + "checks": [ + "check if ((true === 12).try_or(true === 12)).try_or(true)", + "check if (true === 12).try_or(true)", + "reject if (true == 12).try_or(true)" + ] + }, + { + "origin": 18446744073709551615, + "checks": [ + "check if true.try_or(true === 12)" + ] + } + ], + "policies": [ + "allow if true" + ] + }, + "result": { + "Err": { + "Execution": "InvalidType" + } + }, + "authorizer_code": "check if true.try_or(true === 12);\n\nallow if true;\n", + "revocation_ids": [ + "79674155cd5349604e89b00792aeaebfa0a512bd45edc289305ebec107f627d3d8c09847646a0d06c2390a4354771b2ebdc2cc66971f2d74ef744e4e81197600" ] } } diff --git a/samples/data/current/test001_basic.bc b/samples/data/current/test001_basic.bc index e9a777a8..f45e91bb 100644 Binary files a/samples/data/current/test001_basic.bc and b/samples/data/current/test001_basic.bc differ diff --git a/samples/data/current/test002_different_root_key.bc b/samples/data/current/test002_different_root_key.bc index 0d75d0ad..edf2dd78 100644 Binary files a/samples/data/current/test002_different_root_key.bc and b/samples/data/current/test002_different_root_key.bc differ diff --git a/samples/data/current/test003_invalid_signature_format.bc b/samples/data/current/test003_invalid_signature_format.bc index 1144f09b..8c683a62 100644 Binary files a/samples/data/current/test003_invalid_signature_format.bc and b/samples/data/current/test003_invalid_signature_format.bc differ diff --git a/samples/data/current/test004_random_block.bc b/samples/data/current/test004_random_block.bc index 1b2611fe..e8882d3e 100644 Binary files a/samples/data/current/test004_random_block.bc and b/samples/data/current/test004_random_block.bc differ diff --git a/samples/data/current/test005_invalid_signature.bc b/samples/data/current/test005_invalid_signature.bc index d7620dc2..b33c6abd 100644 Binary files a/samples/data/current/test005_invalid_signature.bc and b/samples/data/current/test005_invalid_signature.bc differ diff --git a/samples/data/current/test006_reordered_blocks.bc b/samples/data/current/test006_reordered_blocks.bc index 338c73d9..486981c5 100644 Binary files a/samples/data/current/test006_reordered_blocks.bc and b/samples/data/current/test006_reordered_blocks.bc differ diff --git a/samples/data/current/test007_scoped_rules.bc b/samples/data/current/test007_scoped_rules.bc index 91e24ea8..905f9351 100644 Binary files a/samples/data/current/test007_scoped_rules.bc and b/samples/data/current/test007_scoped_rules.bc differ diff --git a/samples/data/current/test008_scoped_checks.bc b/samples/data/current/test008_scoped_checks.bc index 9c54ad1f..82e4527c 100644 Binary files a/samples/data/current/test008_scoped_checks.bc and b/samples/data/current/test008_scoped_checks.bc differ diff --git a/samples/data/current/test009_expired_token.bc b/samples/data/current/test009_expired_token.bc index ee38c4df..1ae9e59f 100644 Binary files a/samples/data/current/test009_expired_token.bc and b/samples/data/current/test009_expired_token.bc differ diff --git a/samples/data/current/test010_authorizer_scope.bc b/samples/data/current/test010_authorizer_scope.bc index 975adeba..b0188a76 100644 Binary files a/samples/data/current/test010_authorizer_scope.bc and b/samples/data/current/test010_authorizer_scope.bc differ diff --git a/samples/data/current/test011_authorizer_authority_caveats.bc b/samples/data/current/test011_authorizer_authority_caveats.bc index 971d0d0f..a368cf3c 100644 Binary files a/samples/data/current/test011_authorizer_authority_caveats.bc and b/samples/data/current/test011_authorizer_authority_caveats.bc differ diff --git a/samples/data/current/test012_authority_caveats.bc b/samples/data/current/test012_authority_caveats.bc index f4352a67..6d852ec7 100644 Binary files a/samples/data/current/test012_authority_caveats.bc and b/samples/data/current/test012_authority_caveats.bc differ diff --git a/samples/data/current/test013_block_rules.bc b/samples/data/current/test013_block_rules.bc index 4ee974eb..149b4ee8 100644 Binary files a/samples/data/current/test013_block_rules.bc and b/samples/data/current/test013_block_rules.bc differ diff --git a/samples/data/current/test014_regex_constraint.bc b/samples/data/current/test014_regex_constraint.bc index f35237c1..6c3c87e8 100644 Binary files a/samples/data/current/test014_regex_constraint.bc and b/samples/data/current/test014_regex_constraint.bc differ diff --git a/samples/data/current/test015_multi_queries_caveats.bc b/samples/data/current/test015_multi_queries_caveats.bc index 85fff417..7c775b72 100644 Binary files a/samples/data/current/test015_multi_queries_caveats.bc and b/samples/data/current/test015_multi_queries_caveats.bc differ diff --git a/samples/data/current/test016_caveat_head_name.bc b/samples/data/current/test016_caveat_head_name.bc index 1a56d12f..c5066415 100644 Binary files a/samples/data/current/test016_caveat_head_name.bc and b/samples/data/current/test016_caveat_head_name.bc differ diff --git a/samples/data/current/test017_expressions.bc b/samples/data/current/test017_expressions.bc index c41083b5..5b28d360 100644 Binary files a/samples/data/current/test017_expressions.bc and b/samples/data/current/test017_expressions.bc differ diff --git a/samples/data/current/test018_unbound_variables_in_rule.bc b/samples/data/current/test018_unbound_variables_in_rule.bc index 718e0b58..36799591 100644 Binary files a/samples/data/current/test018_unbound_variables_in_rule.bc and b/samples/data/current/test018_unbound_variables_in_rule.bc differ diff --git a/samples/data/current/test019_generating_ambient_from_variables.bc b/samples/data/current/test019_generating_ambient_from_variables.bc index 7a90e327..f486a3c7 100644 Binary files a/samples/data/current/test019_generating_ambient_from_variables.bc and b/samples/data/current/test019_generating_ambient_from_variables.bc differ diff --git a/samples/data/current/test020_sealed.bc b/samples/data/current/test020_sealed.bc index 82a3b5e6..6ce22072 100644 Binary files a/samples/data/current/test020_sealed.bc and b/samples/data/current/test020_sealed.bc differ diff --git a/samples/data/current/test021_parsing.bc b/samples/data/current/test021_parsing.bc index 371e06e6..3f926365 100644 Binary files a/samples/data/current/test021_parsing.bc and b/samples/data/current/test021_parsing.bc differ diff --git a/samples/data/current/test022_default_symbols.bc b/samples/data/current/test022_default_symbols.bc index 8744c10c..c12449df 100644 Binary files a/samples/data/current/test022_default_symbols.bc and b/samples/data/current/test022_default_symbols.bc differ diff --git a/samples/data/current/test023_execution_scope.bc b/samples/data/current/test023_execution_scope.bc index 464ffe62..b10a6861 100644 Binary files a/samples/data/current/test023_execution_scope.bc and b/samples/data/current/test023_execution_scope.bc differ diff --git a/samples/data/current/test024_third_party.bc b/samples/data/current/test024_third_party.bc index 9428ff06..8b7b8645 100644 Binary files a/samples/data/current/test024_third_party.bc and b/samples/data/current/test024_third_party.bc differ diff --git a/samples/data/current/test025_check_all.bc b/samples/data/current/test025_check_all.bc index 19398396..221df2ca 100644 Binary files a/samples/data/current/test025_check_all.bc and b/samples/data/current/test025_check_all.bc differ diff --git a/samples/data/current/test026_public_keys_interning.bc b/samples/data/current/test026_public_keys_interning.bc index 1b56f896..89a87c7f 100644 Binary files a/samples/data/current/test026_public_keys_interning.bc and b/samples/data/current/test026_public_keys_interning.bc differ diff --git a/samples/data/current/test027_integer_wraparound.bc b/samples/data/current/test027_integer_wraparound.bc index 6b5a5a5c..463a6c53 100644 Binary files a/samples/data/current/test027_integer_wraparound.bc and b/samples/data/current/test027_integer_wraparound.bc differ diff --git a/samples/data/current/test028_expressions_v4.bc b/samples/data/current/test028_expressions_v4.bc index 63f8f788..c34d7a10 100644 Binary files a/samples/data/current/test028_expressions_v4.bc and b/samples/data/current/test028_expressions_v4.bc differ diff --git a/samples/data/current/test029_reject_if.bc b/samples/data/current/test029_reject_if.bc new file mode 100644 index 00000000..86ef918b Binary files /dev/null and b/samples/data/current/test029_reject_if.bc differ diff --git a/samples/data/current/test030_null.bc b/samples/data/current/test030_null.bc new file mode 100644 index 00000000..2868715d Binary files /dev/null and b/samples/data/current/test030_null.bc differ diff --git a/samples/data/current/test031_heterogeneous_equal.bc b/samples/data/current/test031_heterogeneous_equal.bc new file mode 100644 index 00000000..2f6cb41f Binary files /dev/null and b/samples/data/current/test031_heterogeneous_equal.bc differ diff --git a/samples/data/current/test032_laziness_closures.bc b/samples/data/current/test032_laziness_closures.bc new file mode 100644 index 00000000..9a98b876 Binary files /dev/null and b/samples/data/current/test032_laziness_closures.bc differ diff --git a/samples/data/current/test033_typeof.bc b/samples/data/current/test033_typeof.bc new file mode 100644 index 00000000..517ae4e7 Binary files /dev/null and b/samples/data/current/test033_typeof.bc differ diff --git a/samples/data/current/test034_array_map.bc b/samples/data/current/test034_array_map.bc new file mode 100644 index 00000000..9deb150a Binary files /dev/null and b/samples/data/current/test034_array_map.bc differ diff --git a/samples/data/current/test035_ffi.bc b/samples/data/current/test035_ffi.bc new file mode 100644 index 00000000..a65c1c4e Binary files /dev/null and b/samples/data/current/test035_ffi.bc differ diff --git a/samples/data/current/test036_secp256r1.bc b/samples/data/current/test036_secp256r1.bc new file mode 100644 index 00000000..8c4c772d Binary files /dev/null and b/samples/data/current/test036_secp256r1.bc differ diff --git a/samples/data/current/test037_secp256r1_third_party.bc b/samples/data/current/test037_secp256r1_third_party.bc new file mode 100644 index 00000000..d40456e7 Binary files /dev/null and b/samples/data/current/test037_secp256r1_third_party.bc differ diff --git a/samples/data/current/test038_try_op.bc b/samples/data/current/test038_try_op.bc new file mode 100644 index 00000000..4155d44f Binary files /dev/null and b/samples/data/current/test038_try_op.bc differ diff --git a/samples/samples_test.go b/samples/samples_test.go index 691afa4a..721565e7 100644 --- a/samples/samples_test.go +++ b/samples/samples_test.go @@ -4,11 +4,11 @@ package biscuittest import ( - "crypto/ed25519" "crypto/rand" "encoding/hex" "encoding/json" "fmt" + "math" "os" "sort" "testing" @@ -67,70 +67,65 @@ type BiscuitError struct { } type World struct { - Facts []ScopedFact `json:"facts"` - Rules []ScopedRule `json:"rules"` - Checks []string `json:"checks"` - Policies []string `json:"policies"` + Facts []ScopedFacts `json:"facts"` + Rules []ScopedRules `json:"rules"` + Checks []ScopedChecks `json:"checks"` + Policies []string `json:"policies"` } -type ScopedFact struct { - Fact string - Scope [](*int32) +type ScopedFacts struct { + Facts []string `json:"facts"` + Scope [](*uint64) `json:"origin"` } -func (sf *ScopedFact) UnmarshalJSON(buf []byte) error { - tmp := []interface{}{&sf.Fact, &sf.Scope} - wantLen := len(tmp) - if err := json.Unmarshal(buf, &tmp); err != nil { - return err - } - if g, e := len(tmp), wantLen; g != e { - return fmt.Errorf("wrong number of fields in ScopedFact: %d != %d", g, e) - } - return nil -} - -type ScopedRule struct { - Rule string - Scope *int32 +type ScopedRules struct { + Rules []string `json:"rules"` + Scope *uint64 `json:"origin"` } -func (sr *ScopedRule) UnmarshalJSON(buf []byte) error { - tmp := []interface{}{&sr.Rule, &sr.Scope} - wantLen := len(tmp) - if err := json.Unmarshal(buf, &tmp); err != nil { - return err - } - if g, e := len(tmp), wantLen; g != e { - return fmt.Errorf("wrong number of fields in ScopedRule: %d != %d", g, e) - } - return nil +type ScopedChecks struct { + Checks []string `json:"checks"` + Scope *uint64 `json:"origin"` } func (w World) String() string { - facts := []string{} + facts := make(map[string][]string) for _, f := range w.Facts { - visible := true - for _, s := range f.Scope { - - if s != nil && *s != 0 { - visible = false - break + origin := make([]uint64, len(f.Scope)) + for i, s := range f.Scope { + if s != nil { + origin[i] = *s + } else { + origin[i] = math.MaxUint64 } } + sort.Slice(origin, func(i, j int) bool { + return origin[i] < origin[j] + }) + + originStr := fmt.Sprintf("%v", origin) + facts[originStr] = make([]string, 0) - if visible { - facts = append(facts, f.Fact) + for _, fact := range f.Facts { + facts[originStr] = append(facts[originStr], fact) } + sort.Strings(facts[originStr]) } - sort.Strings(facts) - rules := []string{} + + rules := make(map[string][]string) + for _, r := range w.Rules { - if r.Scope == nil || *r.Scope == 0 { - rules = append(rules, r.Rule) + origin := uint64(math.MaxUint64) + if r.Scope != nil { + origin = *r.Scope } + + originStr := fmt.Sprintf("%d", origin) + rules[originStr] = make([]string, 0) + + rules[originStr] = r.Rules + sort.Strings(rules[originStr]) } - sort.Strings(rules) return fmt.Sprintf("World {{\n\tfacts: %v\n\trules: %v\n}}", facts, rules) } @@ -142,13 +137,23 @@ type Validation struct { RevocationIds []string `json:"revocation_ids"` } -func CheckSample(root_key ed25519.PublicKey, c TestCase, t *testing.T) { +func CheckSample(root_key biscuit.PublicKey, c TestCase, t *testing.T) { // all these contain v4 blocks, which are not supported yet - if c.Filename == "test024_third_party.bc" || - c.Filename == "test025_check_all.bc" || - c.Filename == "test026_public_keys_interning.bc" || + if //c.Filename == "test024_third_party.bc" || + c.Filename == "test025_check_all.bc" || + //c.Filename == "test026_public_keys_interning.bc" || c.Filename == "test027_integer_wraparound.bc" || - c.Filename == "test028_expressions_v4.bc" { + c.Filename == "test028_expressions_v4.bc" || + c.Filename == "test029_reject_if.bc" || + c.Filename == "test030_null.bc" || + c.Filename == "test031_heterogeneous_equal.bc" || + c.Filename == "test032_laziness_closures.bc" || + c.Filename == "test033_typeof.bc" || + c.Filename == "test034_array_map.bc" || + c.Filename == "test035_ffi.bc" || + c.Filename == "test036_secp256r1.bc" || + c.Filename == "test037_secp256r1_third_party.bc" || + c.Filename == "test038_try_op.bc" { t.SkipNow() } fmt.Printf("Checking sample %s\n", c.Filename) @@ -181,7 +186,7 @@ func CompareBlocks(token biscuit.Biscuit, blocks []Block, t *testing.T) { p := parser.New() rng := rand.Reader - _, privateRoot, _ := ed25519.GenerateKey(rng) + _, privateRoot, _ := biscuit.NewEd25519KeyPair(rng) authority, err := p.Block(blocks[0].Code, nil) require.NoError(t, err) builder := biscuit.NewBuilder(privateRoot) @@ -203,7 +208,7 @@ func CompareBlocks(token biscuit.Biscuit, blocks []Block, t *testing.T) { require.Equal(t, sample, rebuilt.Code()) } -func CompareResult(root_key ed25519.PublicKey, filename string, token biscuit.Biscuit, v Validation, t *testing.T) { +func CompareResult(root_key biscuit.PublicKey, filename string, token biscuit.Biscuit, v Validation, t *testing.T) { p := parser.New() authorizer_code, err := p.Authorizer(v.AuthorizerCode, nil) require.NoError(t, err) @@ -212,7 +217,11 @@ func CompareResult(root_key ed25519.PublicKey, filename string, token biscuit.Bi if err != nil { CompareError(err, v.Result.Err, t) } else { - authorizer.AddAuthorizer(authorizer_code) + err = authorizer.AddAuthorizer(authorizer_code) + if err != nil { + CompareError(err, v.Result.Err, t) + return + } err = authorizer.Authorize() if err != nil { CompareError(err, v.Result.Err, t) @@ -250,7 +259,9 @@ func TestReadSamples(t *testing.T) { err = json.Unmarshal(b, &samples) require.NoError(t, err) - root_key, err := hex.DecodeString(samples.RootPublicKey) + root_key_data, err := hex.DecodeString(samples.RootPublicKey) + require.NoError(t, err) + root_key, err := biscuit.Ed25519PublicKeyDeserialize(root_key_data) require.NoError(t, err) fmt.Printf("Checking %d samples\n", len(samples.TestCases)) for _, v := range samples.TestCases { diff --git a/serialized.go b/serialized.go new file mode 100644 index 00000000..759463ce --- /dev/null +++ b/serialized.go @@ -0,0 +1,11 @@ +// Copyright (c) 2019 Titanous, daeMOn63 and Contributors to the Eclipse Foundation. +// SPDX-License-Identifier: Apache-2.0 + +package biscuit + +type SerializedBiscuit struct { + RootKeyID *uint32 + Authority CryptoBlock + Blocks []CryptoBlock + Proof TokenNext +} diff --git a/types.go b/types.go index 02cdf902..47ded7d6 100644 --- a/types.go +++ b/types.go @@ -13,8 +13,20 @@ import ( "github.com/biscuit-auth/biscuit-go/v2/datalog" ) +// minimum supported version of the serialization format const MinSchemaVersion uint32 = 3 -const MaxSchemaVersion uint32 = 3 + +// maximum supported version of the serialization format +const MaxSchemaVersion uint32 = 4 + +// starting version for datalog 3.1 features (check all, bitwise operators, !=, …) +const Datalog31 uint32 = 4 + +// starting version for 3rd party blocks (datalog 3.2) +const Datalog32 uint32 = 5 + +// starting version for datalog 3.3 features (reject if, closures, array/map, null, external functions, …) +const Datalog33 uint32 = 6 // defaultSymbolTable predefines some symbols available in every implementation, to avoid // transmitting them with every token @@ -22,9 +34,10 @@ var defaultSymbolTable = &datalog.SymbolTable{} type Block struct { symbols *datalog.SymbolTable - facts *datalog.FactSet + facts []datalog.Fact rules []datalog.Rule checks []datalog.Check + scopes []datalog.Scope context string version uint32 } @@ -33,8 +46,8 @@ func (b *Block) Code(symbols *datalog.SymbolTable) string { debug := &datalog.SymbolDebugger{ SymbolTable: symbols, } - facts := make([]string, len(*b.facts)) - for i, f := range *b.facts { + facts := make([]string, len(b.facts)) + for i, f := range b.facts { facts[i] = debug.Predicate(f.Predicate) } rules := make([]string, len(b.rules)) @@ -51,10 +64,12 @@ func (b *Block) Code(symbols *datalog.SymbolTable) string { %v %s %s + scopes: %v }`, strings.Join(facts, ";\n"), strings.Join(rules, ";\n"), strings.Join(checks, ";\n"), + b.scopes, ) } @@ -62,6 +77,10 @@ func (b *Block) String(symbols *datalog.SymbolTable) string { debug := &datalog.SymbolDebugger{ SymbolTable: symbols, } + facts := make([]string, len(b.facts)) + for i, f := range b.facts { + facts[i] = debug.Predicate(f.Predicate) + } rules := make([]string, len(b.rules)) for i, r := range b.rules { rules[i] = debug.Rule(r) @@ -82,7 +101,7 @@ func (b *Block) String(symbols *datalog.SymbolTable) string { }`, *b.symbols, b.context, - debug.FactSet(b.facts), + facts, rules, strings.Join(checks, ", "), b.version, @@ -172,7 +191,7 @@ func fromDatalogID(symbols *datalog.SymbolTable, id datalog.Term) (Term, error) case datalog.TermTypeBool: a = Bool(id.(datalog.Bool)) case datalog.TermTypeSet: - setIDs := id.(datalog.Set) + setIDs := id.(datalog.TermSet) set := make(Set, 0, len(setIDs)) for _, i := range setIDs { setTerm, err := fromDatalogID(symbols, i) @@ -193,6 +212,7 @@ type Rule struct { Head Predicate Body []Predicate Expressions []Expression + Scopes []datalog.Scope } func (r Rule) convert(symbols *datalog.SymbolTable) datalog.Rule { @@ -205,10 +225,17 @@ func (r Rule) convert(symbols *datalog.SymbolTable) datalog.Rule { for i, e := range r.Expressions { dlExpressions[i] = e.convert(symbols) } + + scopes := make([]datalog.Scope, len(r.Scopes)) + for i, scope := range r.Scopes { + scopes[i] = scope + } + return datalog.Rule{ - Head: r.Head.convert(symbols), - Body: dlBody, - Expressions: dlExpressions, + Head: r.Head.convert(symbols), + Body: dlBody, + Expressions: dlExpressions, + TrustedScopes: scopes, } } @@ -236,10 +263,16 @@ func fromDatalogRule(symbols *datalog.SymbolTable, dlRule datalog.Rule) (*Rule, expressions[i] = expr } + scopes := make([]datalog.Scope, len(dlRule.TrustedScopes)) + for i, scope := range dlRule.TrustedScopes { + scopes[i] = scope + } + return &Rule{ Head: *head, Body: body, Expressions: expressions, + Scopes: scopes, }, nil } @@ -364,6 +397,9 @@ const ( BinaryGreaterThan BinaryGreaterOrEqual BinaryEqual + BinaryNotEqual + BinaryStrictEqual + BinaryStrictNotEqual BinaryContains BinaryPrefix BinarySuffix @@ -393,6 +429,12 @@ func (op BinaryOp) convert(symbols *datalog.SymbolTable) datalog.Op { return datalog.BinaryOp{BinaryOpFunc: datalog.GreaterOrEqual{}} case BinaryEqual: return datalog.BinaryOp{BinaryOpFunc: datalog.Equal{}} + case BinaryNotEqual: + return datalog.BinaryOp{BinaryOpFunc: datalog.NotEqual{}} + case BinaryStrictEqual: + return datalog.BinaryOp{BinaryOpFunc: datalog.StrictEqual{}} + case BinaryStrictNotEqual: + return datalog.BinaryOp{BinaryOpFunc: datalog.StrictNotEqual{}} case BinaryContains: return datalog.BinaryOp{BinaryOpFunc: datalog.Contains{}} case BinaryPrefix: @@ -434,6 +476,12 @@ func fromDatalogBinaryOp(symbols *datalog.SymbolTable, dbBinary datalog.BinaryOp return BinaryGreaterOrEqual, nil case datalog.BinaryEqual: return BinaryEqual, nil + case datalog.BinaryNotEqual: + return BinaryNotEqual, nil + case datalog.BinaryStrictEqual: + return BinaryStrictEqual, nil + case datalog.BinaryStrictNotEqual: + return BinaryStrictNotEqual, nil case datalog.BinaryContains: return BinaryContains, nil case datalog.BinaryPrefix: @@ -588,7 +636,7 @@ type Set []Term func (a Set) Type() TermType { return TermTypeSet } func (a Set) convert(symbols *datalog.SymbolTable) datalog.Term { - datalogSet := make(datalog.Set, 0, len(a)) + datalogSet := make(datalog.TermSet, 0, len(a)) for _, e := range a { datalogSet = append(datalogSet, e.convert(symbols)) } @@ -621,3 +669,85 @@ type Policy struct { Queries []Rule Kind PolicyKind } + +type ScopeType byte + +const ( + ScopeTypeAuthority ScopeType = iota + ScopeTypePrevious + ScopeTypePublicKey + ScopeTypeParameter +) + +type Scope interface { + Type() ScopeType + convert(symbols *datalog.SymbolTable) datalog.Scope +} + +type AuthorityScope struct{} + +func (AuthorityScope) Type() ScopeType { + return ScopeTypeAuthority +} + +func (AuthorityScope) convert(symbols *datalog.SymbolTable) datalog.Scope { + return datalog.AuthorityScope{} +} + +type PreviousScope struct{} + +func (PreviousScope) Type() ScopeType { + return ScopeTypePrevious +} + +func (PreviousScope) convert(symbols *datalog.SymbolTable) datalog.Scope { + return datalog.PreviousScope{} +} + +/* +type PublicKeyScope struct { + publicKey ed25519.PublicKey +} + +func (PublicKeyScope) Type() ScopeType { + return ScopeTypePublicKey +} + +func (s PublicKeyScope) convert(symbols *datalog.SymbolTable) datalog.Scope { + return datalog.PublicKeyScope{ID: symbols.InsertPublicKey(s.publicKey)} +} + +type ParameterScope struct { + parameter string +} + +func (ParameterScope) Type() ScopeType { + return ScopeTypeParameter +} + +func (s Scope) convert(symbols *datalog.SymbolTable) datalog.Scope { + queries := make([]datalog.Rule, len(c.Queries)) + for i, q := range c.Queries { + queries[i] = q.convert(symbols) + } + + return datalog.Check{ + Queries: queries, + } +} +*/ +/* +func fromDatalogScope(symbols *datalog.SymbolTable, dlScope datalog.Scope) (*Scope, error) { + queries := make([]Rule, len(dlCheck.Queries)) + for i, q := range dlCheck.Queries { + query, err := fromDatalogRule(symbols, q) + if err != nil { + return nil, fmt.Errorf("failed to convert datalog check query: %w", err) + } + queries[i] = *query + } + + return &Check{ + Queries: queries, + }, nil +}*/ diff --git a/types_test.go b/types_test.go index cea05b82..b382b669 100644 --- a/types_test.go +++ b/types_test.go @@ -14,7 +14,7 @@ import ( func TestFromDatalogFact(t *testing.T) { now := time.Now() - symbolTable := &datalog.SymbolTable{"sym0", "sym1", "var1"} + symbolTable := &datalog.SymbolTable{Symbols: []string{"sym0", "sym1", "var1"}} dlFact := datalog.Fact{ Predicate: datalog.Predicate{ Name: datalog.String(datalog.OFFSET + 0), @@ -27,7 +27,7 @@ func TestFromDatalogFact(t *testing.T) { datalog.Bytes([]byte("some random bytes")), datalog.Bool(true), datalog.Bool(false), - datalog.Set{ + datalog.TermSet{ symbolTable.Insert("abc"), datalog.Integer(42), datalog.String(datalog.OFFSET + 1), diff --git a/website_test.go b/website_test.go index fc4d951e..8105db0e 100644 --- a/website_test.go +++ b/website_test.go @@ -16,14 +16,14 @@ import ( // code examples for the documentation at https://www.biscuitsec.org // if these functions change, please send a PR at https://github.com/biscuit-auth/website -func CreateKey() (ed25519.PublicKey, ed25519.PrivateKey) { +func CreateKey() (biscuit.PublicKey, biscuit.PrivateKey) { rng := rand.Reader - publicRoot, privateRoot, _ := ed25519.GenerateKey(rng) + publicRoot, privateRoot, _ := biscuit.NewEd25519KeyPair(rng) return publicRoot, privateRoot } -func CreateToken(root *ed25519.PrivateKey) (*biscuit.Biscuit, error) { - builder := biscuit.NewBuilder(*root) +func CreateToken(root biscuit.PrivateKey) (*biscuit.Biscuit, error) { + builder := biscuit.NewBuilder(root) fact, err := parser.FromStringFact(`user("1234")`) if err != nil { @@ -51,8 +51,8 @@ func CreateToken(root *ed25519.PrivateKey) (*biscuit.Biscuit, error) { return token, nil } -func Authorize(token *biscuit.Biscuit, root *ed25519.PublicKey) error { - authorizer, err := token.Authorizer(*root) +func Authorize(token *biscuit.Biscuit, root biscuit.PublicKey) error { + authorizer, err := token.Authorizer(root) if err != nil { return fmt.Errorf("failed to create verifier: %v", err) }