Skip to content

Commit

Permalink
fix: routing
Browse files Browse the repository at this point in the history
  • Loading branch information
gfyrag committed Sep 30, 2022
1 parent f944d52 commit 1505d4b
Show file tree
Hide file tree
Showing 14 changed files with 230 additions and 81 deletions.
8 changes: 2 additions & 6 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
"github.com/formancehq/auth/pkg/delegatedauth"
"github.com/formancehq/auth/pkg/oidc"
"github.com/formancehq/auth/pkg/storage/sqlstorage"
"github.com/gorilla/mux"
sharedhealth "github.com/numary/go-libs/sharedhealth/pkg"
"github.com/numary/go-libs/sharedlogging"
"github.com/numary/go-libs/sharedotlp/pkg/sharedotlptraces"
"github.com/pkg/errors"
Expand Down Expand Up @@ -134,10 +132,8 @@ var serveCmd = &cobra.Command{
api.Module(":8080", baseUrl),
oidc.Module(key, baseUrl, o.Clients...),
authorization.Module(),
fx.Invoke(func(router *mux.Router, healthController *sharedhealth.HealthController) {
router.Path("/_healthcheck").HandlerFunc(healthController.Check)
}),
sqlstorage.Module(viper.GetString(postgresUriFlag), viper.GetBool(debugFlag), key, o.Clients),
sqlstorage.Module(sqlstorage.KindPostgres, viper.GetString(postgresUriFlag),
viper.GetBool(debugFlag), key, o.Clients...),
delegatedauth.Module(),
fx.Invoke(func() {
sharedlogging.Infof("App started.")
Expand Down
10 changes: 6 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ services:
volumes:
- ./dex-config.yaml:/etc/dex/config.docker.yaml
- ./pkg/web:/app/web
network_mode: service:auth
ports:
- '5556:5556/tcp'
- '8080:8080/tcp'

postgres:
image: postgres:alpine
Expand All @@ -34,6 +36,7 @@ services:
build:
context: .
dockerfile: reflex.Dockerfile
network_mode: service:dex
healthcheck:
test: curl -s -f -k http://localhost:8080/_healthcheck > /dev/null || exit 1
interval: 3s
Expand All @@ -50,6 +53,7 @@ services:
- serve
environment:
# DEBUG: 1
CGO_ENABLED: 0
CONFIG: ./config.yaml
POSTGRES_URI: host=postgres user=auth password=auth dbname=auth port=5432 sslmode=disable
CAOS_OIDC_DEV: 1
Expand All @@ -63,12 +67,10 @@ services:
depends_on:
- postgres
- jaeger
- dex
volumes:
- .:/src
working_dir: /src
ports:
- '5556:5556/tcp'
- '8080:8080/tcp'

frontend:
image: node:alpine
Expand Down
4 changes: 2 additions & 2 deletions pkg/api/authorization/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import (

func Module() fx.Option {
return fx.Options(
fx.Invoke(func(router *mux.Router, o op.OpenIDProvider) error {
fx.Invoke(fx.Annotate(func(router *mux.Router, o op.OpenIDProvider) error {
return router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
route.Handler(
middleware(o)(route.GetHandler()),
)
return nil
})
}),
}, fx.ParamTags(`name:"prefixedRouter"`))),
)
}

Expand Down
21 changes: 5 additions & 16 deletions pkg/api/module.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,21 @@
package api

import (
"context"
"net/url"

"github.com/gorilla/mux"
"github.com/formancehq/auth/pkg/api/routing"
sharedhealth "github.com/numary/go-libs/sharedhealth/pkg"
"go.uber.org/fx"
)

func Module(addr string, baseUrl *url.URL) fx.Option {
return fx.Options(
sharedhealth.Module(),
sharedhealth.ProvideHealthCheck(delegatedOIDCServerAvailability),
fx.Provide(func(healthController *sharedhealth.HealthController) *mux.Router {
return NewRouter(baseUrl, healthController)
}),
routing.Module(addr, baseUrl),
fx.Invoke(
addClientRoutes,
addScopeRoutes,
addUserRoutes,
fx.Annotate(addClientRoutes, fx.ParamTags(``, `name:"prefixedRouter"`)),
fx.Annotate(addScopeRoutes, fx.ParamTags(``, `name:"prefixedRouter"`)),
fx.Annotate(addUserRoutes, fx.ParamTags(``, `name:"prefixedRouter"`)),
),
fx.Invoke(func(lc fx.Lifecycle, router *mux.Router) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
return StartServer(addr, router)
},
})
}),
)
}
25 changes: 0 additions & 25 deletions pkg/api/router.go

