forked from authentricity/authentricity
97 lines
2.9 KiB
Go
97 lines
2.9 KiB
Go
package webui
|
|
|
|
import (
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/coreos/go-systemd/v22/activation"
|
|
"github.com/google/uuid"
|
|
"github.com/kelseyhightower/envconfig"
|
|
"go.e43.eu/authentricity/internal/store"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type Config struct {
|
|
Debug bool `default:"false" description:"Enable debug logging"`
|
|
ListenType string `envconfig:"listen_type" default:"tcp" description:"Type of socket to listen on (Go 'net.Listen()' network)"`
|
|
ListenAddress string `envconfig:"listen_address" default:":8700" description:"Address to listen on (Go 'net.Listen()' address)"`
|
|
SecretsDir string `envconfig:"secrets_dir" default:"/var/lib/authentricity/webui/secrets" description:"Directory in which to store secrets"`
|
|
TokenCookie string `envconfig:"token_cookie" default:"authentricity_token" description:"Cookie in which to store authentication token"`
|
|
AdminGroupID uuid.UUID `envconfig:"admin_group_id" required:"true" description:"UUID of administrator group"`
|
|
CookieDomain string `envconfig:"cookie_domain" default:"" description:"Domain to use when setting token cookie - customize to do cross-domain cookie based SSO"`
|
|
NoHTTPS bool `envconfig:"no_https" default:"false" description:"Allow access over insecure HTTP. For development only"`
|
|
WebAuthnOrigin string `envconfig:"webauthn_origin" default:"" description:"WebAuthn Origin"`
|
|
}
|
|
|
|
func Main() {
|
|
var (
|
|
cfg Config
|
|
L *zap.Logger
|
|
)
|
|
|
|
err := envconfig.Process("authentricity_webui", &cfg)
|
|
if err != nil {
|
|
envconfig.Usage("authentricity_webui", &cfg)
|
|
log.Fatalf("Parsing settings: %v", err)
|
|
}
|
|
|
|
if cfg.Debug {
|
|
L, err = zap.NewDevelopment()
|
|
} else {
|
|
L, err = zap.NewProduction()
|
|
}
|
|
if err != nil {
|
|
log.Fatal("Initializing logger", err)
|
|
}
|
|
defer zap.ReplaceGlobals(L)()
|
|
defer zap.RedirectStdLog(L)()
|
|
S := L.Sugar()
|
|
|
|
if err := os.MkdirAll(cfg.SecretsDir, 0700); err != nil {
|
|
S.Fatalf("Error creating secrets directory '%s': %v", cfg.SecretsDir, err)
|
|
}
|
|
|
|
cst, err := store.NewConsulStore(L.Named("consul_store"))
|
|
if err != nil {
|
|
S.Fatalf("Error creating Consul store: %v", err)
|
|
}
|
|
|
|
l := listener(cfg)
|
|
service := buildService(cfg, cst)
|
|
err = http.Serve(l, service)
|
|
if err != nil {
|
|
S.Fatalf("Error serving requests: %v", err)
|
|
}
|
|
}
|
|
|
|
func listener(cfg Config) net.Listener {
|
|
S := zap.S()
|
|
|
|
listeners, err := activation.Listeners()
|
|
if err != nil {
|
|
S.Fatalf("Error checking for socket-activation sockets: %v", err)
|
|
}
|
|
|
|
switch len(listeners) {
|
|
case 0:
|
|
S.Infof("Listening on %s:%s", cfg.ListenType, cfg.ListenAddress)
|
|
l, err := net.Listen(cfg.ListenType, cfg.ListenAddress)
|
|
if err != nil {
|
|
S.Fatalf("Error creating listener: %v", err)
|
|
}
|
|
return l
|
|
|
|
case 1:
|
|
l := listeners[0]
|
|
S.Infof("Listening on socket passed by init system with address %s:%s",
|
|
l.Addr().Network(), l.Addr().String())
|
|
return l
|
|
|
|
default:
|
|
S.Fatalf("Socket activated with more than one socket - only one expected")
|
|
return nil
|
|
}
|
|
}
|