Skip to content

Commit

Permalink
Merge 9c6c8a8 into 4334cd7
Browse files Browse the repository at this point in the history
  • Loading branch information
RafPe committed Dec 27, 2019
2 parents 4334cd7 + 9c6c8a8 commit 6eddf96
Showing 1 changed file with 47 additions and 16 deletions.
63 changes: 47 additions & 16 deletions ladon.go
Expand Up @@ -24,11 +24,20 @@ import (
"github.com/pkg/errors"
)

// Metric is used to expose metrics about authz
type Metric interface {
RequestDeniedBy(Request, Policy)
RequestAllowedBy(Request, Policies)
RequestNoMatch(Request)
RequestProcessingError(Request, Policy, error)
}

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

func (l *Ladon) matcher() matcher {
Expand All @@ -49,6 +58,7 @@ func (l *Ladon) auditLogger() AuditLogger {
func (l *Ladon) IsAllowed(r *Request) (err error) {
policies, err := l.Manager.FindRequestCandidates(r)
if err != nil {
go l.Metric.RequestProcessingError(*r, nil, err)
return err
}

Expand All @@ -66,57 +76,78 @@ func (l *Ladon) DoPoliciesAllow(r *Request, policies []Policy) (err error) {

// 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 {
return errors.WithStack(err)
} else if !pm {
// no, continue to next policy
continue
}

// Does the subject match with one of the policies?
// 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 {
if l.Metric != nil {
go l.Metric.RequestProcessingError(*r, p, err)
}
return err
} else if !sm {
// no, continue to next policy
continue
}

// Does the resource match with one of the policies?
if rm, err := l.matcher().Matches(p, p.GetResources(), r.Resource); err != nil {
// 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 {
if l.Metric != nil {
go l.Metric.RequestProcessingError(*r, p, err)
}
return errors.WithStack(err)
} else if !rm {
} else if !pm {
// no, continue to next policy
continue
}

// Are the policies conditions met?
// This is checked first because it usually has a small complexity.
if !l.passesConditions(p, r) {
// Does the resource match with one of the policies?
if rm, err := l.matcher().Matches(p, p.GetResources(), r.Resource); err != nil {
if l.Metric != nil {
go l.Metric.RequestProcessingError(*r, p, err)
}
return errors.WithStack(err)
} else if !rm {
// no, continue to next policy
continue
}

// Is the policies effect deny? If yes, this overrides all allow policies -> access denied.
// Is the policies effect deny? If yes, this overrides all allow policies
if !p.AllowAccess() {
deciders = append(deciders, p)
l.auditLogger().LogRejectedAccessRequest(r, policies, deciders)
if l.Metric != nil {
go l.Metric.RequestDeniedBy(*r, p)
}
return errors.WithStack(ErrRequestForcefullyDenied)
}

// Are the policies conditions met?
// This is checked first because it usually has a small complexity.
if !l.passesConditions(p, r) {
// no, continue to next policy
continue
}

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

if !allowed {
if l.Metric != nil {
go l.Metric.RequestNoMatch(*r)
}

l.auditLogger().LogRejectedAccessRequest(r, policies, deciders)
return errors.WithStack(ErrRequestDenied)
}

if l.Metric != nil {
l.Metric.RequestAllowedBy(*r, deciders)
}

l.auditLogger().LogGrantedAccessRequest(r, policies, deciders)
return nil
}
Expand Down

0 comments on commit 6eddf96

Please sign in to comment.