2022-08-02 10:26:28 +00:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
2022-08-11 15:14:21 +00:00
|
|
|
"fmt"
|
2023-03-29 10:59:08 +00:00
|
|
|
"strings"
|
2022-08-02 10:26:28 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.coopgo.io/coopgo-platform/mobility-accounts/storage"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/santhosh-tekuri/jsonschema/v5"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (h MobilityAccountsHandler) Login(username string, password string, namespace string) (*storage.Account, error) {
|
|
|
|
if password == "" {
|
|
|
|
return nil, errors.New("empty password not allowed")
|
|
|
|
}
|
2023-05-01 22:34:33 +00:00
|
|
|
u := strings.ToLower(username)
|
|
|
|
account, err := h.storage.DB.LocalAuthentication(namespace, &u, nil, nil)
|
2022-08-02 10:26:28 +00:00
|
|
|
if err != nil {
|
2023-07-18 10:38:07 +00:00
|
|
|
fmt.Println(err)
|
2022-08-02 10:26:28 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = bcrypt.CompareHashAndPassword([]byte(account.Authentication.Local.Password), []byte(password)); err != nil {
|
2023-07-18 10:38:07 +00:00
|
|
|
fmt.Println(err)
|
2022-08-02 10:26:28 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2023-07-18 10:38:07 +00:00
|
|
|
|
2022-08-02 10:26:28 +00:00
|
|
|
return account, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h MobilityAccountsHandler) Register(account storage.Account) (*storage.Account, error) {
|
2023-07-18 10:38:07 +00:00
|
|
|
|
2022-08-02 10:26:28 +00:00
|
|
|
if account.ID != "" {
|
|
|
|
return nil, errors.New("id should be empty")
|
|
|
|
}
|
|
|
|
|
2023-05-01 22:34:33 +00:00
|
|
|
// Generate new UUID
|
|
|
|
account.ID = uuid.NewString()
|
2023-03-29 10:59:08 +00:00
|
|
|
|
2023-05-01 22:34:33 +00:00
|
|
|
if account.Authentication.Local != nil && account.Authentication.Local.Username != nil {
|
|
|
|
username := strings.ToLower(*account.Authentication.Local.Username)
|
|
|
|
account.Authentication.Local.Username = &username
|
|
|
|
}
|
|
|
|
if account.Authentication.Local != nil && account.Authentication.Local.Email != nil {
|
|
|
|
email := strings.ToLower(*account.Authentication.Local.Email)
|
|
|
|
account.Authentication.Local.Username = &email
|
2023-03-29 10:59:08 +00:00
|
|
|
}
|
|
|
|
|
2023-05-01 22:34:33 +00:00
|
|
|
//TODO remove this as we want to handle unicity in storage
|
|
|
|
if account.Authentication.Local != nil {
|
|
|
|
// If a password was sent, hash the password
|
|
|
|
if account.Authentication.Local.Password != "" {
|
|
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(account.Authentication.Local.Password), bcrypt.DefaultCost)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
account.Authentication.Local.Password = string(hashedPassword)
|
|
|
|
}
|
|
|
|
|
2023-07-18 10:38:07 +00:00
|
|
|
_, _ = h.storage.DB.LocalAuthentication(account.Namespace, account.Authentication.Local.Username, account.Authentication.Local.Email, account.Authentication.Local.PhoneNumber)
|
2022-08-02 10:26:28 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate data schemas
|
|
|
|
dataschemas := h.config.GetStringMap("data_schemas")
|
|
|
|
for k, v := range account.Data {
|
|
|
|
if !h.config.GetBool("allow_any_data") && dataschemas[k] == nil {
|
|
|
|
return nil, errors.New("data scope not allowed")
|
|
|
|
}
|
|
|
|
|
|
|
|
if dataschemas[k] != nil {
|
|
|
|
s := dataschemas[k].(map[string]string)
|
|
|
|
sch, err := jsonschema.Compile(s["schema"])
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = sch.Validate(v); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the "created" metadata
|
|
|
|
if account.Metadata == nil {
|
|
|
|
account.Metadata = map[string]any{}
|
|
|
|
}
|
|
|
|
account.Metadata["created"] = time.Now()
|
|
|
|
|
|
|
|
// Store the account
|
|
|
|
if err := h.storage.DB.CreateAccount(account); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &account, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h MobilityAccountsHandler) UpdateData(accountid string, datas map[string]any) (*storage.Account, error) {
|
|
|
|
account, err := h.storage.DB.GetAccount(accountid)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate data schemas and update account
|
|
|
|
dataschemas := h.config.GetStringMap("data_schemas")
|
|
|
|
for k, v := range datas {
|
|
|
|
if !h.config.GetBool("allow_any_data") && dataschemas[k] == nil {
|
2022-08-11 15:14:21 +00:00
|
|
|
fmt.Println("data scope not allowed")
|
2022-08-02 10:26:28 +00:00
|
|
|
return nil, errors.New("data scope not allowed")
|
|
|
|
}
|
|
|
|
|
|
|
|
if dataschemas[k] != nil {
|
|
|
|
s := dataschemas[k].(map[string]string)
|
|
|
|
sch, err := jsonschema.Compile(s["schema"])
|
|
|
|
if err != nil {
|
2022-08-11 15:14:21 +00:00
|
|
|
fmt.Println(err)
|
2022-08-02 10:26:28 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = sch.Validate(v); err != nil {
|
2022-08-11 15:14:21 +00:00
|
|
|
fmt.Println(err)
|
2022-08-02 10:26:28 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
2022-08-11 15:14:21 +00:00
|
|
|
account.Data[k] = v
|
2022-08-02 10:26:28 +00:00
|
|
|
}
|
|
|
|
if err = h.storage.DB.UpdateAccount(*account); err != nil {
|
2022-08-11 15:14:21 +00:00
|
|
|
fmt.Println(err)
|
2022-08-02 10:26:28 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return account, nil
|
|
|
|
}
|
|
|
|
|
2023-03-29 10:59:08 +00:00
|
|
|
func (h MobilityAccountsHandler) UpdatePhoneNumber(accountid, phone_number string, verified bool, verification_code string) error {
|
|
|
|
account, err := h.storage.DB.GetAccount(accountid)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-05-01 22:34:33 +00:00
|
|
|
account2, err := h.storage.DB.LocalAuthentication(account.Namespace, nil, nil, &phone_number)
|
2023-03-29 10:59:08 +00:00
|
|
|
|
|
|
|
if err == nil && account.ID != account2.ID {
|
|
|
|
return errors.New("user with this phone number already exists")
|
|
|
|
}
|
2023-05-01 22:34:33 +00:00
|
|
|
account.Authentication.Local.PhoneNumber = &phone_number
|
2023-03-29 10:59:08 +00:00
|
|
|
account.Authentication.Local.PhoneNumberValidation.Validated = verified
|
|
|
|
account.Authentication.Local.PhoneNumberValidation.ValidationCode = verification_code
|
|
|
|
|
|
|
|
if err = h.storage.DB.UpdateAccount(*account); err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-08-02 10:26:28 +00:00
|
|
|
func (h MobilityAccountsHandler) GetAccount(id string) (account *storage.Account, err error) {
|
|
|
|
account, err = h.storage.DB.GetAccount(id)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-09-06 13:03:39 +00:00
|
|
|
func (h MobilityAccountsHandler) GetAccountUsername(username string, namespace string) (account *storage.Account, err error) {
|
2023-05-01 22:34:33 +00:00
|
|
|
account, err = h.storage.DB.LocalAuthentication(namespace, &username, nil, nil)
|
2022-09-06 13:03:39 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-08-02 10:26:28 +00:00
|
|
|
func (h MobilityAccountsHandler) GetAccounts(namespaces []string) (accounts []storage.Account, err error) {
|
|
|
|
accounts, err = h.storage.DB.GetAccounts(namespaces)
|
|
|
|
return
|
|
|
|
}
|
2022-08-11 15:14:21 +00:00
|
|
|
|
|
|
|
func (h MobilityAccountsHandler) GetAccountsBatch(accountIds []string) (accounts []storage.Account, err error) {
|
|
|
|
if len(accountIds) == 0 {
|
|
|
|
return accounts, nil
|
|
|
|
}
|
|
|
|
accounts, err = h.storage.DB.GetAccountsByIds(accountIds)
|
|
|
|
return
|
|
|
|
}
|
2022-10-30 19:09:51 +00:00
|
|
|
|
|
|
|
func (h MobilityAccountsHandler) ChangePassword(accountid string, newpassword string) error {
|
|
|
|
account, err := h.storage.DB.GetAccount(accountid)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newpassword), bcrypt.DefaultCost)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
account.Authentication.Local.Password = string(hashedPassword)
|
|
|
|
|
|
|
|
if err = h.storage.DB.UpdateAccount(*account); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|