cmd/routed: use split database handlers

This commit is contained in:
Cadey Ratio 2018-01-21 11:08:43 -08:00
parent e91d1bb2b1
commit 2d2f894517
10 changed files with 178 additions and 147 deletions

View File

@ -170,7 +170,13 @@ retry_netrc:
tBody := uuid.New() tBody := uuid.New()
_, err = db.PutToken(context.Background(), tBody, *tokenGenerateUsername, *tokenGenerateScopes) tok := database.Token{
Body: uuid.New(),
Owner: *tokenGenerateUsername,
Scopes: *tokenGenerateScopes,
}
_, err = db.Tokens().Put(context.Background(), tok)
if err != nil { if err != nil {
ln.FatalErr(ctx, err, ln.Action("add newly created token to database")) ln.FatalErr(ctx, err, ln.Action("add newly created token to database"))
} }

View File

@ -60,7 +60,7 @@ func (s *Server) makeTwirpHooks() *twirp.ServerHooks {
tok := ck.Value tok := ck.Value
t, err := s.db.GetToken(ctx, tok) t, err := s.db.Tokens().Get(ctx, tok)
if err != nil { if err != nil {
return ctx, err return ctx, err
} }
@ -94,6 +94,13 @@ func (s *Server) makeTwirpHooks() *twirp.ServerHooks {
"twirp_error_msg": e.Msg(), "twirp_error_msg": e.Msg(),
}) })
tr, ok := trace.FromContext(ctx)
if !ok {
return ctx
}
tr.SetError()
return ctx return ctx
} }
@ -108,6 +115,12 @@ func (s *Server) getAuth(ctx context.Context, operation, scope string) (database
ok = false ok = false
for _, sc := range t.Scopes { for _, sc := range t.Scopes {
// the "admin" scope is implicitly allowed for everything.
if sc == "admin" {
ok = true
break
}
if sc == scope { if sc == scope {
ok = true ok = true
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"git.xeserv.us/xena/route/internal/database"
"git.xeserv.us/xena/route/internal/elfs" "git.xeserv.us/xena/route/internal/elfs"
proto "git.xeserv.us/xena/route/proto" proto "git.xeserv.us/xena/route/proto"
"github.com/Xe/ln" "github.com/Xe/ln"
@ -24,7 +25,7 @@ func (r *Route) Get(ctx context.Context, req *proto.GetRouteRequest) (*proto.Rou
return nil, handleError(ctx, clitok, err, ln.F{"action": "Route.Get_getAuth"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "Route.Get_getAuth"})
} }
val, err := r.db.GetRoute(ctx, req.Id) val, err := r.db.Routes().Get(ctx, req.Id)
if err != nil { if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "get single route from database", "id": req.Id}) return nil, handleError(ctx, clitok, err, ln.F{"action": "get single route from database", "id": req.Id})
} }
@ -43,7 +44,7 @@ func (r *Route) GetAll(ctx context.Context, req *proto.Nil) (*proto.GetAllRoutes
return nil, handleError(ctx, clitok, err, ln.F{"action": "Route.GetAll_getAuth"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "Route.GetAll_getAuth"})
} }
routes, err := r.db.GetAllRoutes(ctx, clitok.Owner) routes, err := r.db.Routes().GetAll(ctx, clitok.Owner)
if err != nil { if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "get all routes for user from database"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "get all routes for user from database"})
} }
@ -70,12 +71,18 @@ func (r *Route) Put(ctx context.Context, rt *proto.Route) (*proto.Route, error)
rt.Host = elfs.MakeName() + r.cfg.DomainSuffix rt.Host = elfs.MakeName() + r.cfg.DomainSuffix
} }
drt, err := r.db.PutRoute(ctx, rt.Host, clitok.Owner) rr := database.Route{
ID: rt.Id,
Hostname: rt.Host,
Creator: clitok.Owner,
}
drt, err := r.db.Routes().Put(ctx, rr)
if err != nil { if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "put route to database"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "put route to database"})
} }
ln.Log(ctx, drt, ln.Action("created new route")) ln.Log(ctx, drt, ln.Action("put route to database"))
return drt.AsProto(), nil return drt.AsProto(), nil
} }
@ -86,7 +93,7 @@ func (r *Route) Delete(ctx context.Context, rt *proto.Route) (*proto.Nil, error)
return nil, handleError(ctx, clitok, err, ln.F{"action": "Route.Delete_getAuth"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "Route.Delete_getAuth"})
} }
drt, err := r.db.GetRoute(ctx, rt.Host) drt, err := r.db.Routes().Get(ctx, rt.Host)
if err != nil { if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "fetch route from database", "host": rt.Host}) return nil, handleError(ctx, clitok, err, ln.F{"action": "fetch route from database", "host": rt.Host})
} }
@ -95,7 +102,7 @@ func (r *Route) Delete(ctx context.Context, rt *proto.Route) (*proto.Nil, error)
return nil, handleError(ctx, clitok, ErrNotAuthorized, ln.F{"action": "user not authorized to delete this route", "host": rt.Host}) return nil, handleError(ctx, clitok, ErrNotAuthorized, ln.F{"action": "user not authorized to delete this route", "host": rt.Host})
} }
err = r.db.DeleteRoute(ctx, rt.Id) _, err = r.db.Routes().Delete(ctx, database.Route{ID: rt.Id})
f := drt.F() f := drt.F()
f["action"] = "delete route from database" f["action"] = "delete route from database"
if err != nil { if err != nil {

View File

@ -16,7 +16,7 @@ var (
) )
func (s *storageWrapper) HasToken(token string) (string, []string, error) { func (s *storageWrapper) HasToken(token string) (string, []string, error) {
t, err := s.Storage.GetToken(context.Background(), token) t, err := s.Storage.Tokens().Get(context.Background(), token)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
@ -25,7 +25,7 @@ func (s *storageWrapper) HasToken(token string) (string, []string, error) {
} }
func (s *storageWrapper) HasRoute(domain string) (string, error) { func (s *storageWrapper) HasRoute(domain string) (string, error) {
r, err := s.Storage.GetRouteHost(context.Background(), domain) r, err := s.Storage.Routes().GetHost(context.Background(), domain)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -1,6 +1,9 @@
package main package main
import ( import (
"errors"
"git.xeserv.us/xena/route/internal/database"
proto "git.xeserv.us/xena/route/proto" proto "git.xeserv.us/xena/route/proto"
"github.com/Xe/ln" "github.com/Xe/ln"
"github.com/Xe/uuid" "github.com/Xe/uuid"
@ -29,7 +32,7 @@ func (t *Token) Get(ctx context.Context, req *proto.GetTokenRequest) (*proto.Tok
return nil, status.Errorf(codes.InvalidArgument, "must specify ID") return nil, status.Errorf(codes.InvalidArgument, "must specify ID")
} }
dbt, err := t.db.GetTokenID(ctx, req.Id) dbt, err := t.db.Tokens().Get(ctx, req.Id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -47,7 +50,7 @@ func (t *Token) GetAll(ctx context.Context, req *proto.Nil) (*proto.TokenSet, er
return nil, handleError(ctx, clitok, err, ln.F{"action": "Token.GetAll_getAuth"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "Token.GetAll_getAuth"})
} }
toks, err := t.db.GetTokensForOwner(ctx, clitok.Owner) toks, err := t.db.Tokens().GetAll(ctx, clitok.Owner)
if err != nil { if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "Token.GetAll_db.GetTokensForOwner"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "Token.GetAll_db.GetTokensForOwner"})
} }
@ -69,7 +72,13 @@ func (t *Token) Put(ctx context.Context, tok *proto.Token) (*proto.Token, error)
return nil, handleError(ctx, clitok, err, ln.F{"action": "not authorized"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "not authorized"})
} }
dbt, err := t.db.PutToken(ctx, uuid.New(), clitok.Owner, tok.Scopes) dtok := database.Token{
ID: uuid.New(),
Owner: clitok.Owner,
Scopes: tok.Scopes,
}
dbt, err := t.db.Tokens().Put(ctx, dtok)
if err != nil { if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "put token into database", "scopes": tok.Scopes}) return nil, handleError(ctx, clitok, err, ln.F{"action": "put token into database", "scopes": tok.Scopes})
} }
@ -85,7 +94,7 @@ func (t *Token) Delete(ctx context.Context, tok *proto.Token) (*proto.Nil, error
return nil, handleError(ctx, clitok, err, ln.F{"action": "not authorized"}) return nil, handleError(ctx, clitok, err, ln.F{"action": "not authorized"})
} }
err = t.db.DeleteToken(ctx, tok.Id) _, err = t.db.Tokens().Delete(ctx, tok.Id)
if err != nil { if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "delete token from database", "token_id": tok.Id}) return nil, handleError(ctx, clitok, err, ln.F{"action": "delete token from database", "token_id": tok.Id})
} }
@ -96,17 +105,5 @@ func (t *Token) Delete(ctx context.Context, tok *proto.Token) (*proto.Nil, error
} }
func (t *Token) Deactivate(ctx context.Context, tok *proto.Token) (*proto.Nil, error) { func (t *Token) Deactivate(ctx context.Context, tok *proto.Token) (*proto.Nil, error) {
clitok, err := t.getAuth(ctx, "deactivate single token", "token:deactivate") return nil, errors.New("not implemented")
if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "not authorized"})
}
err = t.db.DeactivateToken(ctx, tok.Id)
if err != nil {
return nil, handleError(ctx, clitok, err, ln.F{"action": "deactivate token in database", "token_id": tok.Id})
}
ln.Log(ctx, clitok, ln.Action("deactivated token"), ln.F{"token_id": tok.Id})
return &proto.Nil{}, nil
} }

