neowolves/auth-server/logic/storage.go

160 lines
3.6 KiB
Go
Raw Normal View History

package logic
import (
"context"
"fmt"
"github.com/go-oauth2/oauth2/v4"
"github.com/nspcc-dev/neo-go/pkg/util"
2024-01-15 14:49:10 +00:00
"log/slog"
)
type InMemoryClient struct {
UserID string
Domain string
IsPublic bool
}
2024-01-14 21:35:00 +00:00
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 {
2024-01-15 14:49:10 +00:00
//client, _ := GetInMemoryClient(model.Id)
//return client.Domain
return ""
}
func (model StorageClientInfo) IsPublic() bool {
2024-01-15 14:49:10 +00:00
//client, _ := GetInMemoryClient(model.Id)
//return client.IsPublic
return false
}
func (model StorageClientInfo) GetUserID() string {
2024-01-15 14:49:10 +00:00
//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
}
2024-01-15 14:49:10 +00:00
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
}
2024-01-15 14:49:10 +00:00
func (storage BlockchainStorage) Delete(id string) (err error) {
// should we use hash and ValidUntilBlock?
2024-01-15 14:49:10 +00:00
_, _, res := storage.contract.DeleteUser(id)
2024-01-15 14:49:10 +00:00
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
}