104 lines
2.4 KiB
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
|
|
}
|