infobloxopen / seal

Apache License 2.0
16 stars 11 forks source link

Prefix/annotate obligations with swagger-type #133

Closed rchowinfoblox closed 3 years ago

rchowinfoblox commented 3 years ago

This PR adds type-information to obligations. Once this is merged, I'll update https://github.com/infobloxopen/seal/pull/132 with support for this type-information.

$ make test demo
?       github.com/infobloxopen/seal    [no test files]
?       github.com/infobloxopen/seal/cmd        [no test files]
?       github.com/infobloxopen/seal/pkg/ast    [no test files]
?       github.com/infobloxopen/seal/pkg/compiler       [no test files]
?       github.com/infobloxopen/seal/pkg/compiler/error [no test files]
=== RUN   TestCompile
    rego_test.go:180: validate policy: allow subject group foo to manage petstore.pet;
    rego_test.go:181: rego language output generated:

        package foo

        default allow = false
        default deny = false

        base_verbs := {
        }

        allow {
            seal_list_contains(seal_subject.groups, `foo`)
            seal_list_contains(base_verbs[input.type][`manage`], input.verb)
            re_match(`petstore.pet`, input.type)
        }

        obligations := {
        }

        # rego functions defined by seal

        # Helper to get the token payload.
        seal_subject = payload {
            [header, payload, signature] := io.jwt.decode(input.jwt)
        }

        # seal_list_contains returns true if elem exists in list
        seal_list_contains(list, elem) {
            list[_] = elem
        }
    rego_test.go:180: validate policy: allow subject user foo to manage petstore.pet;
    rego_test.go:181: rego language output generated:

        package foo

        default allow = false
        default deny = false

        base_verbs := {
        }

        allow {
            seal_subject.sub == `foo`
            seal_list_contains(base_verbs[input.type][`manage`], input.verb)
            re_match(`petstore.pet`, input.type)
        }

        obligations := {
        }

        # rego functions defined by seal

        # Helper to get the token payload.
        seal_subject = payload {
            [header, payload, signature] := io.jwt.decode(input.jwt)
        }

        # seal_list_contains returns true if elem exists in list
        seal_list_contains(list, elem) {
            list[_] = elem
        }
--- PASS: TestCompile (0.00s)
=== RUN   TestCleanupSomeI
--- PASS: TestCleanupSomeI (0.00s)
PASS
ok      github.com/infobloxopen/seal/pkg/compiler/rego  (cached)
=== RUN   TestCompileCondition
    sql_condition_test.go:74: Test#0: success: expected error and got err=no prefix condition parse function for IDENT found
    sql_condition_test.go:76: Test#1: success: where=(foobar.qwerty = 'there''s a single-quote in this string')
    sql_condition_test.go:76: Test#2: success: where=(mysqltable.nbf < 123 AND (mysqltable.description = 'string with subject. in it'))
    sql_condition_test.go:76: Test#3: success: where=((NOT (mysqltable.iss = 'string with ctx. in it')) AND (mysqltable.name ~ '.*goofy.*'))
    sql_condition_test.go:74: Test#4: success: expected error and got err=map/array indexing not supported yet: ctx.tags["endangered"]
    sql_condition_test.go:74: Test#5: success: expected error and got err=IN operator not supported yet: (ctx.id in "tag-manage")
--- PASS: TestCompileCondition (0.00s)
PASS
ok      github.com/infobloxopen/seal/pkg/compiler/sql   (cached)
=== RUN   TestCompiler
--- PASS: TestCompiler (0.00s)
=== RUN   TestLanguages
    compiler_test.go:86: validate list of languages - supported languages: []string{"rego"}
