mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-03 11:22:45 +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
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/open-policy-agent/opa/rego"
|
||||
|
@ -35,11 +36,23 @@ type Request struct {
|
|||
// RequestHTTP is the HTTP field in the request.
|
||||
type RequestHTTP struct {
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
URL string `json:"url"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
ClientCertificate string `json:"client_certificate"`
|
||||
}
|
||||
|
||||
// NewRequestHTTP creates a new RequestHTTP.
|
||||
func NewRequestHTTP(method string, requestURL url.URL, headers map[string]string, rawClientCertificate string) RequestHTTP {
|
||||
return RequestHTTP{
|
||||
Method: method,
|
||||
Path: requestURL.Path,
|
||||
URL: requestURL.String(),
|
||||
Headers: headers,
|
||||
ClientCertificate: rawClientCertificate,
|
||||
}
|
||||
}
|
||||
|
||||
// RequestSession is the session field in the request.
|
||||
type RequestSession struct {
|
||||
ID string `json:"id"`
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||
"github.com/pomerium/pomerium/pkg/policy/criteria"
|
||||
"github.com/pomerium/pomerium/pkg/policy/parser"
|
||||
"github.com/pomerium/pomerium/pkg/protoutil"
|
||||
)
|
||||
|
||||
|
@ -86,6 +87,36 @@ func TestEvaluator(t *testing.T) {
|
|||
To: config.WeightedURLs{{URL: *mustParseURL("https://to9.example.com")}},
|
||||
AllowAnyAuthenticatedUser: true,
|
||||
},
|
||||
{
|
||||
To: config.WeightedURLs{{URL: *mustParseURL("https://to10.example.com")}},
|
||||
Policy: &config.PPLPolicy{
|
||||
Policy: &parser.Policy{
|
||||
Rules: []parser.Rule{{
|
||||
Action: parser.ActionAllow,
|
||||
Or: []parser.Criterion{{
|
||||
Name: "http_method", Data: parser.Object{
|
||||
"is": parser.String("GET"),
|
||||
},
|
||||
}},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
To: config.WeightedURLs{{URL: *mustParseURL("https://to11.example.com")}},
|
||||
Policy: &config.PPLPolicy{
|
||||
Policy: &parser.Policy{
|
||||
Rules: []parser.Rule{{
|
||||
Action: parser.ActionAllow,
|
||||
Or: []parser.Criterion{{
|
||||
Name: "http_path", Data: parser.Object{
|
||||
"is": parser.String("/test"),
|
||||
},
|
||||
}},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
options := []Option{
|
||||
WithAuthenticateURL("https://authn.example.com"),
|
||||
|
@ -442,6 +473,32 @@ func TestEvaluator(t *testing.T) {
|
|||
}
|
||||
}
|
||||
})
|
||||
t.Run("http method", func(t *testing.T) {
|
||||
res, err := eval(t, options, []proto.Message{}, &Request{
|
||||
Policy: &policies[9],
|
||||
HTTP: NewRequestHTTP(
|
||||
"GET",
|
||||
*mustParseURL("https://from.example.com/"),
|
||||
nil,
|
||||
testValidCert,
|
||||
),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, res.Allow.Value)
|
||||
})
|
||||
t.Run("http path", func(t *testing.T) {
|
||||
res, err := eval(t, options, []proto.Message{}, &Request{
|
||||
Policy: &policies[10],
|
||||
HTTP: NewRequestHTTP(
|
||||
"POST",
|
||||
*mustParseURL("https://from.example.com/test"),
|
||||
nil,
|
||||
testValidCert,
|
||||
),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, res.Allow.Value)
|
||||
})
|
||||
}
|
||||
|
||||
func mustParseURL(str string) *url.URL {
|
||||
|
|
|
@ -124,12 +124,12 @@ func (a *Authorize) getEvaluatorRequestFromCheckRequest(
|
|||
) (*evaluator.Request, error) {
|
||||
requestURL := getCheckRequestURL(in)
|
||||
req := &evaluator.Request{
|
||||
HTTP: evaluator.RequestHTTP{
|
||||
Method: in.GetAttributes().GetRequest().GetHttp().GetMethod(),
|
||||
URL: requestURL.String(),
|
||||
Headers: getCheckRequestHeaders(in),
|
||||
ClientCertificate: getPeerCertificate(in),
|
||||
},
|
||||
HTTP: evaluator.NewRequestHTTP(
|
||||
in.GetAttributes().GetRequest().GetHttp().GetMethod(),
|
||||
requestURL,
|
||||
getCheckRequestHeaders(in),
|
||||
getPeerCertificate(in),
|
||||
),
|
||||
}
|
||||
if sessionState != nil {
|
||||
req.Session = evaluator.RequestSession{
|
||||
|
|
|
@ -90,15 +90,15 @@ func Test_getEvaluatorRequest(t *testing.T) {
|
|||
Session: evaluator.RequestSession{
|
||||
ID: "SESSION_ID",
|
||||
},
|
||||
HTTP: evaluator.RequestHTTP{
|
||||
Method: "GET",
|
||||
URL: "http://example.com/some/path?qs=1",
|
||||
Headers: map[string]string{
|
||||
HTTP: evaluator.NewRequestHTTP(
|
||||
"GET",
|
||||
mustParseURL("http://example.com/some/path?qs=1"),
|
||||
map[string]string{
|
||||
"Accept": "text/html",
|
||||
"X-Forwarded-Proto": "https",
|
||||
},
|
||||
ClientCertificate: certPEM,
|
||||
},
|
||||
certPEM,
|
||||
),
|
||||
}
|
||||
assert.Equal(t, expect, actual)
|
||||
}
|
||||
|
@ -296,15 +296,15 @@ func Test_getEvaluatorRequestWithPortInHostHeader(t *testing.T) {
|
|||
expect := &evaluator.Request{
|
||||
Policy: &a.currentOptions.Load().Policies[0],
|
||||
Session: evaluator.RequestSession{},
|
||||
HTTP: evaluator.RequestHTTP{
|
||||
Method: "GET",
|
||||
URL: "http://example.com/some/path?qs=1",
|
||||
Headers: map[string]string{
|
||||
HTTP: evaluator.NewRequestHTTP(
|
||||
"GET",
|
||||
mustParseURL("http://example.com/some/path?qs=1"),
|
||||
map[string]string{
|
||||
"Accept": "text/html",
|
||||
"X-Forwarded-Proto": "https",
|
||||
},
|
||||
ClientCertificate: certPEM,
|
||||
},
|
||||
certPEM,
|
||||
),
|
||||
}
|
||||
assert.Equal(t, expect, actual)
|
||||
}
|
||||
|
@ -414,3 +414,11 @@ func TestAuthorize_Check(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mustParseURL(rawURL string) url.URL {
|
||||
u, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return *u
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue