2016-07-08 21:32:31 +08:00
|
|
|
package storagetest
|
|
|
|
|
|
|
|
import (
|
2016-09-09 08:48:32 +08:00
|
|
|
"errors"
|
2016-07-08 21:32:31 +08:00
|
|
|
"net/url"
|
|
|
|
"sync"
|
2016-09-09 08:48:32 +08:00
|
|
|
|
|
|
|
"github.com/mholt/caddy/caddytls"
|
2016-07-08 21:32:31 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// memoryMutex is a mutex used to control access to memoryStoragesByCAURL.
|
|
|
|
var memoryMutex sync.Mutex
|
|
|
|
|
|
|
|
// memoryStoragesByCAURL is a map keyed by a CA URL string with values of
|
|
|
|
// instantiated memory stores. Do not access this directly, it is used by
|
|
|
|
// InMemoryStorageCreator.
|
|
|
|
var memoryStoragesByCAURL = make(map[string]*InMemoryStorage)
|
|
|
|
|
|
|
|
// InMemoryStorageCreator is a caddytls.Storage.StorageCreator to create
|
|
|
|
// InMemoryStorage instances for testing.
|
|
|
|
func InMemoryStorageCreator(caURL *url.URL) (caddytls.Storage, error) {
|
|
|
|
urlStr := caURL.String()
|
|
|
|
memoryMutex.Lock()
|
|
|
|
defer memoryMutex.Unlock()
|
|
|
|
storage := memoryStoragesByCAURL[urlStr]
|
|
|
|
if storage == nil {
|
|
|
|
storage = NewInMemoryStorage()
|
|
|
|
memoryStoragesByCAURL[urlStr] = storage
|
|
|
|
}
|
|
|
|
return storage, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// InMemoryStorage is a caddytls.Storage implementation for use in testing.
|
|
|
|
// It simply stores information in runtime memory.
|
|
|
|
type InMemoryStorage struct {
|
|
|
|
// Sites are exposed for testing purposes.
|
|
|
|
Sites map[string]*caddytls.SiteData
|
|
|
|
// Users are exposed for testing purposes.
|
|
|
|
Users map[string]*caddytls.UserData
|
|
|
|
// LastUserEmail is exposed for testing purposes.
|
|
|
|
LastUserEmail string
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewInMemoryStorage constructs an InMemoryStorage instance. For use with
|
|
|
|
// caddytls, the InMemoryStorageCreator should be used instead.
|
|
|
|
func NewInMemoryStorage() *InMemoryStorage {
|
|
|
|
return &InMemoryStorage{
|
|
|
|
Sites: make(map[string]*caddytls.SiteData),
|
|
|
|
Users: make(map[string]*caddytls.UserData),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SiteExists implements caddytls.Storage.SiteExists in memory.
|
2016-08-19 00:28:43 +08:00
|
|
|
func (s *InMemoryStorage) SiteExists(domain string) (bool, error) {
|
2016-07-08 21:32:31 +08:00
|
|
|
_, siteExists := s.Sites[domain]
|
2016-08-19 00:28:43 +08:00
|
|
|
return siteExists, nil
|
2016-07-08 21:32:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clear completely clears all values associated with this storage.
|
|
|
|
func (s *InMemoryStorage) Clear() {
|
|
|
|
s.Sites = make(map[string]*caddytls.SiteData)
|
|
|
|
s.Users = make(map[string]*caddytls.UserData)
|
|
|
|
s.LastUserEmail = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// LoadSite implements caddytls.Storage.LoadSite in memory.
|
|
|
|
func (s *InMemoryStorage) LoadSite(domain string) (*caddytls.SiteData, error) {
|
|
|
|
siteData, ok := s.Sites[domain]
|
|
|
|
if !ok {
|
2016-09-09 08:48:32 +08:00
|
|
|
return nil, caddytls.ErrNotExist(errors.New("not found"))
|
2016-07-08 21:32:31 +08:00
|
|
|
}
|
|
|
|
return siteData, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func copyBytes(from []byte) []byte {
|
|
|
|
copiedBytes := make([]byte, len(from))
|
|
|
|
copy(copiedBytes, from)
|
|
|
|
return copiedBytes
|
|
|
|
}
|
|
|
|
|
|
|
|
// StoreSite implements caddytls.Storage.StoreSite in memory.
|
|
|
|
func (s *InMemoryStorage) StoreSite(domain string, data *caddytls.SiteData) error {
|
|
|
|
copiedData := new(caddytls.SiteData)
|
|
|
|
copiedData.Cert = copyBytes(data.Cert)
|
|
|
|
copiedData.Key = copyBytes(data.Key)
|
|
|
|
copiedData.Meta = copyBytes(data.Meta)
|
|
|
|
s.Sites[domain] = copiedData
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteSite implements caddytls.Storage.DeleteSite in memory.
|
|
|
|
func (s *InMemoryStorage) DeleteSite(domain string) error {
|
|
|
|
if _, ok := s.Sites[domain]; !ok {
|
2016-09-09 08:48:32 +08:00
|
|
|
return caddytls.ErrNotExist(errors.New("not found"))
|
2016-07-08 21:32:31 +08:00
|
|
|
}
|
|
|
|
delete(s.Sites, domain)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-09-20 07:24:34 +08:00
|
|
|
// TryLock implements Storage.TryLock by returning nil values because it
|
|
|
|
// is not a multi-server storage implementation.
|
|
|
|
func (s *InMemoryStorage) TryLock(domain string) (caddytls.Waiter, error) {
|
|
|
|
return nil, nil
|
2016-07-08 21:32:31 +08:00
|
|
|
}
|
|
|
|
|
2016-09-20 07:24:34 +08:00
|
|
|
// Unlock implements Storage.Unlock as a no-op because it is
|
2016-07-08 21:32:31 +08:00
|
|
|
// not a multi-server storage implementation.
|
2016-09-20 07:24:34 +08:00
|
|
|
func (s *InMemoryStorage) Unlock(domain string) error {
|
2016-07-08 21:32:31 +08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// LoadUser implements caddytls.Storage.LoadUser in memory.
|
|
|
|
func (s *InMemoryStorage) LoadUser(email string) (*caddytls.UserData, error) {
|
|
|
|
userData, ok := s.Users[email]
|
|
|
|
if !ok {
|
2016-09-09 08:48:32 +08:00
|
|
|
return nil, caddytls.ErrNotExist(errors.New("not found"))
|
2016-07-08 21:32:31 +08:00
|
|
|
}
|
|
|
|
return userData, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// StoreUser implements caddytls.Storage.StoreUser in memory.
|
|
|
|
func (s *InMemoryStorage) StoreUser(email string, data *caddytls.UserData) error {
|
|
|
|
copiedData := new(caddytls.UserData)
|
|
|
|
copiedData.Reg = copyBytes(data.Reg)
|
|
|
|
copiedData.Key = copyBytes(data.Key)
|
|
|
|
s.Users[email] = copiedData
|
|
|
|
s.LastUserEmail = email
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// MostRecentUserEmail implements caddytls.Storage.MostRecentUserEmail in memory.
|
|
|
|
func (s *InMemoryStorage) MostRecentUserEmail() string {
|
|
|
|
return s.LastUserEmail
|
|
|
|
}
|