--- PASS: TestLanguages (0.00s)
=== RUN   TestBackend
=== RUN   TestBackend/invalid-nonwildcarded-resource-property
=== RUN   TestBackend/invalid-nonwildcarded-resource-property-in-context
=== RUN   TestBackend/invalid-nonwildcarded-resource-property-with-subject
=== RUN   TestBackend/obligations-wildcard
=== RUN   TestBackend/obligations-multi-oblig-in-single-stmt
=== RUN   TestBackend/missing-verb-errors
=== RUN   TestBackend/blank-subject
=== RUN   TestBackend/context
=== RUN   TestBackend/context-2
=== RUN   TestBackend/context-nested
=== RUN   TestBackend/not-in-operator
=== RUN   TestBackend/support-for-or-operator-simple
=== RUN   TestBackend/missing-resource-errors
=== RUN   TestBackend/in-operator
=== RUN   TestBackend/invalid-resource-format-without-using-family.type-errors
=== RUN   TestBackend/simplest-statement-with-subject
=== RUN   TestBackend/grouping-with-parens
=== RUN   TestBackend/grouping-with-not-and-parens
=== RUN   TestBackend/company.personnel
=== RUN   TestBackend/obligations-simple
=== RUN   TestBackend/support-for-or-operator-context
=== RUN   TestBackend/statement-with-and
=== RUN   TestBackend/multiple-statements
=== RUN   TestBackend/matches
=== RUN   TestBackend/invalid-resource-not-registered
=== RUN   TestBackend/no-swagger-actions
=== RUN   TestBackend/obligations-context
=== RUN   TestBackend/blank-swagger
=== RUN   TestBackend/statement-with-not
=== RUN   TestBackend/precedence-with-not
=== RUN   TestBackend/tags
=== RUN   TestBackend/obligations-multi-stmt-with-oblig
=== RUN   TestBackend/missing-to-errors
--- PASS: TestBackend (0.07s)
    --- PASS: TestBackend/invalid-nonwildcarded-resource-property (0.00s)
    --- PASS: TestBackend/invalid-nonwildcarded-resource-property-in-context (0.00s)
    --- PASS: TestBackend/invalid-nonwildcarded-resource-property-with-subject (0.00s)
    --- PASS: TestBackend/obligations-wildcard (0.00s)
    --- PASS: TestBackend/obligations-multi-oblig-in-single-stmt (0.00s)
    --- PASS: TestBackend/missing-verb-errors (0.00s)
    --- PASS: TestBackend/blank-subject (0.00s)
    --- PASS: TestBackend/context (0.00s)
    --- PASS: TestBackend/context-2 (0.00s)
    --- PASS: TestBackend/context-nested (0.00s)
    --- PASS: TestBackend/not-in-operator (0.00s)
    --- PASS: TestBackend/support-for-or-operator-simple (0.00s)
    --- PASS: TestBackend/missing-resource-errors (0.00s)
    --- PASS: TestBackend/in-operator (0.00s)
    --- PASS: TestBackend/invalid-resource-format-without-using-family.type-errors (0.00s)
    --- PASS: TestBackend/simplest-statement-with-subject (0.00s)
    --- PASS: TestBackend/grouping-with-parens (0.00s)
    --- PASS: TestBackend/grouping-with-not-and-parens (0.00s)
    --- PASS: TestBackend/company.personnel (0.00s)
    --- PASS: TestBackend/obligations-simple (0.00s)
    --- PASS: TestBackend/support-for-or-operator-context (0.00s)
    --- PASS: TestBackend/statement-with-and (0.00s)
    --- PASS: TestBackend/multiple-statements (0.00s)
    --- PASS: TestBackend/matches (0.00s)
    --- PASS: TestBackend/invalid-resource-not-registered (0.00s)
    --- PASS: TestBackend/no-swagger-actions (0.00s)
    --- PASS: TestBackend/obligations-context (0.00s)
    --- PASS: TestBackend/blank-swagger (0.00s)
    --- PASS: TestBackend/statement-with-not (0.00s)
    --- PASS: TestBackend/precedence-with-not (0.00s)
    --- PASS: TestBackend/tags (0.00s)
    --- PASS: TestBackend/obligations-multi-stmt-with-oblig (0.00s)
    --- PASS: TestBackend/missing-to-errors (0.00s)
