Files
query-orchestration/internal/eula/service_cognito.go
T
Jay Brown 63c12a2f44 Merged in feature/eula.part1 (pull request #206)
eula support

* eula support

* docs
2026-01-22 18:17:27 +00:00

122 lines
4.0 KiB
Go

// Package eula provides EULA (End User License Agreement) version management and compliance tracking.
// This file contains functions that require Cognito integration and cannot be tested with localstack.
package eula
import (
"context"
"fmt"
"queryorchestration/internal/usermanagement"
"github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider"
)
// GetComplianceReport generates a compliance report showing which users have agreed to an EULA version.
// This function requires Cognito access to list users and compare against recorded agreements.
//
// The report includes:
// - Version information for the target EULA
// - Summary statistics (total users, agreed count, not agreed count, compliance percentage)
// - Paginated list of users with their agreement status
//
// Parameters:
// - ctx: Context for cancellation and timeout
// - cognitoClient: AWS Cognito Identity Provider client
// - userPoolID: The Cognito User Pool ID to query for users
// - input: Report configuration including optional version_id, pagination, and filters
//
// Returns:
// - ComplianceReportResult with version info, summary stats, and paginated user list
// - ErrNoCurrentVersion if no version_id provided and no current version exists
// - ErrVersionNotFound if the specified version_id does not exist
// - An error if Cognito or database queries fail
func (s *Service) GetComplianceReport(
ctx context.Context,
cognitoClient *cognitoidentityprovider.Client,
userPoolID string,
input *ComplianceReportInput,
) (*ComplianceReportResult, error) {
// Apply default pagination values
s.ApplyCompliancePaginationDefaults(input)
// Step 1: Resolve target EULA version
version, err := s.ResolveComplianceVersion(ctx, input.VersionID)
if err != nil {
return nil, err
}
// Step 2: Fetch all enabled users from Cognito
cognitoUsers, err := s.fetchAllEnabledCognitoUsers(ctx, cognitoClient, userPoolID)
if err != nil {
return nil, fmt.Errorf("failed to fetch Cognito users: %w", err)
}
// Step 3: Fetch all agreements for this version from DB
agreements, err := s.FetchAllAgreementsForVersion(ctx, version.ID)
if err != nil {
return nil, fmt.Errorf("failed to fetch agreements: %w", err)
}
// Step 4: Build user list with agreement status and compute summary
allUsers, summary := s.BuildComplianceUserList(cognitoUsers, agreements)
// Step 5: Apply filters and sort
filteredUsers := s.FilterAndSortComplianceUsers(allUsers, input.Agreed)
// Step 6: Apply pagination
paginatedUsers, totalItems, totalPages := s.PaginateComplianceUsers(filteredUsers, input.Page, input.PageSize)
return &ComplianceReportResult{
Version: version,
Summary: summary,
Users: paginatedUsers,
Page: input.Page,
PageSize: input.PageSize,
TotalPages: totalPages,
TotalItems: totalItems,
}, nil
}
// fetchAllEnabledCognitoUsers fetches all enabled users from Cognito using pagination.
// Cognito has a max limit of 60 users per request, so this loops until all users are fetched.
//
// Parameters:
// - ctx: Context for cancellation and timeout
// - client: AWS Cognito Identity Provider client
// - userPoolID: The Cognito User Pool ID
//
// Returns:
// - A slice of all enabled Cognito users
// - An error if any Cognito API call fails
func (s *Service) fetchAllEnabledCognitoUsers(
ctx context.Context,
client *cognitoidentityprovider.Client,
userPoolID string,
) ([]usermanagement.CognitoUserResponse, error) {
const maxPerRequest = 60
var allUsers []usermanagement.CognitoUserResponse
var paginationToken *string
for {
result, err := usermanagement.ListCognitoUsers(ctx, client, userPoolID, maxPerRequest, paginationToken)
if err != nil {
return nil, err
}
// Filter to only enabled users
for _, user := range result.Users {
if user.Enabled {
allUsers = append(allUsers, user)
}
}
// Check if there are more pages
if result.PaginationKey == nil || *result.PaginationKey == "" {
break
}
paginationToken = result.PaginationKey
}
return allUsers, nil
}