Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
github.com/stretchr/testify v1.11.1
github.com/tinyauthapp/paerser v0.0.0-20260410140347-85c3740d6298
github.com/weppos/publicsuffix-go v0.50.3
go.uber.org/dig v1.19.0
golang.org/x/crypto v0.52.0
golang.org/x/oauth2 v0.36.0
golang.org/x/tools v0.45.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,8 @@ go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g=
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4=
go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
Expand Down
41 changes: 34 additions & 7 deletions internal/bootstrap/app_bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

"github.com/gin-gonic/gin"
"github.com/steveiliop56/ding"
"go.uber.org/dig"

"github.com/tinyauthapp/tinyauth/internal/model"
"github.com/tinyauthapp/tinyauth/internal/repository"
Expand Down Expand Up @@ -56,6 +57,7 @@ type BootstrapApp struct {
db *sql.DB
ding *ding.Ding
listeners []Listener
dig *dig.Container
}

func NewBootstrapApp(config model.Config) *BootstrapApp {
Expand All @@ -70,7 +72,11 @@ func (app *BootstrapApp) Setup() error {
app.ctx = ctx
app.cancel = cancel

// Create a ding instance
// create the dig container
c := dig.New()
app.dig = c

// create a ding instance
dg := ding.New(ctx)
app.ding = dg

Expand Down Expand Up @@ -157,12 +163,6 @@ func (app *BootstrapApp) Setup() error {
app.runtime.OAuthProviders[id] = provider
}

// setup oidc clients
for id, client := range app.config.OIDC.Clients {
client.ID = id
app.runtime.OIDCClients = append(app.runtime.OIDCClients, client)
}

// cookie domain
cookieDomainResolver := utils.GetCookieDomain

Expand Down Expand Up @@ -211,6 +211,33 @@ func (app *BootstrapApp) Setup() error {
// store
app.queries = store

// provide basic utilities to container
type utilityProvider struct {
dig.Out

Log *logger.Logger
Config *model.Config
Runtime *model.RuntimeConfig
Ding *ding.Ding
Ctx context.Context
Queries repository.Store
}

err = app.dig.Provide(func() utilityProvider {
return utilityProvider{
Log: app.log,
Config: &app.config,
Runtime: &app.runtime,
Ding: app.ding,
Ctx: app.ctx,
Queries: app.queries,
}
})

if err != nil {
return fmt.Errorf("failed to provide utilities to container: %w", err)
}

// services
err = app.setupServices()

Expand Down
96 changes: 80 additions & 16 deletions internal/bootstrap/router_bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/tinyauthapp/tinyauth/internal/controller"
"github.com/tinyauthapp/tinyauth/internal/middleware"
"github.com/tinyauthapp/tinyauth/internal/model"
"go.uber.org/dig"

"github.com/gin-gonic/gin"
)
Expand Down Expand Up @@ -40,31 +41,94 @@ func (app *BootstrapApp) setupRouter() error {
}
}

contextMiddleware := middleware.NewContextMiddleware(app.log, app.runtime, app.services.authService, app.services.oauthBrokerService, app.services.tailscaleService)
engine.Use(contextMiddleware.Middleware())
middlewareProvideFor := []any{
middleware.NewContextMiddleware,
middleware.NewUIMiddleware,
middleware.NewZerologMiddleware,
}

uiMiddleware, err := middleware.NewUIMiddleware()
for _, provider := range middlewareProvideFor {
err := app.dig.Provide(provider)

if err != nil {
return fmt.Errorf("failed to provide middleware: %w", err)
}
}

type middlewareInput struct {
dig.In

ContextMiddleware *middleware.ContextMiddleware
UIMiddleware *middleware.UIMiddleware
ZerologMiddleware *middleware.ZerologMiddleware
}

err := app.dig.Invoke(func(mi middlewareInput) {
engine.Use(mi.ContextMiddleware.Middleware())
engine.Use(mi.UIMiddleware.Middleware())
engine.Use(mi.ZerologMiddleware.Middleware())
})

if err != nil {
return fmt.Errorf("failed to initialize UI middleware: %w", err)
return fmt.Errorf("failed to invoke middleware: %w", err)
}

engine.Use(uiMiddleware.Middleware())
err = app.dig.Provide(func() *gin.RouterGroup {
return &engine.RouterGroup
}, dig.Name("mainRouterGroup"))

zerologMiddleware := middleware.NewZerologMiddleware(app.log)
if err != nil {
return fmt.Errorf("failed to provide main router group: %w", err)
}

engine.Use(zerologMiddleware.Middleware())
err = app.dig.Provide(func() *gin.RouterGroup {
return engine.Group("/api")
}, dig.Name("apiRouterGroup"))

apiRouter := engine.Group("/api")
if err != nil {
return fmt.Errorf("failed to provide api router group: %w", err)
}

controller.NewContextController(app.log, app.config, app.runtime, apiRouter)
controller.NewOAuthController(app.log, app.config, app.runtime, apiRouter, app.services.authService)
controller.NewOIDCController(app.log, app.services.oidcService, app.runtime, apiRouter, &engine.RouterGroup)
controller.NewProxyController(app.log, app.runtime, apiRouter, app.services.accessControlService, app.services.authService, app.services.policyEngine)
controller.NewUserController(app.log, app.runtime, apiRouter, app.services.authService)
controller.NewResourcesController(app.config, &engine.RouterGroup)
controller.NewHealthController(apiRouter)
controller.NewWellKnownController(app.services.oidcService, &engine.RouterGroup)
controllerProvideFor := []any{
controller.NewContextController,
controller.NewOAuthController,
controller.NewOIDCController,
controller.NewProxyController,
controller.NewUserController,
controller.NewResourcesController,
controller.NewHealthController,
controller.NewWellKnownController,
}

for _, provider := range controllerProvideFor {
err := app.dig.Provide(provider)

if err != nil {
return fmt.Errorf("failed to provide controller: %w", err)
}
}

type controllerInput struct {
dig.In

ContextController *controller.ContextController
OAuthController *controller.OAuthController
OIDCController *controller.OIDCController
ProxyController *controller.ProxyController
UserController *controller.UserController
ResourcesController *controller.ResourcesController
HealthController *controller.HealthController
WellKnownController *controller.WellKnownController
}

// force dig to build all controllers and register their routes
err = app.dig.Invoke(func(ci controllerInput) error {
return nil
})

if err != nil {
return fmt.Errorf("failed to invoke controllers: %w", err)
}

app.router = engine
return nil
Expand Down
Loading