=== RUN   TestManySwaggers
=== RUN   TestManySwaggers/global
=== RUN   TestManySwaggers/empty
=== RUN   TestManySwaggers/global-sw1-sw2
=== RUN   TestManySwaggers/global-sw2-sw1
=== RUN   TestManySwaggers/sw1
=== RUN   TestManySwaggers/sw2
--- PASS: TestManySwaggers (0.01s)
    --- PASS: TestManySwaggers/global (0.00s)
    --- PASS: TestManySwaggers/empty (0.00s)
    --- PASS: TestManySwaggers/global-sw1-sw2 (0.00s)
    --- PASS: TestManySwaggers/global-sw2-sw1 (0.00s)
    --- PASS: TestManySwaggers/sw1 (0.00s)
    --- PASS: TestManySwaggers/sw2 (0.00s)
PASS
ok      github.com/infobloxopen/seal/pkg/compiler/test  (cached)
=== RUN   TestNextToken
--- PASS: TestNextToken (0.00s)
=== RUN   TestContextToken
--- PASS: TestContextToken (0.00s)
=== RUN   TestNextTokenComment
--- PASS: TestNextTokenComment (0.00s)
PASS
ok      github.com/infobloxopen/seal/pkg/lexer  (cached)
=== RUN   TestWhereClause
=== RUN   TestWhereClause/simple_user
=== RUN   TestWhereClause/simple_group
=== RUN   TestWhereClause/simple_where_clause_compare_equal
=== RUN   TestWhereClause/simple_where_clause_compare_not_equal
=== RUN   TestWhereClause/simple_where_clause_compare_int
=== RUN   TestWhereClause/simple_where_clause_compare_bool
=== RUN   TestWhereClause/single_where_clause_and
=== RUN   TestWhereClause/left_associative_where_clause_and
=== RUN   TestWhereClause/where_clause_grouped_conditions
=== RUN   TestWhereClause/where_clause_multiple_grouped_conditions
--- PASS: TestWhereClause (0.00s)
    --- PASS: TestWhereClause/simple_user (0.00s)
    --- PASS: TestWhereClause/simple_group (0.00s)
    --- PASS: TestWhereClause/simple_where_clause_compare_equal (0.00s)
    --- PASS: TestWhereClause/simple_where_clause_compare_not_equal (0.00s)
    --- PASS: TestWhereClause/simple_where_clause_compare_int (0.00s)
    --- PASS: TestWhereClause/simple_where_clause_compare_bool (0.00s)
    --- PASS: TestWhereClause/single_where_clause_and (0.00s)
    --- PASS: TestWhereClause/left_associative_where_clause_and (0.00s)
    --- PASS: TestWhereClause/where_clause_grouped_conditions (0.00s)
    --- PASS: TestWhereClause/where_clause_multiple_grouped_conditions (0.00s)
=== RUN   TestExportedParseCondition
=== RUN   TestExportedParseCondition/no_parens
=== RUN   TestExportedParseCondition/single_parens
=== RUN   TestExportedParseCondition/double_parens
=== RUN   TestExportedParseCondition/mismatched_parens
    condition_test.go:199: ParseCondition(`(((ctx.age > 65))`) expected error, and error returned: "expected next token to be ), got EOF instead"
--- PASS: TestExportedParseCondition (0.00s)
    --- PASS: TestExportedParseCondition/no_parens (0.00s)
    --- PASS: TestExportedParseCondition/single_parens (0.00s)
    --- PASS: TestExportedParseCondition/double_parens (0.00s)
    --- PASS: TestExportedParseCondition/mismatched_parens (0.00s)