This file was deleted.

31 changes: 31 additions & 0 deletions pkg/api/routing/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package routing

import (
"context"
)

var contextKey = struct{}{}

type contextHolder struct {
port int
}

func NewContext(ctx context.Context) context.Context {
return context.WithValue(ctx, contextKey, &contextHolder{})
}

func setPort(ctx context.Context, port int) {
v := ctx.Value(contextKey)
if v == nil {
return
}
v.(*contextHolder).port = port
}

func ListeningPort(ctx context.Context) int {
v := ctx.Value(contextKey)
if v == nil {
return 0
}
return v.(*contextHolder).port
}
48 changes: 48 additions & 0 deletions pkg/api/routing/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package routing

import (
"context"
"net/http"
"net/url"

"github.com/gorilla/mux"
sharedhealth "github.com/numary/go-libs/sharedhealth/pkg"
"go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
"go.uber.org/fx"
)

func CreateRootRouter(baseUrl *url.URL, healthController *sharedhealth.HealthController) (*mux.Router, *mux.Router) {
rootRouter := mux.NewRouter()
rootRouter.Use(otelmux.Middleware("auth"))
rootRouter.Use(func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
handler.ServeHTTP(w, r)
})
})
rootRouter.Path("/_healthcheck").HandlerFunc(healthController.Check)

subRouter := rootRouter
if baseUrl.Path != "/" {
subRouter = subRouter.PathPrefix(baseUrl.Path).Subrouter()
subRouter.Path("/_healthcheck").HandlerFunc(healthController.Check)
}

return rootRouter, subRouter
}

func Module(addr string, baseUrl *url.URL) fx.Option {
return fx.Options(
sharedhealth.Module(),
fx.Provide(fx.Annotate(func(healthController *sharedhealth.HealthController) (*mux.Router, *mux.Router) {
return CreateRootRouter(baseUrl, healthController)
}, fx.ResultTags(`name:"rootRouter"`, `name:"prefixedRouter"`))),
fx.Invoke(fx.Annotate(func(lc fx.Lifecycle, router *mux.Router, healthController *sharedhealth.HealthController) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
return StartServer(ctx, addr, router)
},
})
}, fx.ParamTags(``, `name:"rootRouter"`))),
)
}
64 changes: 64 additions & 0 deletions pkg/api/routing/module_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package routing

import (
"context"
"fmt"
"net/http"
"net/url"
"testing"

"github.com/gorilla/mux"
"github.com/stretchr/testify/require"
"go.uber.org/fx"
)

