package main import ( "context" "net/http" "time" "forge.cadoles.com/Cadoles/daddy/internal/mail" "forge.cadoles.com/Cadoles/daddy/internal/model" "forge.cadoles.com/Cadoles/daddy/internal/voter" "github.com/wader/gormstore" "forge.cadoles.com/Cadoles/daddy/internal/auth" "forge.cadoles.com/Cadoles/daddy/internal/orm" "gitlab.com/wpetit/goweb/logger" "forge.cadoles.com/Cadoles/daddy/internal/config" oidc "forge.cadoles.com/wpetit/goweb-oidc" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/service" "gitlab.com/wpetit/goweb/service/build" "gitlab.com/wpetit/goweb/service/session" "gitlab.com/wpetit/goweb/session/gorilla" ) func getServiceContainer(ctx context.Context, conf *config.Config) (*service.Container, error) { // Initialize and configure service container ctn := service.NewContainer() ctn.Provide(build.ServiceName, build.ServiceProvider(ProjectVersion, GitRef, BuildDate)) // Generate random cookie authentication key if none is set if conf.HTTP.CookieAuthenticationKey == "" { logger.Info(ctx, "could not find cookie authentication key. generating one...") cookieAuthenticationKey, err := gorilla.GenerateRandomBytes(64) if err != nil { return nil, errors.Wrap(err, "could not generate cookie authentication key") } conf.HTTP.CookieAuthenticationKey = string(cookieAuthenticationKey) } // Generate random cookie encryption key if none is set if conf.HTTP.CookieEncryptionKey == "" { logger.Info(ctx, "could not find cookie encryption key. generating one...") cookieEncryptionKey, err := gorilla.GenerateRandomBytes(32) if err != nil { return nil, errors.Wrap(err, "could not generate cookie encryption key") } conf.HTTP.CookieEncryptionKey = string(cookieEncryptionKey) } ctn.Provide(orm.ServiceName, orm.ServiceProvider("postgres", conf.Database.DSN, conf.Debug)) orm, err := orm.From(ctn) if err != nil { return nil, errors.WithStack(err) } // Create and initialize HTTP session service provider sessionStore := gormstore.NewOptions( orm.DB(), gormstore.Options{ TableName: "sessions", SkipCreateTable: false, }, []byte(conf.HTTP.CookieAuthenticationKey), []byte(conf.HTTP.CookieEncryptionKey), ) quit := make(chan struct{}) go sessionStore.PeriodicCleanup(1*time.Hour, quit) // Define default cookie options sessionStore.SessionOpts.Path = "/" sessionStore.SessionOpts.HttpOnly = true sessionStore.SessionOpts.MaxAge = conf.HTTP.CookieMaxAge sessionStore.SessionOpts.SameSite = http.SameSiteStrictMode ctn.Provide( session.ServiceName, gorilla.ServiceProvider("daddy", sessionStore), ) // Create and expose config service provider ctn.Provide(config.ServiceName, config.ServiceProvider(conf)) provider, err := oidc.NewProvider(ctx, conf.OIDC.IssuerURL) if err != nil { return nil, errors.Wrap(err, "could not create oidc provider") } ctn.Provide(oidc.ServiceName, oidc.ServiceProvider( oidc.WithCredentials(conf.OIDC.ClientID, conf.OIDC.ClientSecret), oidc.WithProvider(provider), oidc.WithScopes("email", "openid"), )) ctn.Provide(auth.ServiceName, auth.ServiceProvider(conf.Auth.Rules)) ctn.Provide(voter.ServiceName, voter.ServiceProvider( voter.StrategyUnanimous, model.NewDecisionSupportFileVoter(), model.NewWorkgroupVoter(), )) ctn.Provide(mail.ServiceName, mail.ServiceProvider( mail.WithServer(conf.SMTP.Host, conf.SMTP.Port), mail.WithCredentials(conf.SMTP.User, conf.SMTP.Password), mail.WithTLS(conf.SMTP.UseStartTLS, conf.SMTP.InsecureSkipVerify), )) return ctn, nil }