=== RUN   TestSplitKeyValueAnnotations
    condition_test.go:305: Test#0: pass (remain): input=` a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#0: pass (annMap): input=` a b c d ` annoMap=`map[]`
    condition_test.go:305: Test#1: pass (remain): input=` ; a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#1: pass (annMap): input=` ; a b c d ` annoMap=`map[]`
    condition_test.go:305: Test#2: pass (remain): input=` , ; a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#2: pass (annMap): input=` , ; a b c d ` annoMap=`map[]`
    condition_test.go:305: Test#3: pass (remain): input=`k1; a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#3: pass (annMap): input=`k1; a b c d ` annoMap=`map[k1:]`
    condition_test.go:305: Test#4: pass (remain): input=`k1: v1 ; a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#4: pass (annMap): input=`k1: v1 ; a b c d ` annoMap=`map[k1:v1]`
    condition_test.go:305: Test#5: pass (remain): input=`k1: v1 , k2 ; a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#5: pass (annMap): input=`k1: v1 , k2 ; a b c d ` annoMap=`map[k1:v1 k2:]`
    condition_test.go:305: Test#6: pass (remain): input=`k1: v1 , k2 : ; a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#6: pass (annMap): input=`k1: v1 , k2 : ; a b c d ` annoMap=`map[k1:v1 k2:]`
    condition_test.go:305: Test#7: pass (remain): input=`k1: v1 , k2 : v2 ; a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#7: pass (annMap): input=`k1: v1 , k2 : v2 ; a b c d ` annoMap=`map[k1:v1 k2:v2]`
    condition_test.go:305: Test#8: pass (remain): input=`k 1: v 1 , k 2 : v 2 ; a b c d ` remaining=` a b c d `
    condition_test.go:313: Test#8: pass (annMap): input=`k 1: v 1 , k 2 : v 2 ; a b c d ` annoMap=`map[k 1:v 1 k 2:v 2]`
--- PASS: TestSplitKeyValueAnnotations (0.00s)
=== RUN   TestLetStatements
--- PASS: TestLetStatements (0.00s)
PASS
ok      github.com/infobloxopen/seal/pkg/parser (cached)
=== RUN   TestLookupOperator
=== RUN   TestLookupOperator/invalid_empty
=== RUN   TestLookupOperator/equal_to
=== RUN   TestLookupOperator/not_equal
=== RUN   TestLookupOperator/less_than
=== RUN   TestLookupOperator/greater_than
=== RUN   TestLookupOperator/less_than_or_equal_to
=== RUN   TestLookupOperator/greater_than_or_equal_to
=== RUN   TestLookupOperator/not
=== RUN   TestLookupOperator/and
=== RUN   TestLookupOperator/or
=== RUN   TestLookupOperator/matches
--- PASS: TestLookupOperator (0.00s)
    --- PASS: TestLookupOperator/invalid_empty (0.00s)
    --- PASS: TestLookupOperator/equal_to (0.00s)
    --- PASS: TestLookupOperator/not_equal (0.00s)
    --- PASS: TestLookupOperator/less_than (0.00s)
    --- PASS: TestLookupOperator/greater_than (0.00s)
    --- PASS: TestLookupOperator/less_than_or_equal_to (0.00s)
    --- PASS: TestLookupOperator/greater_than_or_equal_to (0.00s)
    --- PASS: TestLookupOperator/not (0.00s)
    --- PASS: TestLookupOperator/and (0.00s)
    --- PASS: TestLookupOperator/or (0.00s)
    --- PASS: TestLookupOperator/matches (0.00s)
PASS
ok      github.com/infobloxopen/seal/pkg/token  (cached)
=== RUN   TestIsNilInterface
--- PASS: TestIsNilInterface (0.00s)
=== RUN   TestNewTypeFromOpenAPIv3
    types_test.go:17: got type: petstore.pet
    types_test.go:19: got action: &types.swaggerAction{name:"allow", schema:(*openapi3.SchemaRef)(0xc000134540)}
    types_test.go:23:     TODO: get type schema for action
    types_test.go:19: got action: &types.swaggerAction{name:"deny", schema:(*openapi3.SchemaRef)(nil)}
    types_test.go:23:     TODO: get type schema for action
--- PASS: TestNewTypeFromOpenAPIv3 (0.00s)
PASS
ok      github.com/infobloxopen/seal/pkg/types  (cached)
./seal compile \
        -s docs/source/examples/petstore/petstore.jwt.swagger \
        -s docs/source/examples/petstore/petstore.tags.swagger \
        -s docs/source/examples/petstore/petstore.all.swagger \
        -f docs/source/examples/petstore/petstore.all.seal \
        > docs/source/examples/petstore/petstore.all.rego.compiled
