monorepo/cloud/maplefile-backend/internal/repo/blockedemail/blockedemail.go

199 lines
5.6 KiB
Go

// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/blockedemail/blockedemail.go
package blockedemail
import (
"context"
"strings"
"go.uber.org/zap"
"github.com/gocql/gocql"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
dom_blockedemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/blockedemail"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/validation"
)
type blockedEmailRepositoryImpl struct {
config *config.Configuration
logger *zap.Logger
session *gocql.Session
}
func NewBlockedEmailRepository(
config *config.Configuration,
logger *zap.Logger,
session *gocql.Session,
) dom_blockedemail.BlockedEmailRepository {
logger = logger.Named("BlockedEmailRepository")
return &blockedEmailRepositoryImpl{
config: config,
logger: logger,
session: session,
}
}
func (r *blockedEmailRepositoryImpl) Create(ctx context.Context, blockedEmail *dom_blockedemail.BlockedEmail) error {
// Normalize email to lowercase
normalizedEmail := strings.ToLower(strings.TrimSpace(blockedEmail.BlockedEmail))
query := `INSERT INTO user_blocked_emails (
user_id, blocked_email, blocked_user_id, reason, created_at
) VALUES (?, ?, ?, ?, ?)`
err := r.session.Query(query,
blockedEmail.UserID,
normalizedEmail,
blockedEmail.BlockedUserID,
blockedEmail.Reason,
blockedEmail.CreatedAt,
).WithContext(ctx).Exec()
if err != nil {
r.logger.Error("Failed to create blocked email",
zap.Any("error", err),
zap.Any("user_id", blockedEmail.UserID),
zap.String("blocked_email", validation.MaskEmail(normalizedEmail)))
return err
}
r.logger.Debug("Blocked email created",
zap.Any("user_id", blockedEmail.UserID),
zap.String("blocked_email", validation.MaskEmail(normalizedEmail)))
return nil
}
func (r *blockedEmailRepositoryImpl) Get(ctx context.Context, userID gocql.UUID, blockedEmail string) (*dom_blockedemail.BlockedEmail, error) {
// Normalize email to lowercase
normalizedEmail := strings.ToLower(strings.TrimSpace(blockedEmail))
query := `SELECT user_id, blocked_email, blocked_user_id, reason, created_at
FROM user_blocked_emails
WHERE user_id = ? AND blocked_email = ?`
var result dom_blockedemail.BlockedEmail
err := r.session.Query(query, userID, normalizedEmail).
WithContext(ctx).
Scan(
&result.UserID,
&result.BlockedEmail,
&result.BlockedUserID,
&result.Reason,
&result.CreatedAt,
)
if err != nil {
if err == gocql.ErrNotFound {
return nil, nil
}
r.logger.Error("Failed to get blocked email",
zap.Any("error", err),
zap.Any("user_id", userID),
zap.String("blocked_email", validation.MaskEmail(normalizedEmail)))
return nil, err
}
return &result, nil
}
func (r *blockedEmailRepositoryImpl) List(ctx context.Context, userID gocql.UUID) ([]*dom_blockedemail.BlockedEmail, error) {
query := `SELECT user_id, blocked_email, blocked_user_id, reason, created_at
FROM user_blocked_emails
WHERE user_id = ?`
iter := r.session.Query(query, userID).WithContext(ctx).Iter()
var results []*dom_blockedemail.BlockedEmail
var entry dom_blockedemail.BlockedEmail
for iter.Scan(
&entry.UserID,
&entry.BlockedEmail,
&entry.BlockedUserID,
&entry.Reason,
&entry.CreatedAt,
) {
results = append(results, &dom_blockedemail.BlockedEmail{
UserID: entry.UserID,
BlockedEmail: entry.BlockedEmail,
BlockedUserID: entry.BlockedUserID,
Reason: entry.Reason,
CreatedAt: entry.CreatedAt,
})
}
if err := iter.Close(); err != nil {
r.logger.Error("Failed to list blocked emails",
zap.Any("error", err),
zap.Any("user_id", userID))
return nil, err
}
r.logger.Debug("Listed blocked emails",
zap.Any("user_id", userID),
zap.Int("count", len(results)))
return results, nil
}
func (r *blockedEmailRepositoryImpl) Delete(ctx context.Context, userID gocql.UUID, blockedEmail string) error {
// Normalize email to lowercase
normalizedEmail := strings.ToLower(strings.TrimSpace(blockedEmail))
query := `DELETE FROM user_blocked_emails WHERE user_id = ? AND blocked_email = ?`
err := r.session.Query(query, userID, normalizedEmail).WithContext(ctx).Exec()
if err != nil {
r.logger.Error("Failed to delete blocked email",
zap.Any("error", err),
zap.Any("user_id", userID),
zap.String("blocked_email", validation.MaskEmail(normalizedEmail)))
return err
}
r.logger.Debug("Blocked email deleted",
zap.Any("user_id", userID),
zap.String("blocked_email", validation.MaskEmail(normalizedEmail)))
return nil
}
func (r *blockedEmailRepositoryImpl) IsBlocked(ctx context.Context, userID gocql.UUID, email string) (bool, error) {
// Normalize email to lowercase
normalizedEmail := strings.ToLower(strings.TrimSpace(email))
query := `SELECT blocked_email FROM user_blocked_emails WHERE user_id = ? AND blocked_email = ?`
var blockedEmail string
err := r.session.Query(query, userID, normalizedEmail).
WithContext(ctx).
Scan(&blockedEmail)
if err != nil {
if err == gocql.ErrNotFound {
return false, nil
}
r.logger.Error("Failed to check if email is blocked",
zap.Any("error", err),
zap.Any("user_id", userID),
zap.String("email", validation.MaskEmail(normalizedEmail)))
return false, err
}
return true, nil
}
func (r *blockedEmailRepositoryImpl) Count(ctx context.Context, userID gocql.UUID) (int, error) {
query := `SELECT COUNT(*) FROM user_blocked_emails WHERE user_id = ?`
var count int
err := r.session.Query(query, userID).WithContext(ctx).Scan(&count)
if err != nil {
r.logger.Error("Failed to count blocked emails",
zap.Any("error", err),
zap.Any("user_id", userID))
return 0, err
}
return count, nil
}