Commit 3f54e2f
Changed files (8)
pkg
pkg/authz/cedar.go
@@ -1,53 +1,26 @@
package authz
import (
- "encoding/json"
- "fmt"
- "net"
"net/http"
- "os"
cedar "github.com/cedar-policy/cedar-go"
- "github.com/cedar-policy/cedar-go/types"
- "github.com/xlgmokha/x/pkg/x"
- xlog "gitlab.com/mokhax/spike/pkg/log"
+ "gitlab.com/mokhax/spike/pkg/policies"
)
func WithCedar() Authorizer {
- var policy cedar.Policy
- x.Check(policy.UnmarshalCedar(x.Must(os.ReadFile("cedar.conf"))))
-
- policies := cedar.NewPolicySet()
- policies.Add("cedar.conf", &policy)
-
- var entities cedar.EntityMap
- if err := json.Unmarshal(x.Must(os.ReadFile("cedar.json")), &entities); err != nil {
- xlog.Logger.Error("Error", "error", err)
- return nil
- }
-
return AuthorizerFunc(func(r *http.Request) bool {
- host, _, err := net.SplitHostPort(r.Host)
- if err != nil {
- return false
- }
-
subject, found := TokenFrom(r).Subject()
if !found {
subject = "*"
}
- req := cedar.Request{
+ return policies.Allowed(cedar.Request{
Principal: cedar.NewEntityUID("Subject", cedar.String(subject)),
Action: cedar.NewEntityUID("Action", cedar.String(r.Method)),
Resource: cedar.NewEntityUID("Path", cedar.String(r.URL.Path)),
Context: cedar.NewRecord(cedar.RecordMap{
- "Host": cedar.String(host),
+ "Host": cedar.String(r.Host),
}),
- }
-
- ok, diagnostic := policies.IsAuthorized(entities, req)
- fmt.Printf("%v: %v -> %v %v%v %v\n", ok, subject, r.Method, host, r.URL.Path, diagnostic.Reasons)
- return ok == types.Allow
+ })
})
}
pkg/policies/entities.json
@@ -0,0 +1,47 @@
+[
+ {
+ "uid": {
+ "type": "User",
+ "id": "alice"
+ },
+ "attrs": {
+ "age": 18
+ },
+ "parents": []
+ },
+ {
+ "uid": {
+ "type": "Photo",
+ "id": "VacationPhoto94.jpg"
+ },
+ "attrs": {},
+ "parents": [
+ {
+ "type": "Album",
+ "id": "jane_vacation"
+ }
+ ]
+ },
+ {
+ "uid": {
+ "type": "User",
+ "id": "1"
+ }
+ },
+ {
+ "uid": {
+ "type": "Project",
+ "id": "3"
+ },
+ "parents": [
+ {
+ "type": "Group",
+ "id": "3"
+ },
+ {
+ "type": "Path",
+ "id": "/projects.json"
+ }
+ ]
+ }
+]
pkg/policies/init.go
@@ -3,33 +3,21 @@ package policies
import (
"embed"
_ "embed"
- "encoding/json"
+ "fmt"
"io/fs"
"log"
+ "strings"
"github.com/cedar-policy/cedar-go"
"github.com/cedar-policy/cedar-go/types"
- "github.com/xlgmokha/x/pkg/x"
xlog "gitlab.com/mokhax/spike/pkg/log"
)
-//go:embed *.cedar
+//go:embed *.cedar *.json
var files embed.FS
var All *cedar.PolicySet = cedar.NewPolicySet()
-
-const entitiesJSON = `[
- {
- "uid": { "type": "User", "id": "alice" },
- "attrs": { "age": 18 },
- "parents": []
- },
- {
- "uid": { "type": "Photo", "id": "VacationPhoto94.jpg" },
- "attrs": {},
- "parents": [{ "type": "Album", "id": "jane_vacation" }]
- }
-]`
+var Entities cedar.EntityMap = cedar.EntityMap{}
func init() {
err := fs.WalkDir(files, ".", func(path string, d fs.DirEntry, err error) error {
@@ -41,17 +29,30 @@ func init() {
return nil
}
- content, err := fs.ReadFile(files, path)
- if err != nil {
- return err
- }
+ if strings.HasSuffix(path, ".cedar") {
+ content, err := fs.ReadFile(files, path)
+ if err != nil {
+ return err
+ }
- var policy cedar.Policy
- if err := policy.UnmarshalCedar(content); err != nil {
- return err
+ policy := cedar.Policy{}
+ if err := policy.UnmarshalCedar(content); err != nil {
+ return err
+ }
+ policy.SetFilename(path)
+
+ All.Add(cedar.PolicyID(path), &policy)
+ } else if strings.HasSuffix(path, ".json") {
+ content, err := fs.ReadFile(files, path)
+ if err != nil {
+ return err
+ }
+
+ if err := Entities.UnmarshalJSON(content); err != nil {
+ return err
+ }
}
- All.Add(cedar.PolicyID(path), &policy)
return nil
})
@@ -61,10 +62,9 @@ func init() {
}
func Allowed(request cedar.Request) bool {
- var entities cedar.EntityMap
- x.Check(json.Unmarshal([]byte(entitiesJSON), &entities))
+ ok, diagnostic := All.IsAuthorized(Entities, request)
+ fmt.Printf("%v: %v -> %v %v%v\n", ok, request.Principal, request.Action, request.Context.Map(), request.Resource)
- ok, diagnostic := All.IsAuthorized(entities, request)
if len(diagnostic.Errors) > 0 {
for err := range diagnostic.Errors {
xlog.Default.Printf("%v\n", err)
pkg/policies/rest.cedar
@@ -0,0 +1,41 @@
+permit (
+ principal == Subject::"*",
+ action == Action::"GET",
+ resource in Path::"/projects.json"
+);
+
+permit (
+ principal == Subject::"gid://User/1",
+ action == Action::"GET",
+ resource in Path::"/*.json"
+);
+
+permit (
+ principal == Subject::"gid://User/1",
+ action == Action::"POST",
+ resource in Path::"/*.json"
+);
+
+permit (
+ principal == Subject::"gid://User/1",
+ action == Action::"PUT",
+ resource in Path::"/*.json"
+);
+
+permit (
+ principal == Subject::"gid://User/1",
+ action == Action::"PATCH",
+ resource in Path::"/*.json"
+);
+
+permit (
+ principal == Subject::"gid://User/1",
+ action == Action::"DELETE",
+ resource in Path::"/*.json"
+);
+
+permit (
+ principal == Subject::"gid://User/1",
+ action == Action::"HEAD",
+ resource in Path::"/*.json"
+);
pkg/rpc/ability_handler.go → pkg/rpc/ability_service.go
File renamed without changes
pkg/rpc/server_test.go
@@ -41,7 +41,7 @@ func TestServer(t *testing.T) {
assert.False(t, reply.Result)
})
- t.Run("returns true", func(t *testing.T) {
+ t.Run("returns true for alice:view:jane_vacation", func(t *testing.T) {
reply, err := client.Allowed(t.Context(), &AllowRequest{
Subject: "alice",
Permission: "view",
@@ -50,4 +50,14 @@ func TestServer(t *testing.T) {
require.NoError(t, err)
assert.True(t, reply.Result)
})
+
+ t.Run("returns gid://User/1:read_projects:gid://Organization/1", func(t *testing.T) {
+ reply, err := client.Allowed(t.Context(), &AllowRequest{
+ Subject: "gid://User/1",
+ Permission: "read_projects",
+ Resource: "gid://Organization/1",
+ })
+ require.NoError(t, err)
+ assert.True(t, reply.Result)
+ })
}
cedar.conf
@@ -1,5 +0,0 @@
-permit (
- principal == Subject::"*",
- action == Action::"GET",
- resource in Path::"/projects.json"
-);
cedar.json
@@ -1,24 +0,0 @@
-[
- {
- "uid": {
- "type": "User",
- "id": "*"
- }
- },
- {
- "uid": {
- "type": "Project",
- "id": "3"
- },
- "parents": [
- {
- "type": "Group",
- "id": "3"
- },
- {
- "type": "Path",
- "id": "/projects.json"
- }
- ]
- }
-]