internal/database: start refactoring Storage into smaller interfaces

This commit is contained in:
Cadey Ratio 2017-12-15 12:56:20 -08:00
parent 91ef642b7f
commit e6084cd874
4 changed files with 99 additions and 41 deletions

View File

@ -1,5 +1,23 @@
package database package database
import (
"io"
"github.com/asdine/storm"
"golang.org/x/crypto/acme/autocert"
"golang.org/x/net/context"
)
// Certs is the set of API calls needed to manage certificate resources.
//
// Database backends should implement this interface, they will not need
// to implement certificate decryption, as that will be handled in the layer
// above this DAO.
type Certs interface {
io.Closer
autocert.Cache
}
// CryptoLevel indicates what form of cryptography the certificate is stored // CryptoLevel indicates what form of cryptography the certificate is stored
// with. // with.
type CryptoLevel int type CryptoLevel int
@ -20,3 +38,35 @@ type CachedCert struct {
// PEM-encoded bytes with the above crypto level as a filter. // PEM-encoded bytes with the above crypto level as a filter.
Body []byte Body []byte
} }
type storageManager struct {
Storage
}
func (s *storageManager) Get(ctx context.Context, key string) ([]byte, error) {
data, err := s.GetCert(ctx, key)
if err != nil {
if err == storm.ErrNotFound {
return nil, autocert.ErrCacheMiss
} else {
return nil, err
}
}
return data, nil
}
func (s *storageManager) Put(ctx context.Context, key string, data []byte) error {
return s.PutCert(ctx, key, data)
}
func (s *storageManager) Delete(ctx context.Context, key string) error {
return s.DeleteCert(ctx, key)
}
// Cache creates an autocert.Cache from a Storage instance.
func Cache(s Storage) autocert.Cache {
return autocert.Cache(&storageManager{
Storage: s,
})
}

View File

@ -1,10 +1,26 @@
package database package database
import ( import (
"io"
proto "git.xeserv.us/xena/route/proto" proto "git.xeserv.us/xena/route/proto"
"github.com/Xe/ln" "github.com/Xe/ln"
"golang.org/x/net/context"
) )
// Routes is the set of API calls needed to manage Route resources.
//
// Database backends should implement this interface.
type Routes interface {
io.Closer
Get(ctx context.Context, id string) (Route, error)
GetHost(ctx context.Context, host string) (Route, error)
GetAll(ctx context.Context, user string) ([]Route, error)
Put(ctx context.Context, r Route) (Route, error)
Delete(ctx context.Context, r Route) (Route, error)
}
// Route is a single HTTP route. // Route is a single HTTP route.
type Route struct { type Route struct {
ID string `storm:"id"` ID string `storm:"id"`
@ -21,7 +37,7 @@ func (r Route) F() ln.F {
} }
} }
// AsProto converts this into the protobuf. // AsProto converts this into a protobuf Route.
func (r Route) AsProto() *proto.Route { func (r Route) AsProto() *proto.Route {
return &proto.Route{ return &proto.Route{
Id: r.ID, Id: r.ID,

View File

@ -1,8 +1,6 @@
package database package database
import ( import (
"github.com/asdine/storm"
"golang.org/x/crypto/acme/autocert"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -30,35 +28,3 @@ type Storage interface {
Close() error Close() error
} }
type storageManager struct {
Storage
}
func (s *storageManager) Get(ctx context.Context, key string) ([]byte, error) {
data, err := s.GetCert(ctx, key)
if err != nil {
if err == storm.ErrNotFound {
return nil, autocert.ErrCacheMiss
} else {
return nil, err
}
}
return data, nil
}
func (s *storageManager) Put(ctx context.Context, key string, data []byte) error {
return s.PutCert(ctx, key, data)
}
func (s *storageManager) Delete(ctx context.Context, key string) error {
return s.DeleteCert(ctx, key)
}
// Cache creates an autocert.Cache from a Storage instance.
func Cache(s Storage) autocert.Cache {
return autocert.Cache(&storageManager{
Storage: s,
})
}

View File

@ -1,11 +1,28 @@
package database package database
import "time"
import ( import (
"io"
"time"
proto "git.xeserv.us/xena/route/proto" proto "git.xeserv.us/xena/route/proto"
"github.com/Xe/ln" "github.com/Xe/ln"
"golang.org/x/net/context"
) )
// Tokens is the set of API calls needed to manage Token resources.
//
// Database backends should implement this interface.
type Tokens interface {
io.Closer
Get(ctx context.Context, id string) (Token, error)
GetBody(ctx context.Context, body string) (Token, error)
GetAll(ctx context.Context, user string) ([]Token, error)
Put(ctx context.Context, t Token) (Token, error)
Delete(ctx context.Context, id string) (Token, error)
DeleteExpired(ctx context.Context) error
}
// Token is a single authorization token. // Token is a single authorization token.
type Token struct { type Token struct {
ID string `storm:"id"` ID string `storm:"id"`
@ -14,19 +31,28 @@ type Token struct {
Scopes []string Scopes []string
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
Active bool `json:"active"` Active bool `json:"active"`
} }
// F https://godoc.org/github.com/Xe/ln#F // F https://godoc.org/github.com/Xe/ln#F
func (t Token) F() ln.F { func (t Token) F() ln.F {
return ln.F{ f := ln.F{
"token-id": t.ID, "token-id": t.ID,
"token-owner": t.Owner, "token-owner": t.Owner,
"token-active": t.Active, "token-active": t.Active,
"token-scopes": t.Scopes,
"token-created-at": t.CreatedAt.String(),
} }
if !t.ExpiresAt.IsZero() {
f["token-expires-at"] = t.ExpiresAt.String()
}
return f
} }
// AsProto ... // AsProto converts this into a protobuf Token.
func (t Token) AsProto() *proto.Token { func (t Token) AsProto() *proto.Token {
return &proto.Token{ return &proto.Token{
Id: t.ID, Id: t.ID,