159 lines
3.6 KiB
Go
159 lines
3.6 KiB
Go
package logic
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/go-oauth2/oauth2/v4"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
"log/slog"
|
|
)
|
|
|
|
type InMemoryClient struct {
|
|
UserID string
|
|
Domain string
|
|
IsPublic bool
|
|
}
|
|
|
|
var clients map[string]InMemoryClient = make(map[string]InMemoryClient)
|
|
|
|
func AddInMemoryClient(id, userId, domain string, isPublic bool) error {
|
|
result := InMemoryClient{
|
|
UserID: userId,
|
|
Domain: domain,
|
|
IsPublic: isPublic,
|
|
}
|
|
_, contains := clients[id]
|
|
if contains {
|
|
return fmt.Errorf("client with id %s already exist", id)
|
|
} else {
|
|
clients[id] = result
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func GetInMemoryClient(id string) (*InMemoryClient, error) {
|
|
result, contains := clients[id]
|
|
if contains {
|
|
return &result, nil
|
|
} else {
|
|
return nil, fmt.Errorf("client with id %s not found", id)
|
|
}
|
|
}
|
|
|
|
func UpdateInMemoryClientById(id string, client InMemoryClient) error {
|
|
_, contains := clients[id]
|
|
if !contains {
|
|
return fmt.Errorf("client with id %s not found", id)
|
|
} else {
|
|
clients[id] = client
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func DeleteInMemoryClient(id string) {
|
|
delete(clients, id)
|
|
}
|
|
|
|
type StorageClientInfo struct {
|
|
Id string
|
|
Secret string
|
|
}
|
|
|
|
func (model StorageClientInfo) GetID() string {
|
|
return model.Id
|
|
}
|
|
|
|
func (model StorageClientInfo) GetSecret() string {
|
|
return model.Secret
|
|
}
|
|
|
|
func (model StorageClientInfo) GetDomain() string {
|
|
//client, _ := GetInMemoryClient(model.Id)
|
|
//return client.Domain
|
|
return ""
|
|
}
|
|
|
|
func (model StorageClientInfo) IsPublic() bool {
|
|
//client, _ := GetInMemoryClient(model.Id)
|
|
//return client.IsPublic
|
|
return false
|
|
}
|
|
|
|
func (model StorageClientInfo) GetUserID() string {
|
|
//client, _ := GetInMemoryClient(model.Id)
|
|
//return client.UserID
|
|
return model.Id
|
|
}
|
|
|
|
type IBlockchainStorage interface {
|
|
GetByID(ctx context.Context, id string) (oauth2.ClientInfo, error) // read
|
|
Set(clt oauth2.ClientInfo) error // create and update
|
|
Delete(id string) error // delete
|
|
CheckPassword(id string, secret string) (bool, error) // CheckUser
|
|
}
|
|
|
|
type BlockchainStorage struct {
|
|
contract *Contract
|
|
}
|
|
|
|
func NewBlockchainStorage(actor Actor, hash util.Uint160) *BlockchainStorage {
|
|
return &BlockchainStorage{contract: New(actor, hash)}
|
|
}
|
|
|
|
func (storage BlockchainStorage) GetByID(ctx context.Context, id string) (oauth2.ClientInfo, error) {
|
|
password, err := storage.contract.GetUser(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &StorageClientInfo{Id: id, Secret: password.StringLE()}, nil
|
|
}
|
|
|
|
func (storage BlockchainStorage) Set(clt oauth2.ClientInfo) error {
|
|
password, decodeErr := util.Uint256DecodeStringLE(clt.GetSecret())
|
|
if decodeErr != nil {
|
|
return decodeErr
|
|
}
|
|
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
_, _, _ = storage.contract.CreateUser(clt.GetID(), password)
|
|
slog.Warn("Recovered. Error during Set operation in BlockchainStorage:\n", r)
|
|
}
|
|
}()
|
|
|
|
_, _, err := storage.contract.UpdateUser(clt.GetID(), password)
|
|
if err != nil {
|
|
_, _, err = storage.contract.CreateUser(clt.GetID(), password)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (storage BlockchainStorage) Delete(id string) (err error) {
|
|
// should we use hash and ValidUntilBlock?
|
|
|
|
_, _, res := storage.contract.DeleteUser(id)
|
|
if res != nil {
|
|
err = res
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (storage BlockchainStorage) CheckPassword(id string, secret string) (bool, error) {
|
|
password, decodeErr := util.Uint256DecodeStringLE(secret)
|
|
if decodeErr != nil {
|
|
return false, decodeErr
|
|
}
|
|
|
|
_, err := storage.contract.CheckUser(id, password)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return true, nil
|
|
}
|