INFO[0000] set logging format                            logging.format=text
INFO[0000] logging level                                 logging.level=info
cat docs/source/examples/petstore/petstore.all.rego.compiled

package petstore.all

default allow = false
default deny = false

base_verbs := {
    "petstore.order": {
        "approve": [
            "approve",
        ],
        "deliver": [
            "deliver",
        ],
        "inspect": [
            "list",
            "watch",
        ],
        "manage": [
            "create",
            "delete",
            "update",
            "get",
            "list",
            "watch",
        ],
        "read": [
            "get",
            "list",
            "watch",
        ],
        "ship": [
            "ship",
        ],
        "use": [
            "update",
            "get",
            "list",
            "watch",
        ],
    },
    "petstore.pet": {
        "buy": [
            "buy",
        ],
        "inspect": [
            "list",
            "watch",
        ],
        "manage": [
            "create",
            "delete",
            "update",
            "get",
            "list",
            "watch",
        ],
        "provision": [
            "provision",
        ],
        "read": [
            "get",
            "list",
            "watch",
        ],
        "sell": [
            "sell",
        ],
        "use": [
            "update",
            "get",
            "list",
            "watch",
        ],
    },
    "petstore.user": {
        "inspect": [
            "list",
            "watch",
        ],
        "manage": [
            "create",
            "delete",
            "update",
            "get",
            "list",
            "watch",
        ],
        "read": [
            "get",
            "list",
            "watch",
        ],
        "sign_in": [
            "sign_in",
        ],
        "use": [
            "update",
            "get",
            "list",
            "watch",
        ],
    },
}

deny {
    seal_list_contains(base_verbs[input.type][`deliver`], input.verb)
    re_match(`petstore.order`, input.type)
    seal_list_contains(seal_subject.groups, `boss`)
}

deny {
    seal_list_contains(base_verbs[input.type][`use`], input.verb)
    re_match(`petstore.order`, input.type)

    some i
    input.ctx[i]["id"] == "-1"
}

deny {
    seal_list_contains(base_verbs[input.type][`use`], input.verb)
    re_match(`petstore.user`, input.type)

    some i
    input.ctx[i]["id"] == "-1"
}

deny {
    seal_list_contains(base_verbs[input.type][`use`], input.verb)
    re_match(`petstore.order`, input.type)
    seal_subject.iss != "context.petstore.swagger.io"
}

deny {
    seal_list_contains(base_verbs[input.type][`use`], input.verb)
    re_match(`petstore.user`, input.type)
    seal_subject.iss != "context.petstore.swagger.io"
}

deny {
    seal_list_contains(base_verbs[input.type][`deliver`], input.verb)
    re_match(`petstore.order`, input.type)

    some i
    input.ctx[i]["status"] == "delivered"
}

deny {
    seal_list_contains(seal_subject.groups, `regexp`)
    seal_list_contains(base_verbs[input.type][`use`], input.verb)
    re_match(`petstore.*`, input.type)
    re_match(`@petstore.swagger.io$`, seal_subject.jti)
}

deny {
    seal_list_contains(seal_subject.groups, `everyone`)
    seal_list_contains(base_verbs[input.type][`use`], input.verb)
    re_match(`petstore.*`, input.type)
    seal_subject.iss != "petstore.swagger.io"
}

deny {
    seal_list_contains(seal_subject.groups, `everyone`)
    seal_list_contains(base_verbs[input.type][`buy`], input.verb)
    re_match(`petstore.pet`, input.type)

    some i
    input.ctx[i]["age"] <= 2
    input.ctx[i]["name"] == "specificPetName"
}

deny {
    seal_list_contains(seal_subject.groups, `banned`)
    seal_list_contains(base_verbs[input.type][`manage`], input.verb)
    re_match(`petstore.*`, input.type)
}

