diff --git a/internal/database/cert.go b/internal/database/cert.go index 2d4aefd..c4acb60 100644 --- a/internal/database/cert.go +++ b/internal/database/cert.go @@ -1,5 +1,23 @@ 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 // with. type CryptoLevel int @@ -20,3 +38,35 @@ type CachedCert struct { // PEM-encoded bytes with the above crypto level as a filter. 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, + }) +} diff --git a/internal/database/route.go b/internal/database/route.go index bc2b9c1..c4b9fa6 100644 --- a/internal/database/route.go +++ b/internal/database/route.go @@ -1,10 +1,26 @@ package database import ( + "io" + proto "git.xeserv.us/xena/route/proto" "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. type Route struct { 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 { return &proto.Route{ Id: r.ID, diff --git a/internal/database/storage.go b/internal/database/storage.go index 5c34e23..afdaa6b 100644 --- a/internal/database/storage.go +++ b/internal/database/storage.go @@ -1,8 +1,6 @@ package database import ( - "github.com/asdine/storm" - "golang.org/x/crypto/acme/autocert" "golang.org/x/net/context" ) @@ -30,35 +28,3 @@ type Storage interface { 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, - }) -} diff --git a/internal/database/token.go b/internal/database/token.go index 7d50c20..5489947 100644 --- a/internal/database/token.go +++ b/internal/database/token.go @@ -1,11 +1,28 @@ package database -import "time" import ( + "io" + "time" + proto "git.xeserv.us/xena/route/proto" "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. type Token struct { ID string `storm:"id"` @@ -14,19 +31,28 @@ type Token struct { Scopes []string CreatedAt time.Time `json:"created_at"` + ExpiresAt time.Time `json:"expires_at"` Active bool `json:"active"` } // F https://godoc.org/github.com/Xe/ln#F func (t Token) F() ln.F { - return ln.F{ - "token-id": t.ID, - "token-owner": t.Owner, - "token-active": t.Active, + f := ln.F{ + "token-id": t.ID, + "token-owner": t.Owner, + "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 { return &proto.Token{ Id: t.ID,