ezshare/store/memory.go

270 lines
5.5 KiB
Go
Raw Normal View History

2021-12-03 22:04:09 +00:00
package store
import (
2021-12-05 00:00:32 +00:00
"crypto/ecdsa"
2021-12-08 04:42:25 +00:00
"crypto/sha256"
2021-12-05 00:00:32 +00:00
"crypto/x509"
2021-12-08 04:42:25 +00:00
"fmt"
"strings"
2021-12-03 22:04:09 +00:00
"sync"
"gitea.benny.dog/torjus/ezshare/pb"
"github.com/google/uuid"
)
2021-12-05 00:00:32 +00:00
type MemoryStore struct {
2021-12-08 04:42:25 +00:00
// Filestore
filesLock sync.RWMutex
files map[string]*pb.File
// Certstore
2021-12-06 16:28:48 +00:00
certLock sync.RWMutex
certs map[string][]byte
keyLock sync.RWMutex
keys map[string][]byte
revokedCerts map[string]struct{}
revokedLock sync.RWMutex
2021-12-08 04:42:25 +00:00
// Userstore
usersLock sync.RWMutex
users map[string]*pb.User
// Binarystore
binaryLock sync.RWMutex
binaries map[[32]byte]*pb.Binary
2021-12-03 22:04:09 +00:00
}
2021-12-05 00:00:32 +00:00
func NewMemoryStore() *MemoryStore {
return &MemoryStore{
2021-12-06 16:28:48 +00:00
files: make(map[string]*pb.File),
certs: make(map[string][]byte),
keys: make(map[string][]byte),
users: make(map[string]*pb.User),
revokedCerts: make(map[string]struct{}),
2021-12-08 04:42:25 +00:00
binaries: make(map[[32]byte]*pb.Binary),
2021-12-05 00:00:32 +00:00
}
2021-12-03 22:04:09 +00:00
}
2021-12-05 10:08:09 +00:00
///////////////
// FileStore //
///////////////
var _ FileStore = &MemoryStore{}
2021-12-05 00:00:32 +00:00
func (s *MemoryStore) GetFile(id string) (*pb.File, error) {
2021-12-03 22:04:09 +00:00
s.filesLock.RLock()
defer s.filesLock.RUnlock()
if file, ok := s.files[id]; ok {
return file, nil
}
2021-12-05 11:42:22 +00:00
return nil, ErrNoSuchItem
2021-12-03 22:04:09 +00:00
}
2021-12-05 00:00:32 +00:00
func (s *MemoryStore) StoreFile(file *pb.File) (string, error) {
2021-12-03 22:04:09 +00:00
s.filesLock.Lock()
defer s.filesLock.Unlock()
id := uuid.Must(uuid.NewRandom()).String()
file.FileId = id
s.files[id] = file
return id, nil
}
2021-12-05 00:00:32 +00:00
func (s *MemoryStore) DeleteFile(id string) error {
2021-12-03 22:04:09 +00:00
s.filesLock.Lock()
defer s.filesLock.Unlock()
if _, ok := s.files[id]; !ok {
2021-12-05 11:42:22 +00:00
return ErrNoSuchItem
2021-12-03 22:04:09 +00:00
}
delete(s.files, id)
return nil
}
2021-12-04 10:30:42 +00:00
2021-12-05 00:00:32 +00:00
func (s *MemoryStore) ListFiles() ([]*pb.ListFilesResponse_ListFileInfo, error) {
2021-12-04 10:30:42 +00:00
s.filesLock.RLock()
defer s.filesLock.RUnlock()
var response []*pb.ListFilesResponse_ListFileInfo
for _, f := range s.files {
response = append(response, &pb.ListFilesResponse_ListFileInfo{FileId: f.FileId, Metadata: f.Metadata})
}
return response, nil
}
2021-12-05 00:00:32 +00:00
2021-12-05 10:08:09 +00:00
//////////////////////
// CertificateStore //
//////////////////////
var _ CertificateStore = &MemoryStore{}
2021-12-06 18:14:39 +00:00
func (s *MemoryStore) GetCertificate(serial string) (*x509.Certificate, error) {
2021-12-05 00:00:32 +00:00
s.certLock.Lock()
defer s.certLock.Unlock()
2021-12-06 18:14:39 +00:00
data, ok := s.certs[serial]
2021-12-05 00:00:32 +00:00
if !ok {
// TODO: Make separate error, or rename error
2021-12-05 11:42:22 +00:00
return nil, ErrNoSuchItem
2021-12-05 00:00:32 +00:00
}
return x509.ParseCertificate(data)
}
2021-12-06 18:14:39 +00:00
func (s *MemoryStore) StoreCertificate(cert *x509.Certificate) error {
2021-12-05 00:00:32 +00:00
s.certLock.Lock()
defer s.certLock.Unlock()
// Copy cert data
data := make([]byte, len(cert.Raw))
copy(data, cert.Raw)
2021-12-06 18:14:39 +00:00
s.certs[cert.SerialNumber.String()] = data
2021-12-05 00:00:32 +00:00
return nil
}
func (s *MemoryStore) GetKey(id string) (*ecdsa.PrivateKey, error) {
s.keyLock.RLock()
defer s.keyLock.RUnlock()
data, ok := s.keys[id]
if !ok {
2021-12-05 11:42:22 +00:00
return nil, ErrNoSuchItem
2021-12-05 00:00:32 +00:00
}
return x509.ParseECPrivateKey(data)
}
func (s *MemoryStore) StoreKey(id string, key *ecdsa.PrivateKey) error {
s.keyLock.Lock()
defer s.keyLock.Unlock()
data, err := x509.MarshalECPrivateKey(key)
if err != nil {
return err
}
s.keys[id] = data
return nil
}
func (s *MemoryStore) ListCertificates() ([]string, error) {
s.certLock.RLock()
defer s.certLock.RUnlock()
var certIDs []string
for key := range s.certs {
certIDs = append(certIDs, key)
}
return certIDs, nil
}
2021-12-05 10:08:09 +00:00
2021-12-06 16:28:48 +00:00
func (s *MemoryStore) Revoke(serial string) error {
s.revokedLock.Lock()
defer s.revokedLock.Unlock()
s.revokedCerts[serial] = struct{}{}
return nil
}
func (s *MemoryStore) IsRevoked(serial string) (bool, error) {
s.revokedLock.RLock()
defer s.revokedLock.RUnlock()
_, revoked := s.revokedCerts[serial]
return revoked, nil
}
2021-12-05 10:08:09 +00:00
///////////////
// UserStore //
///////////////
var _ UserStore = &MemoryStore{}
func (s *MemoryStore) StoreUser(user *pb.User) error {
s.usersLock.Lock()
defer s.usersLock.Unlock()
s.users[user.Id] = user
return nil
}
func (s *MemoryStore) GetUser(id string) (*pb.User, error) {
s.usersLock.RLock()
defer s.usersLock.RUnlock()
user, ok := s.users[id]
if !ok {
// TODO: Update error
2021-12-05 11:42:22 +00:00
return nil, ErrNoSuchItem
2021-12-05 10:08:09 +00:00
}
return user, nil
}
func (s *MemoryStore) ListUsers() ([]string, error) {
s.usersLock.RLock()
defer s.usersLock.RUnlock()
var ids []string
for id := range s.users {
ids = append(ids, id)
}
return ids, nil
}
2021-12-05 11:39:28 +00:00
func (s *MemoryStore) GetUserByUsername(username string) (*pb.User, error) {
s.usersLock.RLock()
defer s.usersLock.RUnlock()
for _, user := range s.users {
if user.Username == username {
return user, nil
}
}
2021-12-05 11:42:22 +00:00
return nil, ErrNoSuchItem
2021-12-05 11:39:28 +00:00
}
2021-12-08 04:42:25 +00:00
2021-12-08 05:17:11 +00:00
//////////////////
// Binary store //
//////////////////
var _ BinaryStore = &MemoryStore{}
2021-12-08 04:42:25 +00:00
func (s *MemoryStore) StoreBinary(release *pb.Binary) error {
s.binaryLock.Lock()
defer s.binaryLock.Unlock()
hasher := sha256.New()
_, err := hasher.Write(release.Data)
if err != nil {
return fmt.Errorf("unable to hash binary: %w", err)
}
sum := hasher.Sum(nil)
var byteSum [32]byte
copy(byteSum[:], sum[:32])
s.binaries[byteSum] = release
return nil
}
func (s *MemoryStore) GetBinary(version string, os string, arch string) (*pb.Binary, error) {
s.binaryLock.RLock()
defer s.binaryLock.RUnlock()
for _, release := range s.binaries {
if release.Arch == arch && release.Os == os {
if release.Version == version || strings.EqualFold(os, "latest") {
return release, nil
}
}
}
return nil, ErrNoSuchItem
}
2021-12-08 05:17:11 +00:00
func (s *MemoryStore) List() ([]string, error) {
var releases []string
for _, release := range s.binaries {
releases = append(releases, fmt.Sprintf("ezshare-%s-%s-%s", release.Version[1:], release.Os, release.Arch))
}
return releases, nil
}