func testWithUrl(t *testing.T, urlStr string) {
u, err := url.Parse(urlStr)
require.NoError(t, err)

ctx := NewContext(context.Background())

app := fx.New(
fx.Invoke(fx.Annotate(func(router *mux.Router) {
router.Path("/subpath-with-prefix").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
}, fx.ParamTags(`name:"prefixedRouter"`))),
fx.Invoke(fx.Annotate(func(router *mux.Router) {
router.Path("/subpath-to-root").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
}, fx.ParamTags(`name:"rootRouter"`))),
Module(":0", u),
fx.NopLogger,
)

require.NoError(t, app.Start(ctx))
defer func() {
require.NoError(t, app.Stop(ctx))
}()

serverUrl := fmt.Sprintf("http://localhost:%d", ListeningPort(ctx))
serverUrlWithPath := fmt.Sprintf("%s%s", serverUrl, u.Path)

rsp, err := http.Get(fmt.Sprintf("%s/_healthcheck", serverUrlWithPath))
require.NoError(t, err)
require.Equal(t, http.StatusOK, rsp.StatusCode)

rsp, err = http.Get(fmt.Sprintf("%s/_healthcheck", serverUrl))
require.NoError(t, err)
require.Equal(t, http.StatusOK, rsp.StatusCode)

rsp, err = http.Get(fmt.Sprintf("%s/subpath-with-prefix", serverUrlWithPath))
require.NoError(t, err)
require.Equal(t, http.StatusNoContent, rsp.StatusCode)

rsp, err = http.Get(fmt.Sprintf("%s/subpath-to-root", serverUrl))
require.NoError(t, err)
require.Equal(t, http.StatusNoContent, rsp.StatusCode)
}

func TestModule(t *testing.T) {
testWithUrl(t, "http://localhost")
testWithUrl(t, "http://localhost/any/sub/path")
}
29 changes: 29 additions & 0 deletions pkg/api/routing/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package routing

import (
"context"
"net"
"net/http"
)

func StartServer(ctx context.Context, addr string, handler http.Handler) error {
socket, err := net.Listen("tcp", addr)
if err != nil {
return err
}

tcpAddr, err := net.ResolveTCPAddr(socket.Addr().Network(), socket.Addr().String())
if err != nil {
panic(err)
}

setPort(ctx, tcpAddr.Port)

go func() {
err := http.Serve(socket, handler)
if err != nil {
panic(err)
}
}()
return nil
}
20 changes: 0 additions & 20 deletions pkg/api/server.go

This file was deleted.

4 changes: 2 additions & 2 deletions pkg/oidc/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import (

func Module(privateKey *rsa.PrivateKey, baseUrl *url.URL, staticClients ...auth.StaticClient) fx.Option {
return fx.Options(
fx.Invoke(func(router *mux.Router, provider op.OpenIDProvider, storage Storage, relyingParty rp.RelyingParty) {
fx.Invoke(fx.Annotate(func(router *mux.Router, provider op.OpenIDProvider, storage Storage, relyingParty rp.RelyingParty) {
AddRoutes(router, provider, storage, relyingParty, baseUrl)
}),
}, fx.ParamTags(`name:"rootRouter"`))),
fx.Provide(fx.Annotate(func(storage Storage, relyingParty rp.RelyingParty) *storageFacade {
return NewStorageFacade(storage, relyingParty, privateKey, staticClients...)
}, fx.As(new(op.Storage)))),
Expand Down
22 changes: 18 additions & 4 deletions pkg/storage/sqlstorage/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import (
"gorm.io/gorm/logger"
)

const (
KindPostgres = "postgres"
)

// TODO: Replace by sharedlogging
func newLogger(debug bool) logger.Interface {
out := io.Discard
Expand Down Expand Up @@ -54,11 +58,18 @@ func MigrateTables(ctx context.Context, db *gorm.DB) error {
)
}

func gormModule(uri string, debug bool) fx.Option {
var drivers = map[string]func(string) gorm.Dialector{}

func registerDriverConstructor(kind string, constructor func(string) gorm.Dialector) {
drivers[kind] = constructor
}

func init() {
registerDriverConstructor(KindPostgres, OpenPostgresDatabase)
}

func gormModule(kind, uri string, debug bool) fx.Option {
return fx.Options(
fx.Provide(func() gorm.Dialector {
return OpenPostgresDatabase(uri)
}),
fx.Provide(func(d gorm.Dialector) (*gorm.DB, error) {
return LoadGorm(d, debug)
}),
Expand All @@ -70,5 +81,8 @@ func gormModule(uri string, debug bool) fx.Option {
},
})
}),
fx.Provide(func() gorm.Dialector {
return drivers[kind](uri)
}),
)
}
Loading

0 comments on commit 1505d4b

Please sign in to comment.