package user import ( "time" "github.com/gocql/gocql" "go.uber.org/zap" domainuser "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/user" "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/logger" "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/security/ipcrypt" ) // CreateUserEntityUseCase creates and validates a user domain entity type CreateUserEntityUseCase struct { ipEncryptor *ipcrypt.IPEncryptor logger *zap.Logger } // ProvideCreateUserEntityUseCase creates a new CreateUserEntityUseCase func ProvideCreateUserEntityUseCase(ipEncryptor *ipcrypt.IPEncryptor, logger *zap.Logger) *CreateUserEntityUseCase { return &CreateUserEntityUseCase{ ipEncryptor: ipEncryptor, logger: logger.Named("create-user-entity-usecase"), } } // Execute creates a new user domain entity with validation func (uc *CreateUserEntityUseCase) Execute(tenantID string, input *CreateUserInput) (*domainuser.User, error) { // Set default role if not provided role := int(input.Role) if role == 0 { role = 1 // Default role } now := time.Now() // CWE-359: Encrypt IP address for GDPR compliance encryptedIP := "" if input.CreatedFromIPAddress != "" { encrypted, err := uc.ipEncryptor.Encrypt(input.CreatedFromIPAddress) if err != nil { uc.logger.Error("failed to encrypt IP address", zap.Error(err), zap.String("ip_plain", input.CreatedFromIPAddress)) // Don't fail user creation if encryption fails, just log it encryptedIP = "" } else { encryptedIP = encrypted uc.logger.Debug("IP address encrypted for user creation") } } // Create domain entity user := &domainuser.User{ ID: gocql.TimeUUID().String(), TenantID: tenantID, Email: input.Email, FirstName: input.FirstName, LastName: input.LastName, Name: input.FirstName + " " + input.LastName, // Computed from FirstName + LastName Role: role, Status: 1, // Default active status ProfileData: &domainuser.UserProfileData{ AgreeTermsOfService: true, // Default to true for entity creation }, SecurityData: &domainuser.UserSecurityData{ PasswordHash: input.PasswordHash, PasswordHashAlgorithm: "argon2id", WasEmailVerified: false, }, Metadata: &domainuser.UserMetadata{ CreatedFromIPAddress: encryptedIP, // CWE-359: Encrypted IP CreatedFromIPTimestamp: now, // CWE-359: For 90-day GDPR expiration ModifiedFromIPAddress: encryptedIP, // CWE-359: Encrypted IP ModifiedFromIPTimestamp: now, // CWE-359: For 90-day GDPR expiration CreatedAt: now, ModifiedAt: now, }, CreatedAt: now, UpdatedAt: now, } // Validate domain entity if err := user.Validate(); err != nil { // CWE-532: Use hashed email to prevent PII in logs uc.logger.Warn("user validation failed", logger.EmailHash(input.Email), zap.Error(err)) return nil, err } // CWE-532: Use hashed email to prevent PII in logs uc.logger.Debug("user entity created and validated", zap.String("user_id", user.ID), logger.EmailHash(user.Email), zap.Int("role", user.Role)) return user, nil }