Skip to content

Commit

Permalink
feat: add Oathkeeper gRPC middleware
Browse files Browse the repository at this point in the history
This adds a gRPC middleware that encapuslates the
Oathkeeper logic.

Matching on gRPC traffic now happens in its own rule.
To match against gRPC traffic, you can use `Authority`
and `FullMethod` instead of `URL` and `Methods`.

Co-authored-by: Patrik <zepatrik@users.noreply.github.com>
  • Loading branch information
2 people authored and aeneasr committed Sep 14, 2022
1 parent c3c5854 commit 210aa5e
Show file tree
Hide file tree
Showing 36 changed files with 939 additions and 117 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -5,3 +5,4 @@ node_modules/
LICENSE.txt
dev
dist/
oathkeeper
2 changes: 1 addition & 1 deletion api/decision.go
Expand Up @@ -100,7 +100,7 @@ func (h *DecisionHandler) decisions(w http.ResponseWriter, r *http.Request) {
fields["subject"] = sess.Subject
}

rl, err := h.r.RuleMatcher().Match(r.Context(), r.Method, r.URL)
rl, err := h.r.RuleMatcher().Match(r.Context(), r.Method, r.URL, rule.ProtocolHTTP)
if err != nil {
h.r.Logger().WithError(err).
WithFields(fields).
Expand Down
16 changes: 8 additions & 8 deletions api/decision_test.go
Expand Up @@ -25,7 +25,7 @@ import (
"context"
"crypto/tls"
"fmt"
"io/ioutil"
"io"
"net/http"
"net/http/httptest"
"net/url"
Expand All @@ -39,13 +39,14 @@ import (
"github.com/urfave/negroni"

"github.com/ory/herodot"
"github.com/ory/x/logrusx"

"github.com/ory/oathkeeper/api"
"github.com/ory/oathkeeper/driver/configuration"
"github.com/ory/oathkeeper/internal"
"github.com/ory/oathkeeper/pipeline/authn"
"github.com/ory/oathkeeper/proxy"
"github.com/ory/oathkeeper/rule"
"github.com/ory/x/logrusx"
)

func TestDecisionAPI(t *testing.T) {
Expand Down Expand Up @@ -101,7 +102,6 @@ func TestDecisionAPI(t *testing.T) {
url string
code int
reqBody []byte
messages []string
rulesRegexp []rule.Rule
rulesGlob []rule.Rule
transform func(r *http.Request)
Expand Down Expand Up @@ -329,20 +329,20 @@ func TestDecisionAPI(t *testing.T) {
res, err := http.DefaultClient.Do(req)
require.NoError(t, err)

entireBody, err := ioutil.ReadAll(res.Body)
entireBody, err := io.ReadAll(res.Body)
require.NoError(t, err)
defer res.Body.Close()

assert.Equal(t, tc.authz, res.Header.Get("Authorization"))
assert.Equal(t, tc.code, res.StatusCode)
assert.Equal(t, strconv.Itoa(len(entireBody)), res.Header.Get("Content-Length"))
}
t.Run("regexp", func(t *testing.T) {
t.Run("regexp", func(_ *testing.T) {
reg.RuleRepository().(*rule.RepositoryMemory).WithRules(tc.rulesRegexp)
testFunc(configuration.Regexp)
})
t.Run("glob", func(t *testing.T) {
reg.RuleRepository().(*rule.RepositoryMemory).WithRules(tc.rulesRegexp)
t.Run("glob", func(_ *testing.T) {
reg.RuleRepository().(*rule.RepositoryMemory).WithRules(tc.rulesGlob)
testFunc(configuration.Glob)
})
})
Expand All @@ -369,7 +369,7 @@ func (*decisionHandlerRegistryMock) Logger() *logrusx.Logger {
return logrusx.New("", "")
}

func (m *decisionHandlerRegistryMock) Match(ctx context.Context, method string, u *url.URL) (*rule.Rule, error) {
func (m *decisionHandlerRegistryMock) Match(ctx context.Context, method string, u *url.URL, _ rule.Protocol) (*rule.Rule, error) {
args := m.Called(ctx, method, u)
return args.Get(0).(*rule.Rule), args.Error(1)
}
Expand Down
29 changes: 12 additions & 17 deletions credentials/fetcher_default.go
Expand Up @@ -211,14 +211,13 @@ func (s *FetcherDefault) resolveAll(done chan struct{}, errs chan error, locatio

func (s *FetcherDefault) resolve(wg *sync.WaitGroup, errs chan error, location url.URL) {
defer wg.Done()
var reader io.Reader
var (
reader io.ReadCloser
err error
)

switch location.Scheme {
case "azblob":
fallthrough
case "gs":
fallthrough
case "s3":
case "azblob", "gs", "s3":
ctx := context.Background()
bucket, err := s.mux.OpenBucket(ctx, location.Scheme+"://"+location.Host)
if err != nil {
Expand All @@ -234,7 +233,7 @@ func (s *FetcherDefault) resolve(wg *sync.WaitGroup, errs chan error, location u
}
defer bucket.Close()

r, err := bucket.NewReader(ctx, location.Path[1:], nil)
reader, err = bucket.NewReader(ctx, location.Path[1:], nil)
if err != nil {
errs <- errors.WithStack(herodot.
ErrInternalServerError.
Expand All @@ -246,13 +245,10 @@ func (s *FetcherDefault) resolve(wg *sync.WaitGroup, errs chan error, location u
)
return
}
defer r.Close()
defer reader.Close()

reader = r
case "":
fallthrough
case "file":
f, err := os.Open(urlx.GetURLFilePath(&location))
case "", "file":
reader, err = os.Open(urlx.GetURLFilePath(&location))
if err != nil {
errs <- errors.WithStack(herodot.
ErrInternalServerError.
Expand All @@ -264,9 +260,8 @@ func (s *FetcherDefault) resolve(wg *sync.WaitGroup, errs chan error, location u
)
return
}
defer f.Close()
defer reader.Close()

reader = f
case "http", "https":
res, err := s.client.Get(location.String())
if err != nil {
Expand All @@ -280,7 +275,8 @@ func (s *FetcherDefault) resolve(wg *sync.WaitGroup, errs chan error, location u
)
return
}
defer res.Body.Close()
reader = res.Body
defer reader.Close()

if res.StatusCode < 200 || res.StatusCode >= 400 {
errs <- errors.WithStack(herodot.
Expand All @@ -294,7 +290,6 @@ func (s *FetcherDefault) resolve(wg *sync.WaitGroup, errs chan error, location u
return
}

reader = res.Body
default:
errs <- errors.WithStack(herodot.
ErrInternalServerError.
Expand Down
3 changes: 2 additions & 1 deletion credentials/fetcher_default_test.go
Expand Up @@ -13,9 +13,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ory/oathkeeper/x"
"github.com/ory/x/logrusx"

"github.com/ory/oathkeeper/x"

"github.com/ory/herodot"
"github.com/ory/x/urlx"

Expand Down
3 changes: 1 addition & 2 deletions driver/configuration/provider.go
Expand Up @@ -6,11 +6,10 @@ import (
"testing"
"time"

"github.com/rs/cors"
"github.com/ory/fosite"
"github.com/ory/x/configx"
"github.com/ory/x/tracing"

"github.com/rs/cors"
)

const (
Expand Down
9 changes: 5 additions & 4 deletions go.mod
@@ -1,3 +1,5 @@
go 1.19

module github.com/ory/oathkeeper

replace (
Expand All @@ -14,12 +16,12 @@ require (
github.com/auth0/go-jwt-middleware v1.0.1
github.com/aws/aws-sdk-go v1.34.28
github.com/blang/semver v3.5.1+incompatible
github.com/bxcodec/faker v2.0.1+incompatible
github.com/dgraph-io/ristretto v0.1.0
github.com/dlclark/regexp2 v1.2.0
github.com/form3tech-oss/jwt-go v3.2.2+incompatible
github.com/fsnotify/fsnotify v1.5.4
github.com/ghodss/yaml v1.0.0
github.com/go-faker/faker/v4 v4.0.0-beta.2
github.com/go-openapi/errors v0.20.3
github.com/go-openapi/runtime v0.24.1
github.com/go-openapi/strfmt v0.21.3
Expand All @@ -31,6 +33,7 @@ require (
github.com/gobwas/glob v0.2.3
github.com/golang-jwt/jwt/v4 v4.0.0
github.com/golang/gddo v0.0.0-20190904175337-72a348e765d2
github.com/golang/mock v1.6.0
github.com/google/go-replayers/httpreplay v1.1.1
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.4.2
Expand Down Expand Up @@ -73,6 +76,7 @@ require (
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
golang.org/x/tools v0.1.12
google.golang.org/api v0.84.0
google.golang.org/grpc v1.47.0
gopkg.in/square/go-jose.v2 v2.6.0
)

Expand Down Expand Up @@ -273,13 +277,10 @@ require (
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
google.golang.org/grpc v1.47.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/DataDog/dd-trace-go.v1 v1.39.0 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
)

go 1.19
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -239,8 +239,6 @@ github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA=
github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM=
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
Expand Down Expand Up @@ -510,6 +508,8 @@ github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2H
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
github.com/go-faker/faker/v4 v4.0.0-beta.2 h1:Vzw8jA3frTirLIK+OOcz68dSYhN5LcdbLXjYIBxfBGU=
github.com/go-faker/faker/v4 v4.0.0-beta.2/go.mod h1:uuNc0PSRxF8nMgjGrrrU4Nw5cF30Jc6Kd0/FUTTYbhg=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
Expand Down
31 changes: 17 additions & 14 deletions internal/httpclient/client/api/api_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions internal/httpclient/client/api/decisions_parameters.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 210aa5e

Please sign in to comment.