parcoursmob/core/application/members.go

248 lines
6.1 KiB
Go
Executable File

package application
import (
"context"
"fmt"
"strings"
"time"
formvalidators "git.coopgo.io/coopgo-apps/parcoursmob/core/utils/form-validators"
groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage"
"github.com/google/uuid"
"google.golang.org/protobuf/types/known/structpb"
)
type MembersResult struct {
Accounts []mobilityaccountsstorage.Account
CacheID string
GroupsNames []string
}
func (h *ApplicationHandler) GetMembers(ctx context.Context) (*MembersResult, error) {
accounts, err := h.services.GetAccounts()
if err != nil {
return nil, err
}
var groupsNames []string
for _, v := range accounts {
adminid := v.ID
request := &mobilityaccounts.GetAccountRequest{
Id: adminid,
}
resp, err := h.services.GRPC.MobilityAccounts.GetAccount(ctx, request)
if err != nil {
return nil, err
}
var allIds []string
for _, v := range resp.Account.ToStorageType().Data["groups"].([]any) {
s := fmt.Sprintf("%v", v)
if !(strings.Contains(s, "admin")) {
allIds = append(allIds, s)
}
}
reques := &groupsmanagement.GetGroupsBatchRequest{
Groupids: allIds,
}
res, err := h.services.GRPC.GroupsManagement.GetGroupsBatch(ctx, reques)
if err != nil {
return nil, err
}
g := ""
for _, group := range res.Groups {
g += fmt.Sprintf("%v", group.ToStorageType().Data["name"]) + " "
}
groupsNames = append(groupsNames, g)
}
cacheID := uuid.NewString()
h.cache.PutWithTTL(cacheID, accounts, 1*time.Hour)
return &MembersResult{
Accounts: accounts,
CacheID: cacheID,
GroupsNames: groupsNames,
}, nil
}
type MemberDataResult struct {
Account mobilityaccountsstorage.Account
GroupsNames []string
}
func (h *ApplicationHandler) GetMemberData(ctx context.Context, memberID string) (*MemberDataResult, error) {
request := &mobilityaccounts.GetAccountRequest{
Id: memberID,
}
resp, err := h.services.GRPC.MobilityAccounts.GetAccount(ctx, request)
if err != nil {
return nil, err
}
// Security check: ensure this is actually a member account
if resp.Account.Namespace != "parcoursmob" {
return nil, fmt.Errorf("account %s is not a member (namespace: %s)", memberID, resp.Account.Namespace)
}
var allIds []string
for _, v := range resp.Account.ToStorageType().Data["groups"].([]any) {
s := fmt.Sprintf("%v", v)
if !(strings.Contains(s, "admin")) {
allIds = append(allIds, s)
}
}
reques := &groupsmanagement.GetGroupsBatchRequest{
Groupids: allIds,
}
res, err := h.services.GRPC.GroupsManagement.GetGroupsBatch(ctx, reques)
if err != nil {
return nil, err
}
var groupsNames []string
for _, group := range res.Groups {
g := fmt.Sprintf("%v", group.ToStorageType().Data["name"])
groupsNames = append(groupsNames, g)
}
return &MemberDataResult{
Account: resp.Account.ToStorageType(),
GroupsNames: groupsNames,
}, nil
}
type MemberResult struct {
Account mobilityaccountsstorage.Account
}
func (h *ApplicationHandler) GetMember(ctx context.Context, memberID string) (*MemberResult, error) {
request := &mobilityaccounts.GetAccountRequest{
Id: memberID,
}
resp, err := h.services.GRPC.MobilityAccounts.GetAccount(ctx, request)
if err != nil {
return nil, err
}
// Security check: ensure this is actually a member account
if resp.Account.Namespace != "parcoursmob" {
return nil, fmt.Errorf("account %s is not a member (namespace: %s)", memberID, resp.Account.Namespace)
}
return &MemberResult{
Account: resp.Account.ToStorageType(),
}, nil
}
func (h *ApplicationHandler) UpdateMember(ctx context.Context, memberID, firstName, lastName, email, phoneNumber, gender string) (string, error) {
// Security check: verify the account exists and is a member
getRequest := &mobilityaccounts.GetAccountRequest{
Id: memberID,
}
getResp, err := h.services.GRPC.MobilityAccounts.GetAccount(ctx, getRequest)
if err != nil {
return "", err
}
if getResp.Account.Namespace != "parcoursmob" {
return "", fmt.Errorf("account %s is not a member (namespace: %s)", memberID, getResp.Account.Namespace)
}
dataMap := map[string]any{
"first_name": firstName,
"last_name": lastName,
"email": email,
"phone_number": phoneNumber,
"gender": gender,
}
// Validate the data
formData := UserForm{
FirstName: firstName,
LastName: lastName,
Email: email,
PhoneNumber: phoneNumber,
Gender: gender,
}
validate := formvalidators.New()
if err := validate.Struct(formData); err != nil {
return "", err
}
data, err := structpb.NewValue(dataMap)
if err != nil {
return "", err
}
request := &mobilityaccounts.UpdateDataRequest{
Account: &mobilityaccounts.Account{
Id: memberID,
Namespace: "parcoursmob",
Data: data.GetStructValue(),
},
}
resp, err := h.services.GRPC.MobilityAccounts.UpdateData(ctx, request)
if err != nil {
return "", err
}
return resp.Account.Id, nil
}
type UserForm struct {
FirstName string `json:"first_name" validate:"required"`
LastName string `json:"last_name" validate:"required"`
Email string `json:"email" validate:"required,email"`
PhoneNumber string `json:"phone_number" `
Address any `json:"address,omitempty"`
Gender string `json:"gender"`
}
type RegisterUserResult struct {
UserID string
}
func (h *ApplicationHandler) RegisterUser(ctx context.Context, user mobilityaccountsstorage.Account) (*RegisterUserResult, error) {
account, err := mobilityaccounts.AccountFromStorageType(&user)
if err != nil {
return nil, err
}
resp, err := h.services.GRPC.MobilityAccounts.Register(ctx, &mobilityaccounts.RegisterRequest{
Account: account,
})
if err != nil {
return nil, err
}
if g, ok := user.Metadata["import_in_group"]; ok {
if group, ok := g.(string); ok {
_, err = h.services.GRPC.GroupsManagement.Subscribe(ctx, &groupsmanagement.SubscribeRequest{
Groupid: group,
Memberid: resp.Account.Id,
})
if err != nil {
return nil, err
}
}
}
return &RegisterUserResult{
UserID: resp.Account.Id,
}, nil
}