implemented member manager.

This commit is contained in:
Miroslav Šedivý 2021-03-14 12:57:19 +01:00
parent 7c79b48750
commit bf560d5289
8 changed files with 435 additions and 249 deletions

View File

@ -1,35 +0,0 @@
package dummy
import (
"demodesk/neko/internal/types"
)
func New() types.MemberManager {
return &MemberManagerCtx{}
}
type MemberManagerCtx struct{}
func (manager *MemberManagerCtx) Connect() error {
return nil
}
func (manager *MemberManagerCtx) Disconnect() error {
return nil
}
func (manager *MemberManagerCtx) Insert(id string, profile types.MemberProfile) error {
return nil
}
func (manager *MemberManagerCtx) Update(id string, profile types.MemberProfile) error {
return nil
}
func (manager *MemberManagerCtx) Delete(id string) error {
return nil
}
func (manager *MemberManagerCtx) Select() (map[string]types.MemberProfile, error) {
return map[string]types.MemberProfile{}, nil
}

View File

@ -0,0 +1,47 @@
package dummy
import (
"demodesk/neko/internal/types"
)
func New() types.MemberManager {
return &MemberManagerCtx{}
}
type MemberManagerCtx struct{}
func (manager *MemberManagerCtx) Connect() error {
return nil
}
func (manager *MemberManagerCtx) Disconnect() error {
return nil
}
func (manager *MemberManagerCtx) Authenticate(username string, password string) (string, types.MemberProfile, error) {
return username, types.MemberProfile{}, nil
}
func (manager *MemberManagerCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {
return "", nil
}
func (manager *MemberManagerCtx) Select(id string) (types.MemberProfile, error) {
return types.MemberProfile{}, nil
}
func (manager *MemberManagerCtx) SelectAll(limit int, offset int) (map[string]types.MemberProfile, error) {
return map[string]types.MemberProfile{}, nil
}
func (manager *MemberManagerCtx) Update(id string, profile types.MemberProfile) error {
return nil
}
func (manager *MemberManagerCtx) UpdatePassword(id string, passwrod string) error {
return nil
}
func (manager *MemberManagerCtx) Delete(id string) error {
return nil
}

View File

@ -1,128 +0,0 @@
package file
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"sync"
"demodesk/neko/internal/types"
)
func New(file string) types.MemberManager {
return &MemberManagerCtx{
file: file,
mu: sync.Mutex{},
}
}
type MemberManagerCtx struct {
file string
mu sync.Mutex
}
func (manager *MemberManagerCtx) Connect() error {
return nil
}
func (manager *MemberManagerCtx) Disconnect() error {
return nil
}
func (manager *MemberManagerCtx) Insert(id string, profile types.MemberProfile) error {
manager.mu.Lock()
defer manager.mu.Unlock()
profiles, err := manager.deserialize()
if err != nil {
return err
}
_, ok := profiles[id]
if ok {
return fmt.Errorf("Member ID already exists.")
}
profiles[id] = profile
return manager.serialize(profiles)
}
func (manager *MemberManagerCtx) Update(id string, profile types.MemberProfile) error {
manager.mu.Lock()
defer manager.mu.Unlock()
profiles, err := manager.deserialize()
if err != nil {
return err
}
_, ok := profiles[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
profiles[id] = profile
return manager.serialize(profiles)
}
func (manager *MemberManagerCtx) Delete(id string) error {
manager.mu.Lock()
defer manager.mu.Unlock()
profiles, err := manager.deserialize()
if err != nil {
return err
}
_, ok := profiles[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
delete(profiles, id)
return manager.serialize(profiles)
}
func (manager *MemberManagerCtx) Select() (map[string]types.MemberProfile, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
profiles, err := manager.deserialize()
return profiles, err
}
func (manager *MemberManagerCtx) deserialize() (map[string]types.MemberProfile, error) {
file, err := os.OpenFile(manager.file, os.O_RDONLY|os.O_CREATE, os.ModePerm)
if err != nil {
return nil, err
}
raw, err := ioutil.ReadAll(file)
if err != nil {
return nil, err
}
if len(raw) == 0 {
return map[string]types.MemberProfile{}, nil
}
var profiles map[string]types.MemberProfile
if err := json.Unmarshal([]byte(raw), &profiles); err != nil {
return nil, err
}
return profiles, nil
}
func (manager *MemberManagerCtx) serialize(data map[string]types.MemberProfile) error {
raw, err := json.Marshal(data)
if err != nil {
return err
}
return ioutil.WriteFile(manager.file, raw, os.ModePerm)
}

View File

@ -0,0 +1,223 @@
package file
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"sync"
"demodesk/neko/internal/types"
)
func New(file string) types.MemberManager {
return &MemberManagerCtx{
file: file,
mu: sync.Mutex{},
}
}
type MemberManagerCtx struct {
file string
mu sync.Mutex
}
type MemberEntry struct {
Password string `json:"password"`
Profile types.MemberProfile `json:"profile"`
}
func (manager *MemberManagerCtx) Connect() error {
return nil
}
func (manager *MemberManagerCtx) Disconnect() error {
return nil
}
func (manager *MemberManagerCtx) Authenticate(username string, password string) (string, types.MemberProfile, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
// id will be also username
id := username
entry, err := manager.getEntry(id)
if err != nil {
return "", types.MemberProfile{}, err
}
// TODO: Use hash function.
if entry.Password != password {
return "", types.MemberProfile{}, fmt.Errorf("Invalid password.")
}
return id, entry.Profile, nil
}
func (manager *MemberManagerCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
// id will be also username
id := username
entries, err := manager.deserialize()
if err != nil {
return "", err
}
entry, ok := entries[id]
if ok {
return "", fmt.Errorf("Member ID already exists.")
}
// TODO: Use hash function.
entry.Password = password
entry.Profile = profile
entries[id] = entry
return id, manager.serialize(entries)
}
func (manager *MemberManagerCtx) Update(id string, profile types.MemberProfile) error {
manager.mu.Lock()
defer manager.mu.Unlock()
entries, err := manager.deserialize()
if err != nil {
return err
}
entry, ok := entries[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
entry.Profile = profile
entries[id] = entry
return manager.serialize(entries)
}
func (manager *MemberManagerCtx) UpdatePassword(id string, password string) error {
manager.mu.Lock()
defer manager.mu.Unlock()
entries, err := manager.deserialize()
if err != nil {
return err
}
entry, ok := entries[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
// TODO: Use hash function.
entry.Password = password
entries[id] = entry
return manager.serialize(entries)
}
func (manager *MemberManagerCtx) Select(id string) (types.MemberProfile, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
entry, err := manager.getEntry(id)
if err != nil {
return types.MemberProfile{}, err
}
return entry.Profile, nil
}
func (manager *MemberManagerCtx) SelectAll(limit int, offset int) (map[string]types.MemberProfile, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
profiles := map[string]types.MemberProfile{}
entries, err := manager.deserialize()
if err != nil {
return profiles, err
}
i := 0
for id, entry := range entries {
if i < offset || i > offset + limit {
continue
}
profiles[id] = entry.Profile
i = i + 1
}
return profiles, nil
}
func (manager *MemberManagerCtx) Delete(id string) error {
manager.mu.Lock()
defer manager.mu.Unlock()
entries, err := manager.deserialize()
if err != nil {
return err
}
_, ok := entries[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
delete(entries, id)
return manager.serialize(entries)
}
func (manager *MemberManagerCtx) deserialize() (map[string]MemberEntry, error) {
file, err := os.OpenFile(manager.file, os.O_RDONLY|os.O_CREATE, os.ModePerm)
if err != nil {
return nil, err
}
raw, err := ioutil.ReadAll(file)
if err != nil {
return nil, err
}
if len(raw) == 0 {
return map[string]MemberEntry{}, nil
}
var entries map[string]MemberEntry
if err := json.Unmarshal([]byte(raw), &entries); err != nil {
return nil, err
}
return entries, nil
}
func (manager *MemberManagerCtx) getEntry(id string) (MemberEntry, error) {
entries, err := manager.deserialize()
if err != nil {
return MemberEntry{}, err
}
entry, ok := entries[id]
if !ok {
return MemberEntry{}, fmt.Errorf("Member ID does not exist.")
}
return entry, nil
}
func (manager *MemberManagerCtx) serialize(data map[string]MemberEntry) error {
raw, err := json.Marshal(data)
if err != nil {
return err
}
return ioutil.WriteFile(manager.file, raw, os.ModePerm)
}

View File

@ -1,74 +0,0 @@
package object
import (
"fmt"
"sync"
"demodesk/neko/internal/types"
)
func New() types.MemberManager {
return &MemberManagerCtx{
profiles: make(map[string]types.MemberProfile),
mu: sync.Mutex{},
}
}
type MemberManagerCtx struct {
profiles map[string]types.MemberProfile
mu sync.Mutex
}
func (manager *MemberManagerCtx) Connect() error {
return nil
}
func (manager *MemberManagerCtx) Disconnect() error {
return nil
}
func (manager *MemberManagerCtx) Insert(id string, profile types.MemberProfile) error {
manager.mu.Lock()
defer manager.mu.Unlock()
_, ok := manager.profiles[id]
if ok {
return fmt.Errorf("Member ID already exists.")
}
manager.profiles[id] = profile
return nil
}
func (manager *MemberManagerCtx) Update(id string, profile types.MemberProfile) error {
manager.mu.Lock()
defer manager.mu.Unlock()
_, ok := manager.profiles[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
manager.profiles[id] = profile
return nil
}
func (manager *MemberManagerCtx) Delete(id string) error {
manager.mu.Lock()
defer manager.mu.Unlock()
_, ok := manager.profiles[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
delete(manager.profiles, id)
return nil
}
func (manager *MemberManagerCtx) Select() (map[string]types.MemberProfile, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
return manager.profiles, nil
}

View File

@ -0,0 +1,149 @@
package object
import (
"fmt"
"sync"
"demodesk/neko/internal/types"
)
func New() types.MemberManager {
return &MemberManagerCtx{
entries: make(map[string]MemberEntry),
mu: sync.Mutex{},
}
}
type MemberManagerCtx struct {
entries map[string]MemberEntry
mu sync.Mutex
}
type MemberEntry struct {
Password string `json:"password"`
Profile types.MemberProfile `json:"profile"`
}
func (manager *MemberManagerCtx) Connect() error {
return nil
}
func (manager *MemberManagerCtx) Disconnect() error {
return nil
}
func (manager *MemberManagerCtx) Authenticate(username string, password string) (string, types.MemberProfile, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
// id will be also username
id := username
entry, ok := manager.entries[id]
if !ok {
return "", types.MemberProfile{}, fmt.Errorf("Member ID does not exist.")
}
// TODO: Use hash function.
if entry.Password != password {
return "", types.MemberProfile{}, fmt.Errorf("Invalid password.")
}
return id, entry.Profile, nil
}
func (manager *MemberManagerCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
// id will be also username
id := username
entry, ok := manager.entries[id]
if ok {
return "", fmt.Errorf("Member ID already exists.")
}
// TODO: Use hash function.
entry.Password = password
entry.Profile = profile
manager.entries[id] = entry
return id, nil
}
func (manager *MemberManagerCtx) Update(id string, profile types.MemberProfile) error {
manager.mu.Lock()
defer manager.mu.Unlock()
entry, ok := manager.entries[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
entry.Profile = profile
manager.entries[id] = entry
return nil
}
func (manager *MemberManagerCtx) UpdatePassword(id string, password string) error {
manager.mu.Lock()
defer manager.mu.Unlock()
entry, ok := manager.entries[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
// TODO: Use hash function.
entry.Password = password
manager.entries[id] = entry
return nil
}
func (manager *MemberManagerCtx) Select(id string) (types.MemberProfile, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
entry, ok := manager.entries[id]
if ok {
return types.MemberProfile{}, fmt.Errorf("Member ID already exists.")
}
return entry.Profile, nil
}
func (manager *MemberManagerCtx) SelectAll(limit int, offset int) (map[string]types.MemberProfile, error) {
manager.mu.Lock()
defer manager.mu.Unlock()
profiles := map[string]types.MemberProfile{}
i := 0
for id, entry := range manager.entries {
if i < offset || i > offset + limit {
continue
}
profiles[id] = entry.Profile
i = i + 1
}
return profiles, nil
}
func (manager *MemberManagerCtx) Delete(id string) error {
manager.mu.Lock()
defer manager.mu.Unlock()
_, ok := manager.entries[id]
if !ok {
return fmt.Errorf("Member ID does not exist.")
}
delete(manager.entries, id)
return nil
}

View File

@ -1,11 +1,25 @@
package types
type MemberProfile struct {
Name string `json:"name"`
IsAdmin bool `json:"is_admin"`
CanLogin bool `json:"can_login"`
CanConnect bool `json:"can_connect"`
CanWatch bool `json:"can_watch"`
CanHost bool `json:"can_host"`
CanAccessClipboard bool `json:"can_access_clipboard"`
}
type MemberManager interface {
Connect() error
Disconnect() error
Insert(id string, profile MemberProfile) error
Authenticate(username string, password string) (string, MemberProfile, error)
Insert(username string, password string, profile MemberProfile) (string, error)
Select(id string) (MemberProfile, error)
SelectAll(limit int, offset int) (map[string]MemberProfile, error)
Update(id string, profile MemberProfile) error
UpdatePassword(id string, passwrod string) error
Delete(id string) error
Select() (map[string]MemberProfile, error)
}

View File

@ -2,16 +2,6 @@ package types
import "net/http"
type MemberProfile struct {
Name string `json:"name"`
IsAdmin bool `json:"is_admin"`
CanLogin bool `json:"can_login"`
CanConnect bool `json:"can_connect"`
CanWatch bool `json:"can_watch"`
CanHost bool `json:"can_host"`
CanAccessClipboard bool `json:"can_access_clipboard"`
}
type SessionState struct {
IsConnected bool `json:"is_connected"`
IsWatching bool `json:"is_watching"`