Skip to content

Commit

Permalink
Merge pull request #26 from strongdm/idx-48/stable-ast
Browse files Browse the repository at this point in the history
Add JSON, programmatic AST, marshaling to Cedar for 0.2.0 release
  • Loading branch information
philhassey authored Aug 26, 2024
2 parents a71e93e + 1da3cb2 commit 17b4d78
Show file tree
Hide file tree
Showing 100 changed files with 12,590 additions and 6,998 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.idea/
tmp/
46 changes: 38 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ import (
"fmt"
"log"

"github.com/cedar-policy/cedar-go"
cedar "github.com/cedar-policy/cedar-go"
"github.com/cedar-policy/cedar-go/types"
)

const policyCedar = `permit (
Expand All @@ -80,20 +81,25 @@ const entitiesJSON = `[
]`

func main() {
ps, err := cedar.NewPolicySet("policy.cedar", []byte(policyCedar))
if err != nil {
var policy cedar.Policy
if err := policy.UnmarshalCedar([]byte(policyCedar)); err != nil {
log.Fatal(err)
}
var entities cedar.Entities

ps := cedar.NewPolicySet()
ps.Store("policy0", &policy)

var entities types.Entities
if err := json.Unmarshal([]byte(entitiesJSON), &entities); err != nil {
log.Fatal(err)
}
req := cedar.Request{
Principal: cedar.EntityUID{Type: "User", ID: "alice"},
Action: cedar.EntityUID{Type: "Action", ID: "view"},
Resource: cedar.EntityUID{Type: "Photo", ID: "VacationPhoto94.jpg"},
Context: cedar.Record{},
Principal: types.EntityUID{Type: "User", ID: "alice"},
Action: types.EntityUID{Type: "Action", ID: "view"},
Resource: types.EntityUID{Type: "Photo", ID: "VacationPhoto94.jpg"},
Context: types.Record{},
}

ok, _ := ps.IsAuthorized(entities, req)
fmt.Println(ok)
}
Expand Down Expand Up @@ -123,6 +129,30 @@ If you're looking to integrate Cedar into a production system, please be sure th
x/exp - code in this subrepository is not subject to the Go 1
compatibility promise.

While in development (0.x.y), each tagged release may contain breaking changes.

## Change log

### New features in 0.2.x

- A programmatic AST is now available in the `ast` package.
- Policy sets can be marshaled and unmarshaled from JSON.
- Policies can also be marshaled to Cedar text.

### Upgrading from 0.1.x to 0.2.x

- The Cedar value types have moved from the `cedar` package to the `types` package.
- The PolicyIDs are now `strings`, previously they were numeric.
- Errors and reasons use the new `PolicyID` form.
- Combining multiple parsed Cedar files now involves coming up with IDs for each
statement in those files. It's best to create an empty `NewPolicySet` then
parse individual files using `NewPolicyListFromBytes` and subsequently use
`PolicySet.Store` to add each of the policy statements.
- The Cedar `Entity` and `Entities` types have moved from the `cedar` package to the `types` package.
- Stronger typing is being used in many places.
- The `Value` method `Cedar() string` was changed to `MarshalCedar() []byte`


## Security

See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
Expand Down
47 changes: 47 additions & 0 deletions ast/annotation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package ast

import (
"github.com/cedar-policy/cedar-go/internal/ast"
"github.com/cedar-policy/cedar-go/types"
)

type Annotations ast.Annotations

func (a *Annotations) unwrap() *ast.Annotations {
return (*ast.Annotations)(a)
}

func wrapAnnotations(a *ast.Annotations) *Annotations {
return (*Annotations)(a)
}

// Annotation allows AST constructors to make policy in a similar shape to textual Cedar with
// annotations appearing before the actual policy scope:
//
// ast := Annotation("foo", "bar").
// Annotation("baz", "quux").
// Permit().
// PrincipalEq(superUser)
func Annotation(key types.Ident, value types.String) *Annotations {
return wrapAnnotations(ast.Annotation(key, value))
}

// Annotation adds an annotation. If a previous annotation exists with the same key, this builder will replace it.
func (a *Annotations) Annotation(key types.Ident, value types.String) *Annotations {
return wrapAnnotations(a.unwrap().Annotation(key, value))
}

// Permit begins a permit policy from the given annotations.
func (a *Annotations) Permit() *Policy {
return wrapPolicy(a.unwrap().Permit())
}

// Forbid begins a forbid policy from the given annotations.
func (a *Annotations) Forbid() *Policy {
return wrapPolicy(a.unwrap().Forbid())
}

// If a previous annotation exists with the same key, this builder will replace it.
func (p *Policy) Annotate(key types.Ident, value types.String) *Policy {
return wrapPolicy(p.unwrap().Annotate(key, value))
}
Loading

0 comments on commit 17b4d78

Please sign in to comment.