deny {
    seal_list_contains(seal_subject.groups, `managers`)
    seal_list_contains(base_verbs[input.type][`sell`], input.verb)
    re_match(`petstore.pet`, input.type)

    some i
    input.ctx[i]["status"] != "available"
}

deny {
    seal_list_contains(seal_subject.groups, `fussy`)
    seal_list_contains(base_verbs[input.type][`buy`], input.verb)
    re_match(`petstore.pet`, input.type)
    not line13_not1_cnd
    not line13_not2_cnd
}

allow {
    seal_list_contains(seal_subject.groups, `fussy`)
    seal_list_contains(base_verbs[input.type][`buy`], input.verb)
    re_match(`petstore.pet`, input.type)
    not line14_not1_cnd
}

allow {
    seal_list_contains(seal_subject.groups, `not_operator_precedence`)
    seal_list_contains(base_verbs[input.type][`buy`], input.verb)
    re_match(`petstore.pet`, input.type)

    some i
    not line15_not1_cnd
    input.ctx[i]["potty_trained"]
}

deny {
    seal_list_contains(seal_subject.groups, `everyone`)
    seal_list_contains(base_verbs[input.type][`buy`], input.verb)
    re_match(`petstore.pet`, input.type)

    some i
    input.ctx[i]["tags"]["endangered"] == "true"
}

allow {
    seal_list_contains(seal_subject.groups, `operators`)
    seal_list_contains(base_verbs[input.type][`use`], input.verb)
    re_match(`petstore.*`, input.type)
}

allow {
    seal_list_contains(seal_subject.groups, `managers`)
    seal_list_contains(base_verbs[input.type][`manage`], input.verb)
    re_match(`petstore.*`, input.type)
}

allow {
    seal_subject.sub == `cto@petstore.swagger.io`
    seal_list_contains(base_verbs[input.type][`manage`], input.verb)
    re_match(`petstore.*`, input.type)
}

allow {
    seal_list_contains(base_verbs[input.type][`inspect`], input.verb)
    re_match(`petstore.pet`, input.type)
}

allow {
    seal_list_contains(seal_subject.groups, `everyone`)
    seal_list_contains(base_verbs[input.type][`inspect`], input.verb)
    re_match(`petstore.pet`, input.type)
}

allow {
    seal_list_contains(seal_subject.groups, `customers`)
    seal_list_contains(base_verbs[input.type][`read`], input.verb)
    re_match(`petstore.pet`, input.type)
}

allow {
    seal_list_contains(seal_subject.groups, `customers`)
    seal_list_contains(base_verbs[input.type][`buy`], input.verb)
    re_match(`petstore.pet`, input.type)

    some i
    input.ctx[i]["status"] == "available"
}

allow {
    seal_list_contains(seal_subject.groups, `breeders_maltese`)
    seal_list_contains(base_verbs[input.type][`buy`], input.verb)
    re_match(`petstore.pet`, input.type)

    some i
    input.ctx[i]["status"] == "reserved"
    input.ctx[i]["breed"] == "maltese"
}

allow {
    seal_list_contains(seal_subject.groups, `employees`)
    seal_list_contains(base_verbs[input.type][`inspect`], input.verb)
    re_match(`petstore.order`, input.type)

    some i
    input.ctx[i]["status"] == "delivered"
}

allow {
    seal_list_contains(seal_subject.groups, `supervisors`)
    seal_list_contains(base_verbs[input.type][`manage`], input.verb)
    re_match(`petstore.user`, input.type)

    some i
    re_match(`.*@acme.com`, input.ctx[i]["email"])
}

line13_not1_cnd {
    some i
    input.ctx[i]["neutered"]
}

line13_not2_cnd {
    some i
    input.ctx[i]["potty_trained"]
}

line14_not1_cnd {
    some i
    input.ctx[i]["neutered"]
    input.ctx[i]["potty_trained"]
}

line15_not1_cnd {
    some i
    input.ctx[i]["neutered"]
}

obligations := {
    `stmt20`: [
        `type:petstore.order; (ctx.marketplace != "amazon")`,
    ],
    `stmt21`: [
        `type:petstore.user; ((ctx.occupation != "unemployed") and (ctx.salary > 200000))`,
    ],
}

