internal/database: start refactoring Storage into smaller interfaces
This commit is contained in:
parent
91ef642b7f
commit
e6084cd874
|
@ -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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue