Using codegangsta/cli, specify keys at runtime

This commit is contained in:
Matthew Dillon 2015-01-05 14:16:50 -09:00
commit 3203c63237
2 changed files with 67 additions and 111 deletions

View file

@ -2,6 +2,7 @@ package api
import ( import (
"errors" "errors"
"fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
@ -10,8 +11,6 @@ import (
) )
const ( const (
privKeyPath = "keys/app.rsa" // openssl genrsa -out app.rsa keysize
pubKeyPath = "keys/app.rsa.pub" // openssl rsa -in app.rsa -pubout > app.rsa.pub
tokenName = "AccessToken" tokenName = "AccessToken"
) )
@ -24,29 +23,28 @@ var (
errGenericError = errors.New("generic error") errGenericError = errors.New("generic error")
) )
func init() { func SetupCerts(p string) error {
var err error var err error
signKey, err = ioutil.ReadFile(privKeyPath)
if err != nil { if err != nil {
// Before exploding, check up one level... log.Fatalf("Path error: ", err)
signKey, err = ioutil.ReadFile("../" + privKeyPath) }
// openssl genrsa -out app.rsa keysize
privKeyPath := fmt.Sprintf("%vapp.rsa", p)
signKey, err = ioutil.ReadFile(privKeyPath)
if err != nil { if err != nil {
log.Fatalf("Error reading private key: ", err) log.Fatalf("Error reading private key: ", err)
return return err
}
} }
// openssl rsa -in app.rsa -pubout > app.rsa.pub
pubKeyPath := fmt.Sprintf("%vapp.rsa.pub", p)
verifyKey, err = ioutil.ReadFile(pubKeyPath) verifyKey, err = ioutil.ReadFile(pubKeyPath)
if err != nil {
// Before exploding, check up one level...
verifyKey, err = ioutil.ReadFile("../" + pubKeyPath)
if err != nil { if err != nil {
log.Fatalf("Error reading public key: ", err) log.Fatalf("Error reading public key: ", err)
return return err
}
} }
return nil
} }
type authHandler func(http.ResponseWriter, *http.Request) error type authHandler func(http.ResponseWriter, *http.Request) error

View file

@ -1,125 +1,83 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"os" "os"
"github.com/codegangsta/cli"
"github.com/thermokarst/bactdb/api" "github.com/thermokarst/bactdb/api"
"github.com/thermokarst/bactdb/datastore" "github.com/thermokarst/bactdb/datastore"
) )
func init() {
flag.Usage = func() {
fmt.Fprintln(os.Stderr, `bactdb is a database for bacteria.
Usage:
bactdb [options] command [arg...]
The commands are:
`)
for _, c := range subcmds {
fmt.Fprintf(os.Stderr, " %-24s %s\n", c.name, c.description)
}
fmt.Fprintln(os.Stderr, `
Use "bactdb command -h" for more information about a command.
The options are:
`)
flag.PrintDefaults()
os.Exit(1)
}
}
func main() { func main() {
flag.Parse() app := cli.NewApp()
app.Name = "bactdb"
app.Usage = "a database for bacteria"
if flag.NArg() == 0 { app.Commands = []cli.Command{
flag.Usage() {
} Name: "serve",
log.SetFlags(0) ShortName: "s",
Usage: "Start web server",
subcmd := flag.Arg(0) Flags: []cli.Flag{
for _, c := range subcmds { cli.IntFlag{
if c.name == subcmd { Name: "port",
c.run(flag.Args()[1:]) Usage: "HTTP service port",
return Value: 8901,
} },
cli.StringFlag{
Name: "keys",
Usage: "path to keys",
Value: "keys/",
},
},
Action: cmdServe,
},
{
Name: "createdb",
ShortName: "c",
Usage: "create the database schema",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "drop",
Usage: "drop DB before creating",
},
cli.StringFlag{
Name: "migration_path",
Usage: "path to migrations",
Value: "./datastore/migrations",
},
},
Action: cmdCreateDB,
},
} }
fmt.Fprintf(os.Stderr, "unknown subcmd %q\n", subcmd) app.Run(os.Args)
fmt.Fprintln(os.Stderr, `Run "bactdb -h" for usage.`)
os.Exit(1)
} }
type subcmd struct { func cmdServe(c *cli.Context) {
name string httpAddr := fmt.Sprintf(":%v", c.Int("port"))
description string
run func(args []string)
}
var subcmds = []subcmd{
{"serve", "start web server", serveCmd},
{"createdb", "create the database schema", createDBCmd},
}
func serveCmd(args []string) {
fs := flag.NewFlagSet("serve", flag.ExitOnError)
httpAddr := flag.String("http", ":8901", "HTTP service address")
fs.Usage = func() {
fmt.Fprintln(os.Stderr, `usage: bactdb serve [options]
Starts the web server that serves the API.
The options are:
`)
fs.PrintDefaults()
os.Exit(1)
}
fs.Parse(args)
if fs.NArg() != 0 {
fs.Usage()
}
datastore.Connect() datastore.Connect()
api.SetupCerts(c.String("keys"))
m := http.NewServeMux() m := http.NewServeMux()
m.Handle("/api/", http.StripPrefix("/api", api.Handler())) m.Handle("/api/", http.StripPrefix("/api", api.Handler()))
log.Print("Listening on ", httpAddr)
log.Print("Listening on ", *httpAddr) err := http.ListenAndServe(httpAddr, m)
err := http.ListenAndServe(*httpAddr, m)
if err != nil { if err != nil {
log.Fatal("ListenAndServe: ", err) log.Fatal("ListenAndServe: ", err)
} }
} }
func createDBCmd(args []string) { func cmdCreateDB(c *cli.Context) {
fs := flag.NewFlagSet("createdb", flag.ExitOnError) migrationsPath := c.String("migration_path")
drop := fs.Bool("drop", false, "drop DB before creating")
fs.Usage = func() {
fmt.Fprintln(os.Stderr, `usage: bactdb createdb [options]
Creates the necessary DB schema.
The options are:
`)
fs.PrintDefaults()
os.Exit(1)
}
fs.Parse(args)
if fs.NArg() != 0 {
fs.Usage()
}
datastore.Connect() datastore.Connect()
migrationsPath := "./datastore/migrations"
if *drop { if c.Bool("drop") {
datastore.Drop(migrationsPath) datastore.Drop(migrationsPath)
} }
datastore.Create(migrationsPath) datastore.Create(migrationsPath)