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