mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2025-10-28 20:55:42 +00:00
feat: version info analytics
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"tinyauth/internal/config"
|
||||
"tinyauth/internal/controller"
|
||||
"tinyauth/internal/middleware"
|
||||
@@ -29,40 +32,43 @@ type Service interface {
|
||||
}
|
||||
|
||||
type BootstrapApp struct {
|
||||
Config config.Config
|
||||
config config.Config
|
||||
uuid string
|
||||
}
|
||||
|
||||
func NewBootstrapApp(config config.Config) *BootstrapApp {
|
||||
return &BootstrapApp{
|
||||
Config: config,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func (app *BootstrapApp) Setup() error {
|
||||
// Parse users
|
||||
users, err := utils.GetUsers(app.Config.Users, app.Config.UsersFile)
|
||||
users, err := utils.GetUsers(app.config.Users, app.config.UsersFile)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get OAuth configs
|
||||
oauthProviders, err := utils.GetOAuthProvidersConfig(os.Environ(), os.Args, app.Config.AppURL)
|
||||
oauthProviders, err := utils.GetOAuthProvidersConfig(os.Environ(), os.Args, app.config.AppURL)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get cookie domain
|
||||
cookieDomain, err := utils.GetCookieDomain(app.Config.AppURL)
|
||||
cookieDomain, err := utils.GetCookieDomain(app.config.AppURL)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Cookie names
|
||||
appUrl, _ := url.Parse(app.Config.AppURL) // Already validated
|
||||
cookieId := utils.GenerateIdentifier(appUrl.Hostname())
|
||||
appUrl, _ := url.Parse(app.config.AppURL) // Already validated
|
||||
uuid := utils.GenerateUUID(appUrl.Hostname())
|
||||
app.uuid = uuid
|
||||
cookieId := strings.Split(uuid, "-")[0]
|
||||
sessionCookieName := fmt.Sprintf("%s-%s", config.SessionCookieName, cookieId)
|
||||
csrfCookieName := fmt.Sprintf("%s-%s", config.CSRFCookieName, cookieId)
|
||||
redirectCookieName := fmt.Sprintf("%s-%s", config.RedirectCookieName, cookieId)
|
||||
@@ -70,26 +76,26 @@ func (app *BootstrapApp) Setup() error {
|
||||
// Create configs
|
||||
authConfig := service.AuthServiceConfig{
|
||||
Users: users,
|
||||
OauthWhitelist: app.Config.OAuthWhitelist,
|
||||
SessionExpiry: app.Config.SessionExpiry,
|
||||
SecureCookie: app.Config.SecureCookie,
|
||||
OauthWhitelist: app.config.OAuthWhitelist,
|
||||
SessionExpiry: app.config.SessionExpiry,
|
||||
SecureCookie: app.config.SecureCookie,
|
||||
CookieDomain: cookieDomain,
|
||||
LoginTimeout: app.Config.LoginTimeout,
|
||||
LoginMaxRetries: app.Config.LoginMaxRetries,
|
||||
LoginTimeout: app.config.LoginTimeout,
|
||||
LoginMaxRetries: app.config.LoginMaxRetries,
|
||||
SessionCookieName: sessionCookieName,
|
||||
}
|
||||
|
||||
// Setup services
|
||||
var ldapService *service.LdapService
|
||||
|
||||
if app.Config.LdapAddress != "" {
|
||||
if app.config.LdapAddress != "" {
|
||||
ldapConfig := service.LdapServiceConfig{
|
||||
Address: app.Config.LdapAddress,
|
||||
BindDN: app.Config.LdapBindDN,
|
||||
BindPassword: app.Config.LdapBindPassword,
|
||||
BaseDN: app.Config.LdapBaseDN,
|
||||
Insecure: app.Config.LdapInsecure,
|
||||
SearchFilter: app.Config.LdapSearchFilter,
|
||||
Address: app.config.LdapAddress,
|
||||
BindDN: app.config.LdapBindDN,
|
||||
BindPassword: app.config.LdapBindPassword,
|
||||
BaseDN: app.config.LdapBaseDN,
|
||||
Insecure: app.config.LdapInsecure,
|
||||
SearchFilter: app.config.LdapSearchFilter,
|
||||
}
|
||||
|
||||
ldapService = service.NewLdapService(ldapConfig)
|
||||
@@ -104,7 +110,7 @@ func (app *BootstrapApp) Setup() error {
|
||||
|
||||
// Bootstrap database
|
||||
databaseService := service.NewDatabaseService(service.DatabaseServiceConfig{
|
||||
DatabasePath: app.Config.DatabasePath,
|
||||
DatabasePath: app.config.DatabasePath,
|
||||
})
|
||||
|
||||
log.Debug().Str("service", fmt.Sprintf("%T", databaseService)).Msg("Initializing service")
|
||||
@@ -183,8 +189,8 @@ func (app *BootstrapApp) Setup() error {
|
||||
// Create engine
|
||||
engine := gin.New()
|
||||
|
||||
if len(app.Config.TrustedProxies) > 0 {
|
||||
engine.SetTrustedProxies(strings.Split(app.Config.TrustedProxies, ","))
|
||||
if len(app.config.TrustedProxies) > 0 {
|
||||
engine.SetTrustedProxies(strings.Split(app.config.TrustedProxies, ","))
|
||||
}
|
||||
|
||||
if config.Version != "development" {
|
||||
@@ -219,24 +225,24 @@ func (app *BootstrapApp) Setup() error {
|
||||
// Create controllers
|
||||
contextController := controller.NewContextController(controller.ContextControllerConfig{
|
||||
Providers: configuredProviders,
|
||||
Title: app.Config.Title,
|
||||
AppURL: app.Config.AppURL,
|
||||
Title: app.config.Title,
|
||||
AppURL: app.config.AppURL,
|
||||
CookieDomain: cookieDomain,
|
||||
ForgotPasswordMessage: app.Config.ForgotPasswordMessage,
|
||||
BackgroundImage: app.Config.BackgroundImage,
|
||||
OAuthAutoRedirect: app.Config.OAuthAutoRedirect,
|
||||
ForgotPasswordMessage: app.config.ForgotPasswordMessage,
|
||||
BackgroundImage: app.config.BackgroundImage,
|
||||
OAuthAutoRedirect: app.config.OAuthAutoRedirect,
|
||||
}, apiRouter)
|
||||
|
||||
oauthController := controller.NewOAuthController(controller.OAuthControllerConfig{
|
||||
AppURL: app.Config.AppURL,
|
||||
SecureCookie: app.Config.SecureCookie,
|
||||
AppURL: app.config.AppURL,
|
||||
SecureCookie: app.config.SecureCookie,
|
||||
CSRFCookieName: csrfCookieName,
|
||||
RedirectCookieName: redirectCookieName,
|
||||
CookieDomain: cookieDomain,
|
||||
}, apiRouter, authService, oauthBrokerService)
|
||||
|
||||
proxyController := controller.NewProxyController(controller.ProxyControllerConfig{
|
||||
AppURL: app.Config.AppURL,
|
||||
AppURL: app.config.AppURL,
|
||||
}, apiRouter, dockerService, authService)
|
||||
|
||||
userController := controller.NewUserController(controller.UserControllerConfig{
|
||||
@@ -244,7 +250,7 @@ func (app *BootstrapApp) Setup() error {
|
||||
}, apiRouter, authService)
|
||||
|
||||
resourcesController := controller.NewResourcesController(controller.ResourcesControllerConfig{
|
||||
ResourcesDir: app.Config.ResourcesDir,
|
||||
ResourcesDir: app.config.ResourcesDir,
|
||||
}, mainRouter)
|
||||
|
||||
healthController := controller.NewHealthController(apiRouter)
|
||||
@@ -264,8 +270,14 @@ func (app *BootstrapApp) Setup() error {
|
||||
ctrl.SetupRoutes()
|
||||
}
|
||||
|
||||
// If analytics are not disabled, start heartbeat
|
||||
if !app.config.DisableAnalytics {
|
||||
log.Debug().Msg("Starting heartbeat routine")
|
||||
go app.heartbeat()
|
||||
}
|
||||
|
||||
// Start server
|
||||
address := fmt.Sprintf("%s:%d", app.Config.Address, app.Config.Port)
|
||||
address := fmt.Sprintf("%s:%d", app.config.Address, app.config.Port)
|
||||
log.Info().Msgf("Starting server on %s", address)
|
||||
if err := engine.Run(address); err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to start server")
|
||||
@@ -273,3 +285,55 @@ func (app *BootstrapApp) Setup() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *BootstrapApp) heartbeat() {
|
||||
ticker := time.NewTicker(time.Duration(12) * time.Hour)
|
||||
defer ticker.Stop()
|
||||
|
||||
type heartbeat struct {
|
||||
UUID string `json:"uuid"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
var body heartbeat
|
||||
|
||||
body.UUID = app.uuid
|
||||
body.Version = config.Version
|
||||
|
||||
bodyJson, err := json.Marshal(body)
|
||||
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to marshal heartbeat body")
|
||||
return
|
||||
}
|
||||
|
||||
heartbeatURL := config.ApiServer + "/v1/instances/heartbeat"
|
||||
|
||||
for ; true; <-ticker.C {
|
||||
log.Debug().Msg("Sending heartbeat")
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, heartbeatURL, strings.NewReader(string(bodyJson)))
|
||||
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to create heartbeat request")
|
||||
continue
|
||||
}
|
||||
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
client := &http.Client{}
|
||||
|
||||
res, err := client.Do(req)
|
||||
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to send heartbeat")
|
||||
continue
|
||||
}
|
||||
|
||||
res.Body.Close()
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
log.Debug().Str("status", res.Status).Msg("Heartbeat returned non-200 status")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user