mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-02 16:30:17 +02:00
ppl: add support for http_path and http_method (#2813)
* ppl: add support for http_path and http_method * fix import ordering
This commit is contained in:
parent
54ec88fb93
commit
2d04106e6d
13 changed files with 257 additions and 18 deletions
|
@ -32,6 +32,7 @@ type (
|
|||
}
|
||||
InputHTTP struct {
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Headers map[string][]string `json:"headers"`
|
||||
}
|
||||
InputSession struct {
|
||||
|
|
43
pkg/policy/criteria/http_method.go
Normal file
43
pkg/policy/criteria/http_method.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package criteria
|
||||
|
||||
import (
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/policy/parser"
|
||||
)
|
||||
|
||||
type httpMethodCriterion struct {
|
||||
g *Generator
|
||||
}
|
||||
|
||||
func (httpMethodCriterion) DataType() CriterionDataType {
|
||||
return CriterionDataTypeStringMatcher
|
||||
}
|
||||
|
||||
func (httpMethodCriterion) Name() string {
|
||||
return "http_method"
|
||||
}
|
||||
|
||||
func (c httpMethodCriterion) GenerateRule(_ string, data parser.Value) (*ast.Rule, []*ast.Rule, error) {
|
||||
var body ast.Body
|
||||
ref := ast.RefTerm(ast.VarTerm("input"), ast.VarTerm("http"), ast.VarTerm("method"))
|
||||
err := matchString(&body, ref, data)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
rule := NewCriterionRule(c.g, c.Name(),
|
||||
ReasonHTTPMethodOK, ReasonHTTPMethodUnauthorized,
|
||||
body)
|
||||
|
||||
return rule, nil, nil
|
||||
}
|
||||
|
||||
// HTTPMethod returns a Criterion which matches an HTTP method.
|
||||
func HTTPMethod(generator *Generator) Criterion {
|
||||
return httpMethodCriterion{g: generator}
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(HTTPMethod)
|
||||
}
|
32
pkg/policy/criteria/http_method_test.go
Normal file
32
pkg/policy/criteria/http_method_test.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package criteria
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHTTPMethod(t *testing.T) {
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
res, err := evaluate(t, `
|
||||
allow:
|
||||
and:
|
||||
- http_method:
|
||||
is: GET
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{Method: "GET"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonHTTPMethodOK}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
})
|
||||
t.Run("unauthorized", func(t *testing.T) {
|
||||
res, err := evaluate(t, `
|
||||
allow:
|
||||
and:
|
||||
- http_method:
|
||||
is: GET
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{Method: "POST"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonHTTPMethodUnauthorized}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
})
|
||||
}
|
43
pkg/policy/criteria/http_path.go
Normal file
43
pkg/policy/criteria/http_path.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package criteria
|
||||
|
||||
import (
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
|
||||
"github.com/pomerium/pomerium/pkg/policy/parser"
|
||||
)
|
||||
|
||||
type httpPathCriterion struct {
|
||||
g *Generator
|
||||
}
|
||||
|
||||
func (httpPathCriterion) DataType() CriterionDataType {
|
||||
return CriterionDataTypeStringMatcher
|
||||
}
|
||||
|
||||
func (httpPathCriterion) Name() string {
|
||||
return "http_path"
|
||||
}
|
||||
|
||||
func (c httpPathCriterion) GenerateRule(_ string, data parser.Value) (*ast.Rule, []*ast.Rule, error) {
|
||||
var body ast.Body
|
||||
ref := ast.RefTerm(ast.VarTerm("input"), ast.VarTerm("http"), ast.VarTerm("path"))
|
||||
err := matchString(&body, ref, data)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
rule := NewCriterionRule(c.g, c.Name(),
|
||||
ReasonHTTPPathOK, ReasonHTTPPathUnauthorized,
|
||||
body)
|
||||
|
||||
return rule, nil, nil
|
||||
}
|
||||
|
||||
// HTTPPath returns a Criterion which matches an HTTP path.
|
||||
func HTTPPath(generator *Generator) Criterion {
|
||||
return httpPathCriterion{g: generator}
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(HTTPPath)
|
||||
}
|
32
pkg/policy/criteria/http_path_test.go
Normal file
32
pkg/policy/criteria/http_path_test.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package criteria
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHTTPPath(t *testing.T) {
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
res, err := evaluate(t, `
|
||||
allow:
|
||||
and:
|
||||
- http_path:
|
||||
is: /test
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{Path: "/test"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{true, A{ReasonHTTPPathOK}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
})
|
||||
t.Run("unauthorized", func(t *testing.T) {
|
||||
res, err := evaluate(t, `
|
||||
allow:
|
||||
and:
|
||||
- http_path:
|
||||
is: /test
|
||||
`, []dataBrokerRecord{}, Input{HTTP: InputHTTP{Path: "/not-test"}})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, A{false, A{ReasonHTTPPathUnauthorized}, M{}}, res["allow"])
|
||||
require.Equal(t, A{false, A{}}, res["deny"])
|
||||
})
|
||||
}
|
|
@ -20,6 +20,10 @@ const (
|
|||
ReasonEmailUnauthorized = "email-unauthorized"
|
||||
ReasonGroupsOK = "groups-ok"
|
||||
ReasonGroupsUnauthorized = "groups-unauthorized"
|
||||
ReasonHTTPMethodOK = "http-method-ok"
|
||||
ReasonHTTPMethodUnauthorized = "http-method-unauthorized"
|
||||
ReasonHTTPPathOK = "http-path-ok"
|
||||
ReasonHTTPPathUnauthorized = "http-path-unauthorized"
|
||||
ReasonInvalidClientCertificate = "invalid-client-certificate"
|
||||
ReasonNonCORSRequest = "non-cors-request"
|
||||
ReasonNonPomeriumRoute = "non-pomerium-route"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue