mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-05-27 23:08:10 +02:00
102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
package authorization
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
|
|
middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
|
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
|
)
|
|
|
|
type RuleSet interface {
|
|
MatchesRequest(req *http.Request) middlewareapi.AuthorizationPolicy
|
|
}
|
|
|
|
type rule struct {
|
|
conditions []condition
|
|
policy middlewareapi.AuthorizationPolicy
|
|
}
|
|
|
|
func (r rule) matches(req *http.Request) middlewareapi.AuthorizationPolicy {
|
|
for _, condition := range r.conditions {
|
|
if !condition.matches(req) {
|
|
// One of the conditions didn't match so this rule does not apply
|
|
return middlewareapi.OmittedPolicy
|
|
}
|
|
}
|
|
// If all conditions match, return the configured rule policy
|
|
return r.policy
|
|
}
|
|
|
|
func newRule(authRule options.AuthorizationRule, getClientIPFunc func(*http.Request) net.IP) (rule, error) {
|
|
// This function should add the conditions in order of complexity, least complex first
|
|
conditions := []condition{}
|
|
|
|
if len(authRule.Methods) > 0 {
|
|
conditions = append(conditions, newMethodCondition(authRule.Methods))
|
|
}
|
|
|
|
if len(authRule.Path) > 0 {
|
|
condition, err := newPathCondition(authRule.Path)
|
|
if err != nil {
|
|
return rule{}, err
|
|
}
|
|
conditions = append(conditions, condition)
|
|
}
|
|
|
|
if len(authRule.IPs) > 0 {
|
|
condition, err := newIPCondition(authRule.IPs, getClientIPFunc)
|
|
if err != nil {
|
|
return rule{}, err
|
|
}
|
|
conditions = append(conditions, condition)
|
|
}
|
|
|
|
var policy middlewareapi.AuthorizationPolicy
|
|
switch authRule.Policy {
|
|
case options.AllowPolicy:
|
|
policy = middlewareapi.AllowPolicy
|
|
case options.DelegatePolicy:
|
|
policy = middlewareapi.DelegatePolicy
|
|
case options.DenyPolicy:
|
|
policy = middlewareapi.DenyPolicy
|
|
default:
|
|
// This shouldn't be the case and should be prevented by validation
|
|
policy = middlewareapi.OmittedPolicy
|
|
}
|
|
|
|
return rule{
|
|
conditions: conditions,
|
|
policy: policy,
|
|
}, nil
|
|
}
|
|
|
|
type ruleSet struct {
|
|
rules []rule
|
|
}
|
|
|
|
func (r ruleSet) MatchesRequest(req *http.Request) middlewareapi.AuthorizationPolicy {
|
|
for _, rule := range r.rules {
|
|
if policy := rule.matches(req); policy != middlewareapi.OmittedPolicy {
|
|
// The rule applies to this request, return its policy
|
|
return policy
|
|
}
|
|
}
|
|
// No rules matched
|
|
return middlewareapi.OmittedPolicy
|
|
}
|
|
|
|
func NewRuleSet(requestRules []options.AuthorizationRule, getClientIPFunc func(*http.Request) net.IP) (RuleSet, error) {
|
|
rules := []rule{}
|
|
for _, requestRule := range requestRules {
|
|
r, err := newRule(requestRule, getClientIPFunc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rules = append(rules, r)
|
|
}
|
|
return ruleSet{
|
|
rules: rules,
|
|
}, nil
|
|
}
|