134 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
		
			Executable File
		
	
	
package application
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"crypto/rand"
 | 
						|
	"encoding/base64"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"time"
 | 
						|
 | 
						|
	groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
 | 
						|
	"git.coopgo.io/coopgo-platform/groups-management/storage"
 | 
						|
	accounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
						|
	"github.com/rs/zerolog/log"
 | 
						|
)
 | 
						|
 | 
						|
type GroupSettingsResult struct {
 | 
						|
	Group        storage.Group
 | 
						|
	GroupMembers []any
 | 
						|
	Admins       []any
 | 
						|
}
 | 
						|
 | 
						|
func (h *ApplicationHandler) GetGroupSettings(ctx context.Context, groupID string) (*GroupSettingsResult, error) {
 | 
						|
	// Get group info
 | 
						|
	groupResp, err := h.services.GRPC.GroupsManagement.GetGroup(ctx, &groupsmanagement.GetGroupRequest{
 | 
						|
		Id: groupID,
 | 
						|
	})
 | 
						|
	if err != nil {
 | 
						|
		return nil, fmt.Errorf("failed to get group: %w", err)
 | 
						|
	}
 | 
						|
 | 
						|
	group := groupResp.Group.ToStorageType()
 | 
						|
 | 
						|
	members, err := h.members()
 | 
						|
	if err != nil {
 | 
						|
		return nil, fmt.Errorf("failed to get members: %w", err)
 | 
						|
	}
 | 
						|
 | 
						|
	admins := []any{}
 | 
						|
	groupMembers := []any{}
 | 
						|
 | 
						|
	for _, m := range members {
 | 
						|
		mm := m.ToStorageType()
 | 
						|
		if groups, ok := mm.Data["groups"].([]any); ok {
 | 
						|
			for _, g := range groups {
 | 
						|
				if g.(string) == groupID {
 | 
						|
					groupMembers = append(groupMembers, mm)
 | 
						|
				}
 | 
						|
				if g.(string) == groupID+":admin" {
 | 
						|
					admins = append(admins, mm)
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return &GroupSettingsResult{
 | 
						|
		Group:        group,
 | 
						|
		GroupMembers: groupMembers,
 | 
						|
		Admins:       admins,
 | 
						|
	}, nil
 | 
						|
}
 | 
						|
 | 
						|
func (h *ApplicationHandler) InviteMemberToGroup(ctx context.Context, groupID string, username string) error {
 | 
						|
	// Get group info
 | 
						|
	groupResp, err := h.services.GRPC.GroupsManagement.GetGroup(ctx, &groupsmanagement.GetGroupRequest{
 | 
						|
		Id: groupID,
 | 
						|
	})
 | 
						|
	if err != nil {
 | 
						|
		return fmt.Errorf("failed to get group: %w", err)
 | 
						|
	}
 | 
						|
 | 
						|
	group := groupResp.Group.ToStorageType()
 | 
						|
 | 
						|
	accountresp, err := h.services.GRPC.MobilityAccounts.GetAccountUsername(ctx, &accounts.GetAccountUsernameRequest{
 | 
						|
		Username:  username,
 | 
						|
		Namespace: "parcoursmob",
 | 
						|
	})
 | 
						|
 | 
						|
	if err == nil {
 | 
						|
		// Account already exists: adding the existing account to group
 | 
						|
		account := accountresp.Account.ToStorageType()
 | 
						|
		if account.Data["groups"] == nil {
 | 
						|
			account.Data["groups"] = []any{}
 | 
						|
		}
 | 
						|
		account.Data["groups"] = append(account.Data["groups"].([]any), groupID)
 | 
						|
 | 
						|
		as, err := accounts.AccountFromStorageType(&account)
 | 
						|
		if err != nil {
 | 
						|
			return fmt.Errorf("failed to convert account: %w", err)
 | 
						|
		}
 | 
						|
 | 
						|
		_, err = h.services.GRPC.MobilityAccounts.UpdateData(ctx, &accounts.UpdateDataRequest{
 | 
						|
			Account: as,
 | 
						|
		})
 | 
						|
		if err != nil {
 | 
						|
			return fmt.Errorf("failed to update account: %w", err)
 | 
						|
		}
 | 
						|
 | 
						|
		data := map[string]any{
 | 
						|
			"group": group.Data["name"],
 | 
						|
		}
 | 
						|
 | 
						|
		if err := h.emailing.Send("onboarding.existing_member", username, data); err != nil {
 | 
						|
			log.Warn().Err(err).Msg("failed to send existing member email")
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		// Create onboarding for new member
 | 
						|
		onboarding := map[string]any{
 | 
						|
			"username": username,
 | 
						|
			"group":    groupID,
 | 
						|
			"admin":    false,
 | 
						|
		}
 | 
						|
 | 
						|
		b := make([]byte, 16)
 | 
						|
		if _, err := io.ReadFull(rand.Reader, b); err != nil {
 | 
						|
			return fmt.Errorf("failed to generate random key: %w", err)
 | 
						|
		}
 | 
						|
		key := base64.RawURLEncoding.EncodeToString(b)
 | 
						|
 | 
						|
		h.cache.PutWithTTL("onboarding/"+key, onboarding, 72*time.Hour)
 | 
						|
 | 
						|
		data := map[string]any{
 | 
						|
			"group": group.Data["name"],
 | 
						|
			"key":   key,
 | 
						|
		}
 | 
						|
 | 
						|
		if err := h.emailing.Send("onboarding.new_member", username, data); err != nil {
 | 
						|
			return fmt.Errorf("failed to send new member email: %w", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 |