Skip to content

Commit

Permalink
Merge pull request #12 from dotindustries/fix/move-auth-middleware-to…
Browse files Browse the repository at this point in the history
…-connect

fix: move auth middleware to connect
  • Loading branch information
nadilas authored Mar 28, 2024
2 parents 9a0c02e + 0f02039 commit 8a9fbe7
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 57 deletions.
48 changes: 35 additions & 13 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
on: [push, pull_request]
name: Test
jobs:
test:
unit-test:
strategy:
matrix:
# [1.15.x, 1.16.x]
go-version: [1.21.x]
# os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Install Go
uses: actions/setup-go@v3
uses: actions/setup-go@master
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v3
- name: Test
run: go test ./...
- name: Integration test
run: |
curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/4.2.0/hurl_4.2.0_amd64.deb
sudo apt update && sudo apt install ./hurl_4.2.0_amd64.deb
integration/run.sh
- name: Unit tests
run: go test -race ./...
integration-tests:
name: Integration tests
strategy:
matrix:
# [1.15.x, 1.16.x]
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
runs-on: ${{ matrix.os }}
services:
minio1:
image: quay.io/minio/minio
env:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: minio123
ports:
- 9000:9000
# todo: we also need to add our local code changed service to be built...
steps:
- name: Checkout
uses: actions/checkout@master
- name: Setup Go
uses: actions/setup-go@master
- name: Setup Node
uses: actions/setup-node@master
- name: Install bruno
run: npm install -g @usebruno/cli
- name: Run tests
run: cd integration && bru run --env local
50 changes: 33 additions & 17 deletions auth/validator.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
package auth

import (
"errors"
"connectrpc.com/connect"
"context"
"fmt"
unkey "github.com/WilfredAlmeida/unkey-go/features"
"github.com/labstack/echo/v4"
"strings"
)

const ContextKey = "auth"
const bearerAuthScheme = "Bearer "

func KeyValidator(key string, c echo.Context) (bool, error) {
if key == "" {
return false, errors.New("missing API key")
}
resp, err := unkey.KeyVerify(key)
if err != nil {
return false, err
}
if !resp.Valid {
return false, nil
}
var ApiKeyInterceptor = connect.UnaryInterceptorFunc(
func(next connect.UnaryFunc) connect.UnaryFunc {
return connect.UnaryFunc(func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
key := req.Header().Get(echo.HeaderAuthorization)
if key == "" {
key = req.Header().Get("X-Api-Key")
}
key = strings.TrimPrefix(key, bearerAuthScheme)
if key == "" {
return nil, connect.NewError(connect.CodeUnauthenticated, fmt.Errorf("missing API key"))
}

c.Set(ContextKey, resp)
return true, nil
}
resp, err := unkey.KeyVerify(key)
if err != nil {
return nil, err
}
if !resp.Valid {
return nil, connect.NewError(connect.CodeUnauthenticated, fmt.Errorf("invalid API key"))
}

// set auth context key
ctx = context.WithValue(ctx, ContextKey, resp)
res, err := next(ctx, req)
return res, err
})
},
)

