crockery/cmd/crockery/cmd_init.go

104 lines
2.4 KiB
Go

package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"gopkg.in/urfave/cli.v1"
"ur.gs/crockery/internal/store"
)
func crockeryInit(c *cli.Context) error {
home := c.GlobalString("home")
domain := c.String("domain")
certFile := c.String("cert")
keyFile := c.String("key")
postmasterPassword := c.String("postmaster-password")
db := store.BuildDatabasePath(home)
if home == "" {
return fmt.Errorf("No crockery home directory specified")
}
if domain == "" {
return fmt.Errorf("A domain must be specified")
}
// FIXME: we can make cert+key optional at some point and have them be
// generated on-demand via ACME during `crockery run` instead.
if certFile == "" {
return fmt.Errorf("A certificate file must be specified")
}
if keyFile == "" {
return fmt.Errorf("A key file must be specified")
}
if postmasterPassword == "" {
return fmt.Errorf("A password must be specified for the postmaster user")
}
// TODO: check it is a directory
if _, err := os.Stat(home); os.IsNotExist(err) {
return fmt.Errorf("Home directory %q does not exist!", home)
}
if _, err := os.Stat(db); !os.IsNotExist(err) {
return fmt.Errorf("Database file %q already exists!", db)
}
certPEM, err := ioutil.ReadFile(certFile)
if err != nil {
return fmt.Errorf("Failed to read certificate from %q: %v", certFile, err)
}
keyPEM, err := ioutil.ReadFile(keyFile)
if err != nil {
return fmt.Errorf("Failed to read key from %q: %v", keyFile, err)
}
if err := store.Init(home, domain, certPEM, keyPEM); err != nil {
return fmt.Errorf("Couldn't initialize home directory %q: %v", home, err)
}
datastore, err := store.New(context.Background(), home)
if err != nil {
return err
}
hash, err := store.HashPassword(postmasterPassword)
if err != nil {
return err
}
username := "postmaster@" + domain
postmaster := store.Account{
Username: username,
Admin: true,
PasswordHash: hash,
}
if err := datastore.CreateAccount(&postmaster); err != nil {
return fmt.Errorf("Failed to create admin account %s: %v", postmaster.Username, err)
}
maildir := store.Maildir{Account: postmaster, Name: ""}
if err := datastore.CreateMaildir(&maildir); err != nil {
return fmt.Errorf("Failed to create admin maildir %q: %v", maildir.Rel(), err)
}
log.Printf(
"Initialized %q for domain %q. Next step:\n\t%s -home %q run",
home, domain, os.Args[0], home,
)
return nil
}