Define API and implement an in-memory store.
This commit is contained in:
parent
b8a4ad02d7
commit
b01c6fb05e
4 changed files with 150 additions and 0 deletions
8
internal/config/config.go
Normal file
8
internal/config/config.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package config
|
||||
|
||||
type Config struct {
|
||||
PublicKeyPath string
|
||||
PrivateKeyPath string
|
||||
}
|
||||
|
||||
var Default = Config{}
|
||||
19
internal/db/db.go
Normal file
19
internal/db/db.go
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package db
|
||||
|
||||
import "github.com/AYM1607/ccclip/pkg/api"
|
||||
|
||||
type DB interface {
|
||||
// Users.
|
||||
PutUser(id string, passwordHash string) error
|
||||
GetUser(id string) (*api.User, error)
|
||||
|
||||
// Devices.
|
||||
PutDevice(pubKey, userId string) (string, error)
|
||||
GetDevice(id string) (*api.Device, error)
|
||||
GetUserDevices(userId string) ([]*api.Device, error)
|
||||
GetDeviceUser(deviceId string) (*api.User, error)
|
||||
|
||||
// Clipboard.
|
||||
PutClipboard(userId string, clipboard *api.Clipboard) error
|
||||
GetClipboard(userId string) (*api.Clipboard, error)
|
||||
}
|
||||
106
internal/db/local.go
Normal file
106
internal/db/local.go
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
ulid "github.com/oklog/ulid/v2"
|
||||
|
||||
"github.com/AYM1607/ccclip/pkg/api"
|
||||
)
|
||||
|
||||
type localDB struct {
|
||||
users map[string]*api.User
|
||||
devices map[string]*api.Device
|
||||
usersDevices map[string]map[string]struct{}
|
||||
clipboards map[string]*api.Clipboard
|
||||
}
|
||||
|
||||
var _ DB = (*localDB)(nil)
|
||||
|
||||
func NewLocalDB() DB {
|
||||
return &localDB{
|
||||
users: make(map[string]*api.User),
|
||||
devices: make(map[string]*api.Device),
|
||||
usersDevices: make(map[string]map[string]struct{}),
|
||||
clipboards: make(map[string]*api.Clipboard),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *localDB) PutUser(id, passwordHash string) error {
|
||||
if _, ok := d.users[id]; ok {
|
||||
return errors.New("user exists")
|
||||
}
|
||||
d.users[id] = &api.User{ID: id, PasswordHash: passwordHash}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *localDB) GetUser(id string) (*api.User, error) {
|
||||
u, ok := d.users[id]
|
||||
if !ok {
|
||||
return nil, errors.New("user does not exist")
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (d *localDB) PutDevice(pubKey, userId string) (string, error) {
|
||||
id := ulid.Make().String()
|
||||
if _, ok := d.users[userId]; !ok {
|
||||
return "", errors.New("user does not exist")
|
||||
}
|
||||
|
||||
d.devices[id] = &api.Device{
|
||||
ID: id,
|
||||
PublicKey: pubKey,
|
||||
}
|
||||
|
||||
if d.usersDevices[userId] == nil {
|
||||
d.usersDevices[userId] = map[string]struct{}{}
|
||||
}
|
||||
d.usersDevices[userId][id] = struct{}{}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (d *localDB) GetDevice(id string) (*api.Device, error) {
|
||||
device, ok := d.devices[id]
|
||||
if !ok {
|
||||
return nil, errors.New("requested device does no exist")
|
||||
}
|
||||
return device, nil
|
||||
}
|
||||
|
||||
func (d *localDB) GetUserDevices(userId string) ([]*api.Device, error) {
|
||||
ids := d.usersDevices[userId]
|
||||
res := []*api.Device{}
|
||||
for id := range ids {
|
||||
d, ok := d.devices[id]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("device %s is associated to user but it does not exist", id)
|
||||
}
|
||||
res = append(res, d)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (d *localDB) GetDeviceUser(deviceId string) (*api.User, error) {
|
||||
// Foreign keys can make this better.
|
||||
for uId, u := range d.users {
|
||||
if _, ok := d.usersDevices[uId]; ok {
|
||||
return u, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("device is not associated to any user")
|
||||
}
|
||||
|
||||
func (d *localDB) PutClipboard(userId string, clipboard *api.Clipboard) error {
|
||||
d.clipboards[userId] = clipboard
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *localDB) GetClipboard(userId string) (*api.Clipboard, error) {
|
||||
c, ok := d.clipboards[userId]
|
||||
if !ok {
|
||||
return nil, errors.New("user does not have a current clipboard")
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
17
pkg/api/api.go
Normal file
17
pkg/api/api.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package api
|
||||
|
||||
type User struct {
|
||||
ID string
|
||||
PasswordHash string
|
||||
}
|
||||
|
||||
type Device struct {
|
||||
ID string
|
||||
PublicKey []byte
|
||||
}
|
||||
|
||||
type Clipboard struct {
|
||||
SenderDeviceID string
|
||||
// Payloads maps DeviceIDs to base64 encoded data.
|
||||
Payloads map[string]string
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue