mirror of https://gitlab.com/ngerakines/tavern.git
161 lines
3.6 KiB
Go
161 lines
3.6 KiB
Go
package start
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"runtime"
|
|
|
|
"github.com/getsentry/sentry-go"
|
|
"github.com/urfave/cli/v2"
|
|
"go.uber.org/zap"
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
"github.com/ngerakines/tavern/config"
|
|
"github.com/ngerakines/tavern/g"
|
|
"github.com/ngerakines/tavern/storage"
|
|
)
|
|
|
|
var Command = cli.Command{
|
|
Name: "init",
|
|
Usage: "Initialize the server",
|
|
Flags: []cli.Flag{
|
|
&config.EnvironmentFlag,
|
|
&config.ListenFlag,
|
|
&config.DomainFlag,
|
|
&config.DatabaseFlag,
|
|
&config.TranslationsFlag,
|
|
&cli.StringFlag{
|
|
Name: "admin-email",
|
|
Usage: "The email address of the admin user",
|
|
Required: true,
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "admin-password",
|
|
Usage: "The password of the admin user",
|
|
Required: true,
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "admin-locale",
|
|
Usage: "The locale of the admin user",
|
|
Value: "en",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "admin-name",
|
|
Usage: "The name of the admin user",
|
|
Required: true,
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "admin-displayname",
|
|
Usage: "The display name of the admin user",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "admin-about",
|
|
Usage: "The 'about me' of the admin user",
|
|
},
|
|
},
|
|
Action: serverCommandAction,
|
|
}
|
|
|
|
func serverCommandAction(cliCtx *cli.Context) error {
|
|
logger, err := config.Logger(cliCtx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
domain := cliCtx.String("domain")
|
|
siteBase := fmt.Sprintf("https://%s", domain)
|
|
|
|
logger.Info("Starting",
|
|
zap.String("command", cliCtx.Command.Name),
|
|
zap.String("GOOS", runtime.GOOS),
|
|
zap.String("site", siteBase),
|
|
zap.String("env", cliCtx.String("environment")))
|
|
|
|
sentryConfig, err := config.NewSentryConfig(cliCtx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if sentryConfig.Enabled {
|
|
err = sentry.Init(sentry.ClientOptions{
|
|
Dsn: sentryConfig.Key,
|
|
Environment: cliCtx.String("environment"),
|
|
Release: fmt.Sprintf("%s-%s", g.ReleaseCode, g.GitCommit),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
|
scope.SetTags(map[string]string{"container": "server"})
|
|
})
|
|
defer sentry.Recover()
|
|
}
|
|
|
|
db, dbClose, err := config.DB(cliCtx, logger)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer dbClose()
|
|
|
|
s := storage.DefaultStorage(db)
|
|
|
|
userID := storage.NewV4()
|
|
|
|
name := cliCtx.String("admin-name")
|
|
displayName := cliCtx.String("admin-displayname")
|
|
if len(displayName) == 0 {
|
|
displayName = name
|
|
}
|
|
about := cliCtx.String("admin-about")
|
|
if len(about) == 0 {
|
|
about = "Just a user"
|
|
}
|
|
|
|
encPassword, err := bcrypt.GenerateFromPassword([]byte(cliCtx.String("admin-password")), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
privateKeyBytes := x509.MarshalPKCS1PrivateKey(key)
|
|
var privateKeyBuffer bytes.Buffer
|
|
if err := pem.Encode(&privateKeyBuffer, &pem.Block{
|
|
Type: "PRIVATE KEY",
|
|
Bytes: privateKeyBytes,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
privateKey := string(privateKeyBuffer.Bytes())
|
|
|
|
publicKeyBytes, err := x509.MarshalPKIXPublicKey(key.Public())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var publicKeyBuffer bytes.Buffer
|
|
if err = pem.Encode(&publicKeyBuffer, &pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Bytes: publicKeyBytes,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
publicKey := string(publicKeyBuffer.Bytes())
|
|
|
|
err = s.CreateUser(context.Background(), userID, cliCtx.String("admin-email"), cliCtx.String("admin-locale"), name, displayName, about, publicKey, privateKey, encPassword)
|
|
if err != nil {
|
|
logger.Error("unable to create user", zap.Error(err))
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|