server/main.go

120 lines
2.8 KiB
Go

package main
import (
"context"
"crypto/rand"
"embed"
"encoding/base64"
"flag"
"log"
"os"
"git.codemonkeysoftware.net/mouseion/server/pkg/authentication"
"git.codemonkeysoftware.net/mouseion/server/pkg/authentication/apitoken"
authstore "git.codemonkeysoftware.net/mouseion/server/pkg/authentication/sql_store"
"git.codemonkeysoftware.net/mouseion/server/pkg/database"
"git.codemonkeysoftware.net/mouseion/server/pkg/database/sqlite"
"git.codemonkeysoftware.net/mouseion/server/pkg/email"
entrystore "git.codemonkeysoftware.net/mouseion/server/pkg/entry/sql_store"
"git.codemonkeysoftware.net/mouseion/server/pkg/views"
"git.codemonkeysoftware.net/mouseion/server/pkg/webserver"
"github.com/JeremyLoy/config"
"github.com/volatiletech/authboss/v3"
)
//go:embed public/*
var public embed.FS
type Config struct {
Auth authentication.Config
Database database.Config
Email email.Config
}
func main() {
var configPath string
flag.StringVar(&configPath, "config", "", "")
flag.Parse()
appConfig := Config{}
config := config.FromEnv()
if configPath != "" {
log.Printf("using config from %s", configPath)
config.From(configPath)
}
err := config.To(&appConfig)
if err != nil {
log.Println(err)
os.Exit(1)
}
db := sqlite.Open(appConfig.Database.Path)
defer db.Close()
err = sqlite.DoMigrations(db.DB)
if err != nil {
log.Println(err)
os.Exit(1)
}
entryService := entrystore.New(db)
authStorer := authstore.New(db)
ab, err := authentication.Authboss(authStorer, appConfig.Auth, appConfig.Email)
if err != nil {
log.Println(err)
os.Exit(1)
}
apiToken := apitoken.APIToken{Authboss: ab}
apiToken.Setup()
adminUser, err := createFirstAdminUser(authStorer, ab)
if err != nil {
log.Println(err)
os.Exit(1)
}
if adminUser != nil {
log.Printf("Created first admin user\nEmail: %s\nPassword: %s", adminUser.Email, adminUser.Password)
}
webserver.New(
entryService,
authStorer,
ab,
authStorer,
apiToken.RequireTokenMiddleware,
views.WebTemplates(),
public,
).Start()
}
func createFirstAdminUser(authStorer *authstore.SQLStore, ab *authboss.Authboss) (*authentication.User, error) {
ctx := context.Background()
err := authStorer.UsersExist(ctx)
if err == nil {
return nil, nil
}
if err != authstore.ErrNoUsers {
return nil, err
}
abUser := authStorer.New(ctx)
adminUser, err := authentication.GetAuthUser(abUser)
if err != nil {
return nil, err
}
adminUser.Email = "tinyhatchet@example.com"
adminUser.Confirmed = true
err = authStorer.Create(ctx, adminUser)
if err != nil {
return nil, err
}
passBuff := make([]byte, 15)
_, err = rand.Read(passBuff)
if err != nil {
return nil, err
}
password := base64.StdEncoding.EncodeToString(passBuff)
err = ab.UpdatePassword(ctx, adminUser, password)
if err != nil {
return nil, err
}
adminUser.Password = password
return adminUser, nil
}