@@ -13,32 +13,26 @@ import (
1313 "time"
1414 "tinyauth/internal/config"
1515 "tinyauth/internal/controller"
16- "tinyauth/internal/middleware"
1716 "tinyauth/internal/model"
18- "tinyauth/internal/service"
1917 "tinyauth/internal/utils"
2018
21- "github.com/gin-gonic/gin"
2219 "github.com/rs/zerolog/log"
2320 "gorm.io/gorm"
2421)
2522
26- type Controller interface {
27- SetupRoutes ()
28- }
29-
30- type Middleware interface {
31- Middleware () gin.HandlerFunc
32- Init () error
33- }
34-
35- type Service interface {
36- Init () error
37- }
38-
3923type BootstrapApp struct {
40- config config.Config
41- uuid string
24+ config config.Config
25+ context struct {
26+ uuid string
27+ cookieDomain string
28+ sessionCookieName string
29+ csrfCookieName string
30+ redirectCookieName string
31+ users []config.User
32+ oauthProviders map [string ]config.OAuthServiceConfig
33+ configuredProviders []controller.Provider
34+ }
35+ services Services
4236}
4337
4438func NewBootstrapApp (config config.Config ) * BootstrapApp {
@@ -55,111 +49,51 @@ func (app *BootstrapApp) Setup() error {
5549 return err
5650 }
5751
52+ app .context .users = users
53+
5854 // Get OAuth configs
5955 oauthProviders , err := utils .GetOAuthProvidersConfig (os .Environ (), os .Args , app .config .AppURL )
6056
6157 if err != nil {
6258 return err
6359 }
6460
61+ app .context .oauthProviders = oauthProviders
62+
6563 // Get cookie domain
6664 cookieDomain , err := utils .GetCookieDomain (app .config .AppURL )
6765
6866 if err != nil {
6967 return err
7068 }
7169
70+ app .context .cookieDomain = cookieDomain
71+
7272 // Cookie names
7373 appUrl , _ := url .Parse (app .config .AppURL ) // Already validated
74- uuid := utils .GenerateUUID (appUrl .Hostname ())
75- app .uuid = uuid
76- cookieId := strings .Split (uuid , "-" )[0 ]
77- sessionCookieName := fmt .Sprintf ("%s-%s" , config .SessionCookieName , cookieId )
78- csrfCookieName := fmt .Sprintf ("%s-%s" , config .CSRFCookieName , cookieId )
79- redirectCookieName := fmt .Sprintf ("%s-%s" , config .RedirectCookieName , cookieId )
74+ app .context .uuid = utils .GenerateUUID (appUrl .Hostname ())
75+ cookieId := strings .Split (app .context .uuid , "-" )[0 ]
76+ app .context .sessionCookieName = fmt .Sprintf ("%s-%s" , config .SessionCookieName , cookieId )
77+ app .context .csrfCookieName = fmt .Sprintf ("%s-%s" , config .CSRFCookieName , cookieId )
78+ app .context .redirectCookieName = fmt .Sprintf ("%s-%s" , config .RedirectCookieName , cookieId )
8079
8180 // Dumps
8281 log .Trace ().Interface ("config" , app .config ).Msg ("Config dump" )
83- log .Trace ().Interface ("users" , users ).Msg ("Users dump" )
84- log .Trace ().Interface ("oauthProviders" , oauthProviders ).Msg ("OAuth providers dump" )
85- log .Trace ().Str ("cookieDomain" , cookieDomain ).Msg ("Cookie domain" )
86- log .Trace ().Str ("sessionCookieName" , sessionCookieName ).Msg ("Session cookie name" )
87- log .Trace ().Str ("csrfCookieName" , csrfCookieName ).Msg ("CSRF cookie name" )
88- log .Trace ().Str ("redirectCookieName" , redirectCookieName ).Msg ("Redirect cookie name" )
89-
90- // Create configs
91- authConfig := service.AuthServiceConfig {
92- Users : users ,
93- OauthWhitelist : app .config .OAuthWhitelist ,
94- SessionExpiry : app .config .SessionExpiry ,
95- SecureCookie : app .config .SecureCookie ,
96- CookieDomain : cookieDomain ,
97- LoginTimeout : app .config .LoginTimeout ,
98- LoginMaxRetries : app .config .LoginMaxRetries ,
99- SessionCookieName : sessionCookieName ,
100- }
101-
102- // Setup services
103- var ldapService * service.LdapService
104-
105- if app .config .LdapAddress != "" {
106- ldapConfig := service.LdapServiceConfig {
107- Address : app .config .LdapAddress ,
108- BindDN : app .config .LdapBindDN ,
109- BindPassword : app .config .LdapBindPassword ,
110- BaseDN : app .config .LdapBaseDN ,
111- Insecure : app .config .LdapInsecure ,
112- SearchFilter : app .config .LdapSearchFilter ,
113- }
114-
115- ldapService = service .NewLdapService (ldapConfig )
82+ log .Trace ().Interface ("users" , app .context .users ).Msg ("Users dump" )
83+ log .Trace ().Interface ("oauthProviders" , app .context .oauthProviders ).Msg ("OAuth providers dump" )
84+ log .Trace ().Str ("cookieDomain" , app .context .cookieDomain ).Msg ("Cookie domain" )
85+ log .Trace ().Str ("sessionCookieName" , app .context .sessionCookieName ).Msg ("Session cookie name" )
86+ log .Trace ().Str ("csrfCookieName" , app .context .csrfCookieName ).Msg ("CSRF cookie name" )
87+ log .Trace ().Str ("redirectCookieName" , app .context .redirectCookieName ).Msg ("Redirect cookie name" )
11688
117- err := ldapService .Init ()
118-
119- if err != nil {
120- log .Warn ().Err (err ).Msg ("Failed to initialize LDAP service, continuing without LDAP" )
121- ldapService = nil
122- }
123- }
124-
125- // Bootstrap database
126- databaseService := service .NewDatabaseService (service.DatabaseServiceConfig {
127- DatabasePath : app .config .DatabasePath ,
128- })
129-
130- log .Debug ().Str ("service" , fmt .Sprintf ("%T" , databaseService )).Msg ("Initializing service" )
131-
132- err = databaseService .Init ()
89+ // Services
90+ services , err := app .initServices ()
13391
13492 if err != nil {
135- return fmt .Errorf ("failed to initialize database service : %w" , err )
93+ return fmt .Errorf ("failed to initialize services : %w" , err )
13694 }
13795
138- database := databaseService .GetDatabase ()
139-
140- // Create services
141- dockerService := service .NewDockerService ()
142- aclsService := service .NewAccessControlsService (dockerService )
143- authService := service .NewAuthService (authConfig , dockerService , ldapService , database )
144- oauthBrokerService := service .NewOAuthBrokerService (oauthProviders )
145-
146- // Initialize services (order matters)
147- services := []Service {
148- dockerService ,
149- aclsService ,
150- authService ,
151- oauthBrokerService ,
152- }
153-
154- for _ , svc := range services {
155- if svc != nil {
156- log .Debug ().Str ("service" , fmt .Sprintf ("%T" , svc )).Msg ("Initializing service" )
157- err := svc .Init ()
158- if err != nil {
159- return err
160- }
161- }
162- }
96+ app .services = services
16397
16498 // Configured providers
16599 configuredProviders := make ([]controller.Provider , 0 )
@@ -176,7 +110,7 @@ func (app *BootstrapApp) Setup() error {
176110 return configuredProviders [i ].Name < configuredProviders [j ].Name
177111 })
178112
179- if authService .UserAuthConfigured () || ldapService != nil {
113+ if services . authService .UserAuthConfigured () {
180114 configuredProviders = append (configuredProviders , controller.Provider {
181115 Name : "Username" ,
182116 ID : "username" ,
@@ -190,106 +124,27 @@ func (app *BootstrapApp) Setup() error {
190124 return fmt .Errorf ("no authentication providers configured" )
191125 }
192126
193- // Create engine
194- engine := gin .New ()
195- engine .Use (gin .Recovery ())
196-
197- if len (app .config .TrustedProxies ) > 0 {
198- err := engine .SetTrustedProxies (strings .Split (app .config .TrustedProxies , "," ))
199-
200- if err != nil {
201- return fmt .Errorf ("failed to set trusted proxies: %w" , err )
202- }
203- }
204-
205- // Create middlewares
206- var middlewares []Middleware
207-
208- contextMiddleware := middleware .NewContextMiddleware (middleware.ContextMiddlewareConfig {
209- CookieDomain : cookieDomain ,
210- }, authService , oauthBrokerService )
211-
212- uiMiddleware := middleware .NewUIMiddleware ()
213- zerologMiddleware := middleware .NewZerologMiddleware ()
127+ app .context .configuredProviders = configuredProviders
214128
215- middlewares = append (middlewares , contextMiddleware , uiMiddleware , zerologMiddleware )
129+ // Setup router
130+ router , err := app .setupRouter ()
216131
217- for _ , middleware := range middlewares {
218- log .Debug ().Str ("middleware" , fmt .Sprintf ("%T" , middleware )).Msg ("Initializing middleware" )
219- err := middleware .Init ()
220- if err != nil {
221- return fmt .Errorf ("failed to initialize middleware %T: %w" , middleware , err )
222- }
223- engine .Use (middleware .Middleware ())
224- }
225-
226- // Create routers
227- mainRouter := engine .Group ("" )
228- apiRouter := engine .Group ("/api" )
229-
230- // Create controllers
231- contextController := controller .NewContextController (controller.ContextControllerConfig {
232- Providers : configuredProviders ,
233- Title : app .config .Title ,
234- AppURL : app .config .AppURL ,
235- CookieDomain : cookieDomain ,
236- ForgotPasswordMessage : app .config .ForgotPasswordMessage ,
237- BackgroundImage : app .config .BackgroundImage ,
238- OAuthAutoRedirect : app .config .OAuthAutoRedirect ,
239- DisableUIWarnings : app .config .DisableUIWarnings ,
240- }, apiRouter )
241-
242- oauthController := controller .NewOAuthController (controller.OAuthControllerConfig {
243- AppURL : app .config .AppURL ,
244- SecureCookie : app .config .SecureCookie ,
245- CSRFCookieName : csrfCookieName ,
246- RedirectCookieName : redirectCookieName ,
247- CookieDomain : cookieDomain ,
248- }, apiRouter , authService , oauthBrokerService )
249-
250- proxyController := controller .NewProxyController (controller.ProxyControllerConfig {
251- AppURL : app .config .AppURL ,
252- }, apiRouter , aclsService , authService )
253-
254- userController := controller .NewUserController (controller.UserControllerConfig {
255- CookieDomain : cookieDomain ,
256- }, apiRouter , authService )
257-
258- resourcesController := controller .NewResourcesController (controller.ResourcesControllerConfig {
259- ResourcesDir : app .config .ResourcesDir ,
260- ResourcesDisabled : app .config .DisableResources ,
261- }, mainRouter )
262-
263- healthController := controller .NewHealthController (apiRouter )
264-
265- // Setup routes
266- controller := []Controller {
267- contextController ,
268- oauthController ,
269- proxyController ,
270- userController ,
271- healthController ,
272- resourcesController ,
132+ if err != nil {
133+ return fmt .Errorf ("failed to setup routes: %w" , err )
273134 }
274135
275- for _ , ctrl := range controller {
276- log .Debug ().Msgf ("Setting up %T controller" , ctrl )
277- ctrl .SetupRoutes ()
278- }
136+ // Start DB cleanup routine
137+ log .Debug ().Msg ("Starting database cleanup routine" )
138+ go app .dbCleanup (services .databaseService .GetDatabase ())
279139
280140 // If analytics are not disabled, start heartbeat
281141 if ! app .config .DisableAnalytics {
282142 log .Debug ().Msg ("Starting heartbeat routine" )
283143 go app .heartbeat ()
284144 }
285145
286- // Start DB cleanup routine
287- log .Debug ().Msg ("Starting database cleanup routine" )
288- go app .dbCleanup (database )
289-
290146 // If we have an socket path, bind to it
291147 if app .config .SocketPath != "" {
292- // Remove existing socket file
293148 if _ , err := os .Stat (app .config .SocketPath ); err == nil {
294149 log .Info ().Msgf ("Removing existing socket file %s" , app .config .SocketPath )
295150 err := os .Remove (app .config .SocketPath )
@@ -298,9 +153,8 @@ func (app *BootstrapApp) Setup() error {
298153 }
299154 }
300155
301- // Start server with unix socket
302156 log .Info ().Msgf ("Starting server on unix socket %s" , app .config .SocketPath )
303- if err := engine .RunUnix (app .config .SocketPath ); err != nil {
157+ if err := router .RunUnix (app .config .SocketPath ); err != nil {
304158 log .Fatal ().Err (err ).Msg ("Failed to start server" )
305159 }
306160
@@ -310,7 +164,7 @@ func (app *BootstrapApp) Setup() error {
310164 // Start server
311165 address := fmt .Sprintf ("%s:%d" , app .config .Address , app .config .Port )
312166 log .Info ().Msgf ("Starting server on %s" , address )
313- if err := engine .Run (address ); err != nil {
167+ if err := router .Run (address ); err != nil {
314168 log .Fatal ().Err (err ).Msg ("Failed to start server" )
315169 }
316170
@@ -328,7 +182,7 @@ func (app *BootstrapApp) heartbeat() {
328182
329183 var body heartbeat
330184
331- body .UUID = app .uuid
185+ body .UUID = app .context . uuid
332186 body .Version = config .Version
333187
334188 bodyJson , err := json .Marshal (body )
@@ -338,7 +192,9 @@ func (app *BootstrapApp) heartbeat() {
338192 return
339193 }
340194
341- client := & http.Client {}
195+ client := & http.Client {
196+ Timeout : time .Duration (10 ) * time .Second , // The server should never take more than 10 seconds to respond
197+ }
342198
343199 heartbeatURL := config .ApiServer + "/v1/instances/heartbeat"
344200
0 commit comments