authorize: add authN validation, additional tests (#761)

Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
This commit is contained in:
Bobby DeSimone 2020-05-26 10:44:51 -07:00 committed by GitHub
parent 9d7ef85687
commit 829280c73c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 160 additions and 3 deletions

View file

@ -9,12 +9,16 @@ import (
"net/url"
"strings"
"testing"
"time"
envoy_service_auth_v2 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v2"
"github.com/stretchr/testify/assert"
"github.com/google/go-cmp/cmp"
"github.com/pomerium/pomerium/authorize/evaluator"
"github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/internal/cryptutil"
"github.com/pomerium/pomerium/internal/encoding/jws"
"github.com/stretchr/testify/assert"
"gopkg.in/square/go-jose.v2/jwt"
)
const certPEM = `
@ -148,3 +152,149 @@ func mustParseURL(str string) *url.URL {
}
return u
}
func TestAuthorize_Check(t *testing.T) {
// golden policy
p := config.Policy{
From: "http://test.example.com",
To: "http://localhost",
AllowedUsers: []string{"bob@example.com"},
}
err := p.Validate()
if err != nil {
t.Fatal(err)
}
ps := []config.Policy{p}
type user struct {
// Standard claims (as specified in RFC 7519).
jwt.Claims
// Pomerium claims (not standard claims)
Email string `json:"email"`
Groups []string `json:"groups,omitempty"`
User string `json:"user,omitempty"`
ImpersonateEmail string `json:"impersonate_email,omitempty"`
ImpersonateGroups []string `json:"impersonate_groups,omitempty"`
}
tests := []struct {
name string
ctx context.Context
sk string
inUser string
inExpiry time.Time
inIssuer string
inAudience string
in *envoy_service_auth_v2.CheckRequest
want string
wantErr bool
}{
{"good",
context.TODO(),
cryptutil.NewBase64Key(),
"bob@example.com",
time.Now().Add(1 * time.Hour),
"authN.example.com",
"test.example.com",
nil,
"OK",
false},
{"bad user, alice",
context.TODO(),
cryptutil.NewBase64Key(),
"alice@example.com",
time.Now().Add(1 * time.Hour),
"authN.example.com",
"test.example.com",
nil,
"Access Denied",
false},
{"expired",
context.TODO(),
cryptutil.NewBase64Key(),
"bob@example.com",
time.Now().Add(-1 * time.Hour),
"authN.example.com",
"test.example.com",
nil,
"Access Denied",
false},
{"bad audience",
context.TODO(),
cryptutil.NewBase64Key(),
"bob@example.com",
time.Now().Add(1 * time.Hour),
"authN.example.com",
"bad.example.com",
nil,
"Access Denied",
false},
{"bad issuer",
context.TODO(),
cryptutil.NewBase64Key(),
"bob@example.com",
time.Now().Add(1 * time.Hour),
"bad.example.com",
"test.example.com",
nil,
"OK",
false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var sa user
sa.Expiry = jwt.NewNumericDate(tt.inExpiry)
sa.IssuedAt = jwt.NewNumericDate(time.Now())
sa.NotBefore = jwt.NewNumericDate(time.Now())
sa.Email = tt.inUser
sa.Subject = sa.Email
sa.Issuer = tt.inIssuer
sa.Audience = jwt.Audience{tt.inAudience}
sharedKey := tt.sk
encoder, err := jws.NewHS256Signer([]byte(sharedKey), tt.inIssuer)
if err != nil {
t.Fatal(err)
}
raw, err := encoder.Marshal(sa)
if err != nil {
t.Fatal(err)
}
opts := config.Options{
Policies: ps,
CookieName: "_pomerium",
AuthenticateURL: mustParseURL("https://authN.example.com"),
SharedKey: sharedKey}
a, err := New(opts)
if err != nil {
t.Fatal(err)
}
in := &envoy_service_auth_v2.CheckRequest{
Attributes: &envoy_service_auth_v2.AttributeContext{
Request: &envoy_service_auth_v2.AttributeContext_Request{
Http: &envoy_service_auth_v2.AttributeContext_HttpRequest{
Id: "id-1234",
Method: "GET",
Headers: map[string]string{
"accept": "text/json",
"cookie": "_pomerium=" + string(raw),
},
Host: "test.example.com",
Scheme: "http",
Body: "BODY",
},
},
},
}
got, err := a.Check(tt.ctx, in)
if (err != nil) != tt.wantErr {
t.Errorf("Authorize.Check() error = %v, wantErr %v", err, tt.wantErr)
return
}
if diff := cmp.Diff(got.Status.GetMessage(), tt.want); diff != "" {
t.Errorf("Authorize.Check() = %v", diff)
}
})
}
}