# rego functions defined by seal

# Helper to get the token payload.
seal_subject = payload {
    [header, payload, signature] := io.jwt.decode(input.jwt)
}

# seal_list_contains returns true if elem exists in list
seal_list_contains(list, elem) {
    list[_] = elem
}

cp docs/source/examples/petstore/petstore.all.rego.compiled docs/source/examples/petstore/petstore.all.rego
# beware that check-rego.sh reformats the compiled rego files...
./docs/source/examples/check-rego.sh docs/source/examples/petstore
+ IMAGE=openpolicyagent/opa:latest
+ [[ -z docs/source/examples/petstore ]]
+ [[ ! -d docs/source/examples/petstore ]]
++ cd docs/source/examples/petstore
++ /bin/pwd
+ TOP=/home/riccho/go/src/github.com/infobloxopen/seal/docs/source/examples/petstore
+ cd /home/riccho/go/src/github.com/infobloxopen/seal/docs/source/examples/petstore
+ docker run -v /home/riccho/go/src/github.com/infobloxopen/seal/docs/source/examples/petstore:/data -w /data openpolicyagent/opa:latest fmt -w .
+ case "$(basename $0)" in
++ basename ./docs/source/examples/check-rego.sh
+ docker run --rm -v /home/riccho/go/src/github.com/infobloxopen/seal/docs/source/examples/petstore:/data -w /data openpolicyagent/opa:latest test -v petstore.all.rego petstore.all.test_bench.rego petstore.all.test.rego petstore.all.mock.json
data.petstore.all.test_in: PASS (1.413064ms)
data.petstore.all.test_in_negative: PASS (910.83µs)
data.petstore.all.test_not_operator_precedence_positive: PASS (783.722µs)
data.petstore.all.test_not_operator_precedence_negative1: PASS (745.253µs)
data.petstore.all.test_not_operator_precedence_negative2: PASS (740.966µs)
data.petstore.all.test_not_operator_precedence_negative3: PASS (939.431µs)
data.petstore.all.test_regexp: PASS (1.942577ms)
data.petstore.all.test_regexp_negative: PASS (878.979µs)
data.petstore.all.test_ctx_usage_multiply: PASS (1.450903ms)
data.petstore.all.test_ctx_usage_negative_multi_ctx: PASS (1.307227ms)
data.petstore.all.test_ctx_usage_negative: PASS (1.318162ms)
data.petstore.all.test_use_tags: PASS (1.298935ms)
data.petstore.all.test_use_tags_negative: PASS (1.271042ms)
data.petstore.all.test_use_tags_negative_missing_endangered_tag: PASS (2.244158ms)
data.petstore.all.test_use_petstore_jwt: PASS (1.030092ms)
data.petstore.all.test_use_petstore_jwt_negative: PASS (884.392µs)
data.petstore.all.test_banned_deny: PASS (933.886µs)
data.petstore.all.test_banned_deny_negative: PASS (827.555µs)
data.petstore.all.test_inspect: PASS (751.168µs)
data.petstore.all.test_inspect_negative: PASS (632.022µs)
data.petstore.all.test_read: PASS (1.55778ms)
data.petstore.all.test_read_negative: PASS (1.404262ms)
data.petstore.all.test_manage_cto: PASS (1.301626ms)
data.petstore.all.test_blank_subject: PASS (1.467127ms)
data.petstore.all.test_bench_deny_in_map_species: PASS (272.052µs)
data.petstore.all.test_bench_deny_in_map_species_2nd: PASS (264.26µs)
data.petstore.all.test_bench_deny_in_map_species_negative: PASS (332.596µs)
data.petstore.all.test_bench_deny_in_map_species_negative_2nd: PASS (244.519µs)
--------------------------------------------------------------------------------
PASS: 28/28
+ git diff --exit-code petstore.all.rego petstore.all.test_bench.rego petstore.all.test.rego
git diff --exit-code docs/source/examples/petstore
### petstore example passed REGO OPA tests