Skip to content

Commit

Permalink
feat: add context.Context to interfaces (#163)
Browse files Browse the repository at this point in the history
Signed-off-by: Tabias Pittman <tabias.pittman@vensure.com>
  • Loading branch information
TabiasP authored Mar 5, 2024
1 parent 4efda1f commit 972387f
Show file tree
Hide file tree
Showing 27 changed files with 292 additions and 198 deletions.
6 changes: 4 additions & 2 deletions audit_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@

package ladon

import "context"

// AuditLogger tracks denied and granted authorizations.
type AuditLogger interface {
LogRejectedAccessRequest(request *Request, pool Policies, deciders Policies)
LogGrantedAccessRequest(request *Request, pool Policies, deciders Policies)
LogRejectedAccessRequest(ctx context.Context, request *Request, pool Policies, deciders Policies)
LogGrantedAccessRequest(ctx context.Context, request *Request, pool Policies, deciders Policies)
}
5 changes: 3 additions & 2 deletions audit_logger_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package ladon

import (
"context"
"log"
"os"
"strings"
Expand All @@ -38,7 +39,7 @@ func (a *AuditLoggerInfo) logger() *log.Logger {
return a.Logger
}

func (a *AuditLoggerInfo) LogRejectedAccessRequest(r *Request, p Policies, d Policies) {
func (a *AuditLoggerInfo) LogRejectedAccessRequest(ctx context.Context, r *Request, p Policies, d Policies) {
if len(d) > 1 {
allowed := joinPoliciesNames(d[0 : len(d)-1])
denied := d[len(d)-1].GetID()
Expand All @@ -51,7 +52,7 @@ func (a *AuditLoggerInfo) LogRejectedAccessRequest(r *Request, p Policies, d Pol
}
}

func (a *AuditLoggerInfo) LogGrantedAccessRequest(r *Request, p Policies, d Policies) {
func (a *AuditLoggerInfo) LogGrantedAccessRequest(ctx context.Context, r *Request, p Policies, d Policies) {
a.logger().Printf("policies %s allow access", joinPoliciesNames(d))
}

Expand Down
8 changes: 6 additions & 2 deletions audit_logger_noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@

package ladon

import "context"

// AuditLoggerNoOp is the default AuditLogger, that tracks nothing.
type AuditLoggerNoOp struct{}

func (*AuditLoggerNoOp) LogRejectedAccessRequest(r *Request, p Policies, d Policies) {}
func (*AuditLoggerNoOp) LogGrantedAccessRequest(r *Request, p Policies, d Policies) {}
func (*AuditLoggerNoOp) LogRejectedAccessRequest(ctx context.Context, r *Request, p Policies, d Policies) {
}
func (*AuditLoggerNoOp) LogGrantedAccessRequest(ctx context.Context, r *Request, p Policies, d Policies) {
}

var DefaultAuditLogger = &AuditLoggerNoOp{}
17 changes: 10 additions & 7 deletions audit_logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package ladon_test

import (
"bytes"
"context"
"log"
"testing"

Expand All @@ -41,21 +42,23 @@ func TestAuditLogger(t *testing.T) {
},
}

warden.Manager.Create(&DefaultPolicy{
ctx := context.Background()

warden.Manager.Create(ctx, &DefaultPolicy{
ID: "no-updates",
Subjects: []string{"<.*>"},
Actions: []string{"update"},
Resources: []string{"<.*>"},
Effect: DenyAccess,
})
warden.Manager.Create(&DefaultPolicy{
warden.Manager.Create(ctx, &DefaultPolicy{
ID: "yes-deletes",
Subjects: []string{"<.*>"},
Actions: []string{"delete"},
Resources: []string{"<.*>"},
Effect: AllowAccess,
})
warden.Manager.Create(&DefaultPolicy{
warden.Manager.Create(ctx, &DefaultPolicy{
ID: "no-bob",
Subjects: []string{"bob"},
Actions: []string{"delete"},
Expand All @@ -64,15 +67,15 @@ func TestAuditLogger(t *testing.T) {
})

r := &Request{}
assert.NotNil(t, warden.IsAllowed(r))
assert.NotNil(t, warden.IsAllowed(ctx, r))
assert.Equal(t, "no policy allowed access\n", output.String())

output.Reset()

r = &Request{
Action: "update",
}
assert.NotNil(t, warden.IsAllowed(r))
assert.NotNil(t, warden.IsAllowed(ctx, r))
assert.Equal(t, "policy no-updates forcefully denied the access\n", output.String())

output.Reset()
Expand All @@ -81,7 +84,7 @@ func TestAuditLogger(t *testing.T) {
Subject: "bob",
Action: "delete",
}
assert.NotNil(t, warden.IsAllowed(r))
assert.NotNil(t, warden.IsAllowed(ctx, r))
assert.Equal(t, "policies yes-deletes allow access, but policy no-bob forcefully denied it\n", output.String())

output.Reset()
Expand All @@ -90,6 +93,6 @@ func TestAuditLogger(t *testing.T) {
Subject: "alice",
Action: "delete",
}
assert.Nil(t, warden.IsAllowed(r))
assert.Nil(t, warden.IsAllowed(ctx, r))
assert.Equal(t, "policies yes-deletes allow access\n", output.String())
}
7 changes: 5 additions & 2 deletions benchmark_warden_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package ladon_test

import (
"context"
"fmt"
"strconv"
"testing"
Expand Down Expand Up @@ -50,16 +51,18 @@ func benchmarkLadon(i int, b *testing.B, warden *ladon.Ladon) {
// sem <- true
//}

ctx := context.Background()

for _, pol := range generatePolicies(i) {
if err := warden.Manager.Create(pol); err != nil {
if err := warden.Manager.Create(ctx, pol); err != nil {
b.Logf("Got error from warden.Manager.Create: %s", err)
}
}

b.ResetTimer()
var err error
for n := 0; n < b.N; n++ {
if err = warden.IsAllowed(&ladon.Request{
if err = warden.IsAllowed(ctx, &ladon.Request{
Subject: "5",
Action: "bar",
Resource: "baz",
Expand Down
5 changes: 3 additions & 2 deletions condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package ladon

import (
"context"
"encoding/json"

"github.com/pkg/errors"
Expand All @@ -32,7 +33,7 @@ type Condition interface {
GetName() string

// Fulfills returns true if the request is fulfilled by the condition.
Fulfills(interface{}, *Request) bool
Fulfills(context.Context, interface{}, *Request) bool
}

// Conditions is a collection of conditions.
Expand Down Expand Up @@ -129,6 +130,6 @@ var ConditionFactories = map[string]func() Condition{
return new(ResourceContainsCondition)
},
new(BooleanCondition).GetName(): func() Condition {
return new (BooleanCondition)
return new(BooleanCondition)
},
}
4 changes: 3 additions & 1 deletion condition_boolean.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ladon

import "context"

/*
BooleanCondition is used to determine if a boolean context matches an expected
boolean condition.
Expand All @@ -18,7 +20,7 @@ func (c *BooleanCondition) GetName() string {

// Fulfills determines if the BooleanCondition is fulfilled.
// The BooleanCondition is fulfilled if the provided boolean value matches the conditions boolean value.
func (c *BooleanCondition) Fulfills(value interface{}, _ *Request) bool {
func (c *BooleanCondition) Fulfills(ctx context.Context, value interface{}, _ *Request) bool {
val, ok := value.(bool)

return ok && val == c.BooleanValue
Expand Down
3 changes: 2 additions & 1 deletion condition_cidr.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package ladon

import (
"context"
"net"
)

Expand All @@ -30,7 +31,7 @@ type CIDRCondition struct {
}

// Fulfills returns true if the the request is fulfilled by the condition.
func (c *CIDRCondition) Fulfills(value interface{}, _ *Request) bool {
func (c *CIDRCondition) Fulfills(ctx context.Context, value interface{}, _ *Request) bool {
ips, ok := value.(string)
if !ok {
return false
Expand Down
3 changes: 2 additions & 1 deletion condition_cidr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package ladon

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -42,6 +43,6 @@ func TestCIDRMatch(t *testing.T) {
CIDR: c.cidr,
}

assert.Equal(t, c.pass, condition.Fulfills(c.ip, new(Request)), "%s; %s", c.ip, c.cidr)
assert.Equal(t, c.pass, condition.Fulfills(context.Background(), c.ip, new(Request)), "%s; %s", c.ip, c.cidr)
}
}
7 changes: 5 additions & 2 deletions condition_resource_contains.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@

package ladon

import "strings"
import (
"context"
"strings"
)

// ResourceContainsCondition is fulfilled if the context matches a substring within the resource name
type ResourceContainsCondition struct{}

// Fulfills returns true if the request's resouce contains the given value string
func (c *ResourceContainsCondition) Fulfills(value interface{}, r *Request) bool {
func (c *ResourceContainsCondition) Fulfills(ctx context.Context, value interface{}, r *Request) bool {

filter, ok := value.(map[string]interface{})
if !ok {
Expand Down
3 changes: 2 additions & 1 deletion condition_resource_contains_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
package ladon

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -82,7 +83,7 @@ func TestResourceContains(t *testing.T) {
}
resourceFilter["value"] = c.value

assert.Equal(t, c.pass, condition.Fulfills(resourceFilter, request), "%s", c.matches)
assert.Equal(t, c.pass, condition.Fulfills(context.Background(), resourceFilter, request), "%s", c.matches)
assert.Equal(t, condition.GetName(), "ResourceContainsCondition", "should be called ResourceContainsCondition")
}
}
4 changes: 3 additions & 1 deletion condition_string_equal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

package ladon

import "context"

// StringEqualCondition is a condition which is fulfilled if the given
// string value is the same as specified in StringEqualCondition
type StringEqualCondition struct {
Expand All @@ -28,7 +30,7 @@ type StringEqualCondition struct {

// Fulfills returns true if the given value is a string and is the
// same as in StringEqualCondition.Equals
func (c *StringEqualCondition) Fulfills(value interface{}, _ *Request) bool {
func (c *StringEqualCondition) Fulfills(ctx context.Context, value interface{}, _ *Request) bool {
s, ok := value.(string)

return ok && s == c.Equals
Expand Down
3 changes: 2 additions & 1 deletion condition_string_match.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package ladon

import (
"context"
"regexp"
)

Expand All @@ -32,7 +33,7 @@ type StringMatchCondition struct {

// Fulfills returns true if the given value is a string and matches the regex
// pattern in StringMatchCondition.Matches
func (c *StringMatchCondition) Fulfills(value interface{}, _ *Request) bool {
func (c *StringMatchCondition) Fulfills(ctx context.Context, value interface{}, _ *Request) bool {
s, ok := value.(string)

matches, _ := regexp.MatchString(c.Matches, s)
Expand Down
3 changes: 2 additions & 1 deletion condition_string_match_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package ladon

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -40,6 +41,6 @@ func TestStringMatch(t *testing.T) {
Matches: c.matches,
}

assert.Equal(t, c.pass, condition.Fulfills(c.value, new(Request)), "%s", c.matches)
assert.Equal(t, c.pass, condition.Fulfills(context.Background(), c.value, new(Request)), "%s", c.matches)
}
}
4 changes: 3 additions & 1 deletion condition_string_pairs_equal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@

package ladon

import "context"

// StringPairsEqualCondition is a condition which is fulfilled if the given
// array of pairs contains two-element string arrays where both elements
// in the string array are equal
type StringPairsEqualCondition struct{}

// Fulfills returns true if the given value is an array of string arrays and
// each string array has exactly two values which are equal
func (c *StringPairsEqualCondition) Fulfills(value interface{}, _ *Request) bool {
func (c *StringPairsEqualCondition) Fulfills(ctx context.Context, value interface{}, _ *Request) bool {
pairs, PairsOk := value.([]interface{})
if !PairsOk {
return false
Expand Down
3 changes: 2 additions & 1 deletion condition_string_pairs_equal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package ladon

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -43,6 +44,6 @@ func TestStringPairsEqualMatch(t *testing.T) {
} {
condition := &StringPairsEqualCondition{}

assert.Equal(t, c.pass, condition.Fulfills(c.pairs, new(Request)), "%s", c.pairs)
assert.Equal(t, c.pass, condition.Fulfills(context.Background(), c.pairs, new(Request)), "%s", c.pairs)
}
}
4 changes: 3 additions & 1 deletion condition_subject_equal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@

package ladon

import "context"

// EqualsSubjectCondition is a condition which is fulfilled if the request's subject is equal to the given value string
type EqualsSubjectCondition struct{}

// Fulfills returns true if the request's subject is equal to the given value string
func (c *EqualsSubjectCondition) Fulfills(value interface{}, r *Request) bool {
func (c *EqualsSubjectCondition) Fulfills(ctx context.Context, value interface{}, r *Request) bool {
s, ok := value.(string)

return ok && s == r.Subject
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.19

require (
github.com/dlclark/regexp2 v1.2.0
github.com/golang/mock v1.1.1
github.com/golang/mock v1.6.0
github.com/hashicorp/golang-lru v0.5.0
github.com/ory/pagination v0.0.1
github.com/pborman/uuid v1.2.0
Expand All @@ -16,5 +16,4 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519 // indirect
)
Loading

0 comments on commit 972387f

Please sign in to comment.