View File

@ -29,6 +29,22 @@ var (
type BoltDBStorage struct { type BoltDBStorage struct {
db *storm.DB db *storm.DB
sb *simplebox.SimpleBox sb *simplebox.SimpleBox
cs *boltCertificateStorage
rs *boltRouteStorage
ts *boltTokenStorage
}
type boltCertificateStorage struct {
*BoltDBStorage
}
type boltRouteStorage struct {
*BoltDBStorage
}
type boltTokenStorage struct {
*BoltDBStorage
} }
// NewBoltStorage creates a new Storage instance backed by BoltDB + Storm. // NewBoltStorage creates a new Storage instance backed by BoltDB + Storm.
@ -43,24 +59,43 @@ func NewBoltStorage(path string, key *[32]byte) (Storage, error) {
sb: simplebox.NewFromSecretKey(key), sb: simplebox.NewFromSecretKey(key),
} }
b.cs = &boltCertificateStorage{b}
b.rs = &boltRouteStorage{b}
b.ts = &boltTokenStorage{b}
return Storage(b), nil return Storage(b), nil
} }
// Certs gets the certificate storage interface.
func (b *BoltDBStorage) Certs() Certs { return b.cs }
// Routes gets the route storage interface.
func (b *BoltDBStorage) Routes() Routes { return b.rs }
// Tokens gets the token storage interface.
func (b *BoltDBStorage) Tokens() Tokens { return b.ts }
// Close cleans up resources for this Storage.
func (b *BoltDBStorage) Close() error { return b.db.Close() }
// interface compliance // interface compliance
var ( var (
_ Storage = &BoltDBStorage{} _ Storage = &BoltDBStorage{}
_ Certs = &boltCertificateStorage{}
_ Routes = &boltRouteStorage{}
_ Tokens = &boltTokenStorage{}
) )
func (b *BoltDBStorage) GetRoute(ctx context.Context, id string) (Route, error) { func (b *boltRouteStorage) Get(ctx context.Context, id string) (Route, error) {
return b.getRouteBy(ctx, "ID", id) return b.getRouteBy(ctx, "ID", id)
} }
func (b *BoltDBStorage) GetRouteHost(ctx context.Context, id string) (Route, error) { func (b *boltRouteStorage) GetHost(ctx context.Context, id string) (Route, error) {
return b.getRouteBy(ctx, "Hostname", id) return b.getRouteBy(ctx, "Hostname", id)
} }
// getRouteBy gets a single route out of the database by a given field data. // getRouteBy gets a single route out of the database by a given field data.
func (b *BoltDBStorage) getRouteBy(ctx context.Context, match, val string) (Route, error) { func (b *boltRouteStorage) getRouteBy(ctx context.Context, match, val string) (Route, error) {
r := Route{} r := Route{}
err := b.db.One(match, val, &r) err := b.db.One(match, val, &r)
if err != nil { if err != nil {
@ -79,19 +114,17 @@ func (b *BoltDBStorage) getRouteBy(ctx context.Context, match, val string) (Rout
return r, nil return r, nil
} }
// GetAllRoutes gets all routes out of the database for a given user by username. // GetAll gets all routes out of the database for a given user by username.
func (b *BoltDBStorage) GetAllRoutes(ctx context.Context, user string) ([]Route, error) { func (b *boltRouteStorage) GetAll(ctx context.Context, user string) ([]Route, error) {
rs := []Route{} rs := []Route{}
err := b.db.All(&rs) err := b.db.All(&rs)
return rs, err return rs, err
} }
// PutRoute creates a new route in the database. // Put creates a new route in the database.
func (b *BoltDBStorage) PutRoute(ctx context.Context, domain, creator string) (Route, error) { func (b *boltRouteStorage) Put(ctx context.Context, r Route) (Route, error) {
r := Route{ if r.ID == "" {
ID: uuid.New(), r.ID = uuid.New()
Creator: creator,
Hostname: domain,
} }
err := b.db.Save(&r) err := b.db.Save(&r)
@ -105,30 +138,30 @@ func (b *BoltDBStorage) PutRoute(ctx context.Context, domain, creator string) (R
return r, err return r, err
} }
// DeleteRoute removes a route from the database. // Delete removes a route from the database.
func (b *BoltDBStorage) DeleteRoute(ctx context.Context, id string) error { func (b *boltRouteStorage) Delete(ctx context.Context, inp Route) (Route, error) {
r := Route{} r := Route{}
err := b.db.One("ID", id, &r) err := b.db.One("ID", inp.ID, &r)
if err != nil { if err != nil {
return err return r, err
} }
defer b.db.Commit() defer b.db.Commit()
ln.Log(ctx, r, ln.Action("route deleted from database")) ln.Log(ctx, r, ln.Action("route deleted from database"))
return b.db.DeleteStruct(&r) return r, b.db.DeleteStruct(&r)
} }
// GetToken fetches a token from the database. This is mainly used in validation // GetBody fetches a token from the database. This is mainly used in validation
// of tokens. // of tokens.
func (b *BoltDBStorage) GetToken(ctx context.Context, token string) (Token, error) { func (b *boltTokenStorage) GetBody(ctx context.Context, token string) (Token, error) {
t := Token{} t := Token{}
err := b.db.One("Body", token, &t) err := b.db.One("Body", token, &t)
return t, err return t, err
} }
// GetTokenID fetches a token by a given token ID. // Get fetches a token by a given token ID.
func (b *BoltDBStorage) GetTokenID(ctx context.Context, id string) (Token, error) { func (b *boltTokenStorage) Get(ctx context.Context, id string) (Token, error) {
t := Token{} t := Token{}
err := b.db.One("ID", id, &t) err := b.db.One("ID", id, &t)
if err != nil { if err != nil {
@ -143,23 +176,19 @@ func (b *BoltDBStorage) GetTokenID(ctx context.Context, id string) (Token, error
return t, nil return t, nil
} }
// GetTokensForOwner fetches all of the tokens owned by a given owner. // GetAll fetches all of the tokens owned by a given owner.
func (b *BoltDBStorage) GetTokensForOwner(ctx context.Context, owner string) ([]Token, error) { func (b *boltTokenStorage) GetAll(ctx context.Context, owner string) ([]Token, error) {
ts := []Token{} ts := []Token{}
err := b.db.Find("Owner", owner, &ts) err := b.db.Find("Owner", owner, &ts)
return ts, err return ts, err
} }
// PutToken adds a new token to the database. // Put adds a new token to the database.
func (b *BoltDBStorage) PutToken(ctx context.Context, token, owner string, scopes []string) (Token, error) { func (b *boltTokenStorage) Put(ctx context.Context, t Token) (Token, error) {
t := Token{ if t.ID == "" {
ID: uuid.New(), t.ID = uuid.New()
Body: token, t.CreatedAt = time.Now()
Owner: owner, t.Active = true
Scopes: scopes,
CreatedAt: time.Now(),
Active: true,
} }
err := b.db.Save(&t) err := b.db.Save(&t)
@ -173,38 +202,53 @@ func (b *BoltDBStorage) PutToken(ctx context.Context, token, owner string, scope
return t, nil return t, nil
} }
// DeleteToken removes a token from the database. // Delete removes a token from the database.
func (b *BoltDBStorage) DeleteToken(ctx context.Context, id string) error { func (b *boltTokenStorage) Delete(ctx context.Context, id string) (Token, error) {
t := Token{} t := Token{}
err := b.db.One("ID", id, &t) err := b.db.One("ID", id, &t)
if err != nil { if err != nil {
return err return t, err
} }
ln.Log(ctx, t, ln.Action("token deleted from database")) ln.Log(ctx, t, ln.Action("token deleted from database"))
return b.db.DeleteStruct(&t) return t, b.db.DeleteStruct(&t)
} }
// DeactivateToken de-activates a token in the database. This should be used // DeleteExpired deletes all expired tokens.
// instead of deletion in many cases. func (b *boltTokenStorage) DeleteExpired(ctx context.Context) error {
func (b *BoltDBStorage) DeactivateToken(ctx context.Context, id string) error { return errors.New("not implemented")
t := Token{} }
err := b.db.One("ID", id, &t)
// GetAll fetches all certificates and returns their DECRYPTED BODIES to the caller.
// This is intended for usage in migration tools only.
func (b *boltCertificateStorage) GetAll(ctx context.Context) ([]CachedCert, error) {
var cc []CachedCert
err := b.db.All(&cc)
if err != nil { if err != nil {
return err return nil, err
} }
defer b.db.Commit()
t.Active = false var result []CachedCert
ln.Log(ctx, t, ln.Action("token deactivated")) for _, c := range cc {
r := CachedCert{
Key: c.Key,
}
return b.db.Save(&t) r.Body, err = b.sb.Decrypt(c.Body)
if err != nil {
return nil, err
}
result = append(result, r)
}
return result, nil
} }
// GetCert fetches a TLS certificate from the database. // Get fetches a TLS certificate from the database.
func (b *BoltDBStorage) GetCert(ctx context.Context, key string) ([]byte, error) { func (b *boltCertificateStorage) Get(ctx context.Context, key string) ([]byte, error) {
cc := CachedCert{} cc := CachedCert{}
err := b.db.One("Key", key, &cc) err := b.db.One("Key", key, &cc)
if err != nil { if err != nil {
@ -213,33 +257,26 @@ func (b *BoltDBStorage) GetCert(ctx context.Context, key string) ([]byte, error)
var body []byte var body []byte
switch cc.CryptoLevel { if b.sb == nil {
case CryptoLevelNone: return nil, ErrCantDecryptCert
body = cc.Body }
case CryptoLevelSecretbox:
if b.sb == nil {
return nil, ErrCantDecryptCert
}
body, err = b.sb.Decrypt(cc.Body) body, err = b.sb.Decrypt(cc.Body)
if err != nil { if err != nil {
return nil, err return nil, err
}
} }
return body, nil return body, nil
} }
// PutCert adds a new TLS certificate to the database. // Put adds a new TLS certificate to the database.
func (b *BoltDBStorage) PutCert(ctx context.Context, key string, data []byte) error { func (b *boltCertificateStorage) Put(ctx context.Context, key string, data []byte) error {
cc := CachedCert{ cc := CachedCert{
Key: key, Key: key,
CryptoLevel: CryptoLevelNone, Body: data,
Body: data,
} }
if b.sb != nil { if b.sb != nil {
cc.CryptoLevel = CryptoLevelSecretbox
cc.Body = b.sb.Encrypt(data) cc.Body = b.sb.Encrypt(data)
} }
@ -250,8 +287,8 @@ func (b *BoltDBStorage) PutCert(ctx context.Context, key string, data []byte) er
return b.db.Save(&cc) return b.db.Save(&cc)
} }
// DeleteCert removes a certificate from the database. // Delete removes a certificate from the database.
func (b *BoltDBStorage) DeleteCert(ctx context.Context, key string) error { func (b *boltCertificateStorage) Delete(ctx context.Context, key string) error {
cc := CachedCert{} cc := CachedCert{}
err := b.db.One("Key", key, &cc) err := b.db.One("Key", key, &cc)
if err != nil { if err != nil {
@ -264,8 +301,3 @@ func (b *BoltDBStorage) DeleteCert(ctx context.Context, key string) error {
return b.db.DeleteStruct(&cc) return b.db.DeleteStruct(&cc)
} }
// Close ...
func (b *BoltDBStorage) Close() error {
return b.db.Close()
}

View File

@ -16,27 +16,17 @@ import (
type Certs interface { type Certs interface {
io.Closer io.Closer
autocert.Cache autocert.Cache
GetAll(ctx context.Context) ([]CachedCert, error)
} }
// CryptoLevel indicates what form of cryptography the certificate is stored
// with.
type CryptoLevel int
// Crypto levels / strategies defined
const (
// NOTE: this is defined for debugging / testing usage only
CryptoLevelNone CryptoLevel = iota
// Use the global set of secretbox keys
CryptoLevelSecretbox
)
// CachedCert is an individual cached certificate in the database. // CachedCert is an individual cached certificate in the database.
type CachedCert struct { type CachedCert struct {
Key string `storm:"id"` Key string `storm:"id" db:"domain"`
CryptoLevel CryptoLevel
// PEM-encoded bytes with the above crypto level as a filter. // Encrypted data
Body []byte Data string `storm:"-" db:"data"`
Body []byte // above as a byte slice
} }
type storageManager struct { type storageManager struct {
@ -44,24 +34,24 @@ type storageManager struct {
} }
func (s *storageManager) Get(ctx context.Context, key string) ([]byte, error) { func (s *storageManager) Get(ctx context.Context, key string) ([]byte, error) {
data, err := s.GetCert(ctx, key) data, err := s.Certs().Get(ctx, key)
if err != nil { if err != nil {
if err == storm.ErrNotFound { if err == storm.ErrNotFound {
return nil, autocert.ErrCacheMiss return nil, autocert.ErrCacheMiss
} else {
return nil, err
} }
return nil, err
} }
return data, nil return data, nil
} }
func (s *storageManager) Put(ctx context.Context, key string, data []byte) error { func (s *storageManager) Put(ctx context.Context, key string, data []byte) error {
return s.PutCert(ctx, key, data) return s.Certs().Put(ctx, key, data)
} }
func (s *storageManager) Delete(ctx context.Context, key string) error { func (s *storageManager) Delete(ctx context.Context, key string) error {
return s.DeleteCert(ctx, key) return s.Certs().Delete(ctx, key)
} }
// Cache creates an autocert.Cache from a Storage instance. // Cache creates an autocert.Cache from a Storage instance.

View File

@ -194,7 +194,7 @@ func migrations1513982254_tokensUpSql() (*asset, error) {
return a, nil return a, nil
} }
var _migrationsPostgresSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x94\xdf\xeb\xda\x30\x14\xc5\xdf\xf3\x57\xdc\x37\x15\x9a\x87\x3d\x0d\x26\x52\x44\x33\x56\xa8\x0a\xb5\xdb\x1e\x25\x36\xd7\x2d\xac\x36\x92\x44\x99\xff\xfd\x48\x1b\xb5\xa9\x3f\x28\xe3\x2b\xf4\xa1\xa4\xdc\x73\x3e\xf7\xf4\xb4\x94\x42\xc5\xf7\xf8\x05\x64\x65\x50\x5b\x5a\xa0\xb6\x72\x27\x0b\x6e\x91\x90\x64\xb9\x66\x59\x0e\xc9\x32\x5f\xc1\xec\xf6\xc0\x10\x80\xa1\x50\x7b\x2e\xab\x08\x04\xb7\x7c\x44\x7e\x4c\xd3\xef\x6c\xed\xce\xe3\x08\xe2\xd1\x98\x90\xab\xf0\x4e\x56\x82\xaa\x0a\x43\xe9\x35\x4b\xd9\x2c\x77\x03\x52\x44\xd0\x16\x8b\xa0\xd0\xc8\x2d\x8a\x0d\xb7\x11\xa0\x90\x97\x5b\x5e\x58\x79\xc2\x11\xf9\x9a\xad\x16\x21\xce\xcf\x6f\x2c\x63\x5e\x64\x12\x93\x34\x59\x24\x39\x7c\x6a\x43\x68\xdc\xab\x13\xde\x63\xcc\x59\xca\x72\xf6\x5f\x92\x3e\x30\xad\x8e\xdd\xa8\x08\x40\xe6\x4e\xcd\xb0\xde\x44\xe9\x08\x7e\x2b\x63\xdd\x58\xbf\xa4\x6a\x4d\xba\x3d\x53\x29\xba\x49\xdd\x29\xf6\x8b\xab\xe1\xf1\x5b\x49\xf1\x78\xa3\x7b\x7f\x67\xf2\x0e\x82\xcb\xe8\x0b\x0e\x5e\x96\x0d\x87\xa1\x3b\xa5\xe9\xd1\xa0\x7e\x07\x89\xd7\x98\xc4\x6d\x00\x81\x25\x5a\xbc\x45\x11\xf6\xa4\x3d\x4f\xa0\x4e\x13\xa6\xcb\x79\x9f\xb2\x58\xf5\x07\xab\xb0\x2c\xb9\x3b\xaa\xbf\xa8\xad\x12\xe7\xd6\x52\xa6\x50\x07\x34\x11\xe0\xdf\x83\xd4\x68\x36\xdc\x76\xcb\xd3\x5c\x41\x85\x7e\xa1\xad\xb1\xbd\x51\x98\xd7\x13\x83\x20\xb3\xab\x59\x27\x34\x8f\xf9\xba\x40\x81\xbb\xeb\x8f\x73\x7c\x1b\x85\x13\x7a\xce\xe1\xfa\x53\x73\x3c\xef\xcf\x87\x91\x3c\x2c\x51\xeb\x97\xe3\xdf\x46\xbb\x44\xbd\xf2\xf4\x12\x0d\x84\xf0\xeb\xbc\xd0\xb9\xd1\x02\x05\x59\x59\xd4\x27\x5e\xc2\xe0\x33\x08\x7e\x36\x83\x31\xf9\x17\x00\x00\xff\xff\x85\x3d\x18\x01\xed\x05\x00\x00") var _migrationsPostgresSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x94\x51\xeb\xda\x30\x14\xc5\xdf\xf3\x29\xee\xdb\xdf\x42\xf3\xb0\xa7\xc1\x44\x8a\x68\xc6\x0a\x55\xa1\x76\xdb\xa3\xc4\xe6\xba\x85\xd5\x46\x92\x28\xf3\xdb\x8f\xd4\xa8\x69\xd5\x22\x43\xc1\x07\x49\xc9\x39\xbf\x9c\x7b\x12\x4a\xa1\xe6\x5b\xfc\x02\xb2\x36\xa8\x2d\x2d\x51\x5b\xb9\x91\x25\xb7\x48\x48\x3a\x5f\xb2\xbc\x80\x74\x5e\x2c\x60\x72\xfd\x60\x08\xc0\x40\xa8\x2d\x97\x75\x0c\x82\x5b\x1e\x91\x1f\xe3\xec\x3b\x5b\xba\xf5\x24\x86\x24\x1a\x12\x72\x11\xde\xc8\x5a\x50\x55\x63\x5b\x7a\xc9\x32\x36\x29\xdc\x06\x29\x62\x08\xc5\x62\x28\x35\x72\x8b\x62\xc5\x6d\x0c\x28\xe4\xf9\x2f\x2f\xad\x3c\x60\x44\xbe\xe6\x8b\x59\x1b\xe7\xe7\x37\x96\x33\x2f\x32\x4a\x48\x96\xce\xd2\x02\x3e\x85\x10\x1a\xb7\xea\x80\xb7\x18\x53\x96\xb1\x82\xfd\x97\xe4\x2f\xb4\x94\x57\x55\xa8\x67\x5e\x7b\xae\xd0\xcd\x8f\x47\xab\x7d\x67\x30\x04\x20\x77\x8b\x66\xd0\xc8\x2b\x1d\xc3\x6f\x65\xac\xdb\xf5\xdc\x58\x1a\x49\xba\x3e\x52\x29\xba\xf8\x37\x8a\xcf\x9d\xe1\xc4\xe3\x23\x94\xe2\x7e\x7c\xb7\xfe\xce\xe4\x1d\x04\xe7\xad\x3d\x1c\x6e\x8e\x0d\x87\xa1\x1b\xa5\xe9\xde\xa0\x7e\x07\x89\xd7\x18\x25\x21\x80\xc0\x0a\x2d\x5e\xa3\x68\x97\x32\xdc\x4f\xa0\x49\x13\xc6\xf3\x69\x6f\x33\x7d\x57\xac\xfa\x83\x75\xfb\x12\x17\x6e\xa9\xb9\xbe\x6b\x25\x8e\xc1\xa1\x4c\xa9\x76\x68\x62\xc0\xbf\x3b\xa9\xd1\xac\xb8\xed\x96\xe7\xf4\x8b\xba\x37\xc0\x61\x7b\xa3\x76\x5e\x0f\x0c\x5a\x99\x5d\xcc\x3a\xa1\x79\xcc\xfe\x02\xb5\xdc\x5d\x7f\x9c\xe3\xdb\x28\x9c\x50\xff\x3b\xd0\x70\x3c\xee\xcf\xcb\x48\xee\x96\x28\x78\xdf\xfc\x34\xc2\x12\x3d\x95\xa7\x97\x38\x41\x08\x7f\x9c\x1e\x9d\x2b\x2d\x50\x90\xb5\x45\x7d\xe0\x15\x7c\x7c\x06\xc1\x8f\xe6\x63\x48\xfe\x05\x00\x00\xff\xff\x1c\x82\x69\x4c\x5a\x06\x00\x00")
func migrationsPostgresSqlBytes() ([]byte, error) { func migrationsPostgresSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -209,7 +209,7 @@ func migrationsPostgresSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "migrations/postgres.sql", size: 1517, mode: os.FileMode(420), modTime: time.Unix(1516557003, 0)} info := bindataFileInfo{name: "migrations/postgres.sql", size: 1626, mode: os.FileMode(420), modTime: time.Unix(1516558817, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }

View File

@ -20,9 +20,15 @@ FROM Certificates
WHERE domain=? WHERE domain=?
LIMIT 1; LIMIT 1;
-- name: get-all-certificates
SELECT
(id, domain, data, created_at, edited_at, active)
FROM Certificates;
-- name: insert-route -- name: insert-route
INSERT INTO INSERT INTO
Routes(creator, hostname) Routes(creator, hostname)
VALUES VALUES
(?, ?); (?, ?);

View File

@ -1,30 +1,10 @@
package database package database
import (
"golang.org/x/net/context"
)
// Storage is the parent interface for the database backends of route. // Storage is the parent interface for the database backends of route.
type Storage interface { type Storage interface {
// routes Certs() Certs
GetRoute(ctx context.Context, id string) (Route, error) Routes() Routes
GetRouteHost(ctx context.Context, host string) (Route, error) Tokens() Tokens
GetAllRoutes(ctx context.Context, user string) ([]Route, error)
PutRoute(ctx context.Context, domain, kind string) (Route, error)
DeleteRoute(ctx context.Context, id string) error
// tokens
GetToken(ctx context.Context, token string) (Token, error)
GetTokenID(ctx context.Context, id string) (Token, error)
GetTokensForOwner(ctx context.Context, owner string) ([]Token, error)
PutToken(ctx context.Context, token, owner string, scopes []string) (Token, error)
DeleteToken(ctx context.Context, id string) error
DeactivateToken(ctx context.Context, id string) error
// certificates
GetCert(ctx context.Context, key string) ([]byte, error)
PutCert(ctx context.Context, key string, data []byte) error
DeleteCert(ctx context.Context, key string) error
Close() error Close() error
} }