func FromContext(c echo.Context) unkey.KeyVerifyResponse {
return c.Get(ContextKey).(unkey.KeyVerifyResponse)
func FromContext(ctx context.Context) unkey.KeyVerifyResponse {
return ctx.Value(ContextKey).(unkey.KeyVerifyResponse)
}
4 changes: 4 additions & 0 deletions cli/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func readGlobalConfig() {
var defaultConfig = &config{
Debug: false,
BackendAddr: "http://localhost:8000",
AuthEnabled: false,
}

// configInit must be called from the packages' init() func
Expand All @@ -47,7 +48,9 @@ type config struct {
ReverseProxyAddr string `mapstructure:"proxy" structs:"proxy" env:"MOAR_S3_PROXY_URL"`
BackendAddr string `mapstructure:"addr" structs:"addr" env:"MOAR_BACKEND_ADDR"`
Debug bool `mapstructure:"debug" structs:"debug" env:"MOAR_DEBUG"`
AuthEnabled bool `mapstructure:"auth_enabled" structs:"auth_enabled" env:"MOAR_AUTH_ENABLED"`

// sensitive
AccessToken string `mapstructure:"access_token" structs:"access_token" env:"MOAR_ACCESS_TOKEN" conform:"redact"`
}

Expand All @@ -58,6 +61,7 @@ func cliFlags() {
rootCmd.PersistentFlags().String("addr", defaultConfig.BackendAddr, "The backend service address")
rootCmd.PersistentFlags().StringP("proxy", "p", defaultConfig.ReverseProxyAddr, "The reverse proxy which is directed at the module storage.")
rootCmd.PersistentFlags().BoolP("debug", "d", defaultConfig.Debug, "Toggles whether debug logs are enabled")
rootCmd.PersistentFlags().Bool("auth_enabled", defaultConfig.AuthEnabled, "Whether the backend service should use authentication")
rootCmd.PersistentFlags().String("access_token", defaultConfig.AccessToken, "Access token")
}

Expand Down
13 changes: 7 additions & 6 deletions cli/cmd/up.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"connectrpc.com/connect"
"github.com/dotindustries/moar/auth"
"github.com/dotindustries/moar/moarpb/v1/v1connect"
"github.com/labstack/echo/v4"
Expand Down Expand Up @@ -66,13 +67,13 @@ var upCmd = &cobra.Command{
e.Use(nrecho.Middleware(app))
}

path, handler := v1connect.NewModuleRegistryServiceHandler(server)
var interceptors []connect.Interceptor
if GlobalConfig.AuthEnabled {
interceptors = append(interceptors, auth.ApiKeyInterceptor)
}
path, handler := v1connect.NewModuleRegistryServiceHandler(server, connect.WithInterceptors(interceptors...))
loggingHandler := handlers.CombinedLoggingHandler(os.Stdout, handler)
e.POST(path+"*", echo.WrapHandler(loggingHandler), middleware.KeyAuthWithConfig(middleware.KeyAuthConfig{
// Allow for both Authorization and X-Api-Key header
KeyLookup: "header:" + echo.HeaderAuthorization + ",header:X-Api-Key",
Validator: auth.KeyValidator,
}))
e.POST(path+"*", echo.WrapHandler(loggingHandler))
e.GET("/", func(c echo.Context) error {
return c.JSON(http.StatusOK, "I'm up")
})
Expand Down
21 changes: 21 additions & 0 deletions integration/Index.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
meta {
name: Index
type: http
seq: 1
}

get {
url: {{host}}
body: none
auth: none
}

assert {
res.status: 200
}

tests {
test("service is up", function() {
expect(res.status).to.equal(200);
});
}
28 changes: 28 additions & 0 deletions integration/Stats.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
meta {
name: Stats
type: http
seq: 2
}

get {
url: {{host}}/stats
body: none
auth: none
}

assert {
res.status: 200
}

tests {
test("success", function() {
expect(res.status).to.equal(200);
});

test("should get state data", function() {
const data = res.getBody();
expect(data.uptime).to.be.a('string');
expect(data.requestCount).to.be.a('number');
expect(data.statuses).to.be.a('object');
});
}
3 changes: 0 additions & 3 deletions integration/basic.hurl

This file was deleted.

5 changes: 5 additions & 0 deletions integration/bruno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"version": "1",
"name": "moar",
"type": "collection"
}
3 changes: 3 additions & 0 deletions integration/environments/local.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
vars {
host: http://localhost:8000
}
10 changes: 0 additions & 10 deletions integration/run.sh

This file was deleted.

5 changes: 0 additions & 5 deletions integration/test.sh

This file was deleted.

3 changes: 0 additions & 3 deletions integration/up.hurl

This file was deleted.

0 comments on commit 8a9fbe7

Please sign in to comment.