Skip to content

Commit

Permalink
Merge 05562a5 into 5892158
Browse files Browse the repository at this point in the history
  • Loading branch information
leplatrem committed Nov 10, 2017
2 parents 5892158 + 05562a5 commit c77e511
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
15 changes: 15 additions & 0 deletions auditlogger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ladon

// AuditLogger tracks denied and granted authorizations.
type AuditLogger interface {
OnDeniedAuthorization(request *Request, pool Policies, deciders Policies)
OnGrantedAuthorization(request *Request, pool Policies, deciders Policies)
}

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

func (*AuditLoggerNoOp) OnDeniedAuthorization(r *Request, p Policies, d Policies) {}
func (*AuditLoggerNoOp) OnGrantedAuthorization(r *Request, p Policies, d Policies) {}

var DefaultAuditLogger = &AuditLoggerNoOp{}
37 changes: 37 additions & 0 deletions auditlogger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ladon_test

import (
"testing"

. "github.com/ory/ladon"
. "github.com/ory/ladon/manager/memory"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

type MockAuditLogger struct {
mock.Mock
}

func (v *MockAuditLogger) OnDeniedAuthorization(r *Request, p Policies, d Policies) {
v.Called(r, p, d)
}

func (v *MockAuditLogger) OnGrantedAuthorization(r *Request, p Policies, d Policies) {
v.Called(r, p, d)
}

func TestAuditLogger(t *testing.T) {
auditLogger := &MockAuditLogger{}
auditLogger.On("OnDeniedAuthorization", mock.Anything, mock.Anything, mock.Anything)

warden := &Ladon{
Manager: NewMemoryManager(),
AuditLogger: auditLogger,
}

r := &Request{}
assert.NotNil(t, warden.IsAllowed(r))

auditLogger.AssertCalled(t, "OnDeniedAuthorization", r, Policies{}, Policies{})
}
27 changes: 25 additions & 2 deletions ladon.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import (

// Ladon is an implementation of Warden.
type Ladon struct {
Manager Manager
Matcher matcher
Manager Manager
Matcher matcher
AuditLogger AuditLogger
}

func (l *Ladon) matcher() matcher {
Expand All @@ -31,6 +32,13 @@ func (l *Ladon) matcher() matcher {
return l.Matcher
}

func (l *Ladon) auditLogger() AuditLogger {
if l.AuditLogger == nil {
l.AuditLogger = DefaultAuditLogger
}
return l.AuditLogger
}

// IsAllowed returns nil if subject s has permission p on resource r with context c or an error otherwise.
func (l *Ladon) IsAllowed(r *Request) (err error) {
policies, err := l.Manager.FindRequestCandidates(r)
Expand All @@ -48,13 +56,23 @@ func (l *Ladon) IsAllowed(r *Request) (err error) {
// The IsAllowed interface should be preferred since it uses the manager directly. This is a lower level interface for when you don't want to use the ladon manager.
func (l *Ladon) DoPoliciesAllow(r *Request, policies []Policy) (err error) {
var allowed = false
var deciders = Policies{}

defer func() {
if allowed {
l.auditLogger().OnGrantedAuthorization(r, policies, deciders)
} else {
l.auditLogger().OnDeniedAuthorization(r, policies, deciders)
}
}()

// Iterate through all policies
for _, p := range policies {
// Does the action match with one of the policies?
// This is the first check because usually actions are a superset of get|update|delete|set
// and thus match faster.
if pm, err := l.matcher().Matches(p, p.GetActions(), r.Action); err != nil {
deciders = append(deciders, p)
return errors.WithStack(err)
} else if !pm {
// no, continue to next policy
Expand All @@ -65,6 +83,7 @@ func (l *Ladon) DoPoliciesAllow(r *Request, policies []Policy) (err error) {
// There are usually less subjects than resources which is why this is checked
// before checking for resources.
if sm, err := l.matcher().Matches(p, p.GetSubjects(), r.Subject); err != nil {
deciders = append(deciders, p)
return err
} else if !sm {
// no, continue to next policy
Expand All @@ -73,6 +92,7 @@ func (l *Ladon) DoPoliciesAllow(r *Request, policies []Policy) (err error) {

// Does the resource match with one of the policies?
if rm, err := l.matcher().Matches(p, p.GetResources(), r.Resource); err != nil {
deciders = append(deciders, p)
return errors.WithStack(err)
} else if !rm {
// no, continue to next policy
Expand All @@ -88,9 +108,12 @@ func (l *Ladon) DoPoliciesAllow(r *Request, policies []Policy) (err error) {

// Is the policies effect deny? If yes, this overrides all allow policies -> access denied.
if !p.AllowAccess() {
deciders = append(deciders, p)
return errors.WithStack(ErrRequestForcefullyDenied)
}

allowed = true
deciders = append(deciders, p)
}

if !allowed {
Expand Down

0 comments on commit c77e511

Please sign in to comment.