golang-lib/web/main.go

92 lines
2.4 KiB
Go
Raw Normal View History

2021-07-19 17:59:47 +02:00
/*
Package web implements common functionality for web APIs using Gin and Gorm.
Modules
Modules provide functionality for a web server. A module is a function executed
before starting a server, accessing the Service and the Gin Engine. Each Service
maintains a list of modules. When it runs, it executes all of its modules.
*/
2021-06-01 10:51:35 +02:00
package web
import (
"net/http"
2021-06-01 10:51:35 +02:00
"github.com/gin-gonic/gin"
2021-09-29 13:08:43 +02:00
"go.uber.org/zap"
2021-06-01 10:51:35 +02:00
// acme
"github.com/gin-gonic/autotls"
"golang.org/x/crypto/acme/autocert"
2021-06-21 16:30:34 +02:00
// internal
2023-10-23 21:40:10 +02:00
"codeberg.org/genofire/golang-lib/mailer"
2021-06-21 16:30:34 +02:00
"gorm.io/gorm"
2021-06-01 10:51:35 +02:00
)
2021-07-19 17:59:47 +02:00
// A Service stores configuration of a server.
2021-06-01 10:51:35 +02:00
type Service struct {
// config
2022-08-14 16:50:52 +02:00
Listen string `config:"listen" toml:"listen"`
AccessLog bool `config:"access_log" toml:"access_log"`
WebrootIndexDisable bool `config:"webroot_index_disable" toml:"webroot_index_disable"`
Webroot string `config:"webroot" toml:"webroot"`
WebrootFS http.FileSystem `config:"-" toml:"-"`
2022-06-06 01:55:57 +02:00
ACME struct {
2022-08-14 16:50:52 +02:00
Enable bool `config:"enable" toml:"enable"`
Domains []string `config:"domains" toml:"domains"`
Cache string `config: "cache" toml:"cache"`
} `config:"acme" toml:"acme"`
2021-06-01 10:51:35 +02:00
Session struct {
2022-08-14 16:50:52 +02:00
Name string `config:"name" toml:"name"`
Secret string `config: "secret" toml:"secret"`
} `config:"session" toml:"session"`
2021-06-01 10:51:35 +02:00
// internal
2022-08-14 16:50:52 +02:00
DB *gorm.DB `config:"-" toml:"-"`
Mailer *mailer.Service `config:"-" toml:"-"`
2021-09-29 13:08:43 +02:00
log *zap.Logger
modules []ModuleRegisterFunc
2021-06-01 10:51:35 +02:00
}
2021-09-29 14:30:17 +02:00
// SetLog - set new logger
func (s *Service) SetLog(l *zap.Logger) {
s.log = l
}
2021-09-29 13:08:43 +02:00
// Log - get current logger
func (s *Service) Log() *zap.Logger {
return s.log
}
2021-07-19 17:59:47 +02:00
// Run creates, configures, and runs a new gin.Engine using its registered
// modules.
2021-09-29 13:08:43 +02:00
func (s *Service) Run(log *zap.Logger) error {
s.log = log
2021-06-01 10:51:35 +02:00
gin.EnableJsonDecoderDisallowUnknownFields()
gin.SetMode(gin.ReleaseMode)
r := gin.New()
// catch crashed
r.Use(gin.Recovery())
2021-07-19 17:59:47 +02:00
if s.AccessLog {
2021-06-01 10:51:35 +02:00
r.Use(gin.Logger())
2021-09-29 13:08:43 +02:00
s.log.Debug("request logging enabled")
2021-06-01 10:51:35 +02:00
}
2021-07-19 17:59:47 +02:00
s.LoadSession(r)
s.Bind(r)
2021-06-01 10:51:35 +02:00
2021-07-19 17:59:47 +02:00
if s.ACME.Enable {
if s.Listen != "" {
2021-09-29 13:08:43 +02:00
s.log.Panic("For ACME / Let's Encrypt it is not possible to set `listen`")
2021-06-01 10:51:35 +02:00
}
m := autocert.Manager{
Prompt: autocert.AcceptTOS,
2021-07-19 17:59:47 +02:00
HostPolicy: autocert.HostWhitelist(s.ACME.Domains...),
Cache: autocert.DirCache(s.ACME.Cache),
2021-06-01 10:51:35 +02:00
}
return autotls.RunWithManager(r, &m)
}
2021-07-19 17:59:47 +02:00
return r.Run(s.Listen)
2021-06-01 10:51:35 +02:00
}