diff --git a/cnjvalidator/cnjvalidator.go b/cnjvalidator/cnjvalidator.go index a4f2e58..668c3c1 100644 --- a/cnjvalidator/cnjvalidator.go +++ b/cnjvalidator/cnjvalidator.go @@ -1,6 +1,15 @@ package cnjvalidator -import "github.com/go-playground/validator/v10" +import ( + "errors" + "strings" + + gocnjhelper "git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper" + "github.com/go-playground/validator/v10" + "github.com/gocql/gocql" + "github.com/gofiber/fiber/v2" + "github.com/scylladb/gocqlx/v2" +) type ErrorResponse struct { FailedField string @@ -24,3 +33,61 @@ func ValidateStruct(event interface{}) []*ErrorResponse { } return errors } + +func HandleAccountNameValidation(scyllaDbSession gocqlx.Session, scyllaDbClusterKeyspace string, accountName string) (int, error) { + accountNameLc := strings.ToLower(accountName) + + isAccountNameInUse, err := isValueAlreadyInUse(scyllaDbSession, scyllaDbClusterKeyspace, "account_name_lc", accountNameLc) + + if err != nil { + gocnjhelper.LogErrorf("Error account name validation %s", err) + return fiber.StatusInternalServerError, err + } + + isByLastAccountNameInUse, err := isValueAlreadyInUse(scyllaDbSession, scyllaDbClusterKeyspace, "last_account_name_lc", accountNameLc) + + if err != nil { + gocnjhelper.LogErrorf("Error account name validation %s", err) + return fiber.StatusInternalServerError, err + } + + if isAccountNameInUse || isByLastAccountNameInUse { + gocnjhelper.LogDebug("AccountName already in use") + return fiber.StatusUnprocessableEntity, errors.New("AccountName already in use") + } + + return fiber.StatusOK, nil +} + +func HandleEmailValidation(scyllaDbSession gocqlx.Session, scyllaDbClusterKeyspace string, email string) (int, error) { + isEmailInUse, err := isValueAlreadyInUse(scyllaDbSession, scyllaDbClusterKeyspace, "email", email) + + if err != nil { + gocnjhelper.LogErrorf("Error email validation %s", err) + return fiber.StatusInternalServerError, err + } + + if isEmailInUse { + gocnjhelper.LogDebug("Email already in use") + return fiber.StatusUnprocessableEntity, errors.New("email already in use") + } + + return fiber.StatusOK, nil +} + +func isValueAlreadyInUse(scyllaDbSession gocqlx.Session, scyllaDbClusterKeyspace string, table_value string, value string) (alreadyInUse bool, err error) { + var foundValue string + + dbErr := scyllaDbSession.Query("SELECT "+table_value+" FROM "+scyllaDbClusterKeyspace+".users WHERE "+table_value+" = '"+value+"'", nil).Get(&foundValue) + + if dbErr != nil && !errors.Is(dbErr, gocql.ErrNotFound) { + gocnjhelper.LogErrorf("Failed to check for table: %s, value: %s, err: %s", table_value, value, dbErr) + return true, dbErr + } + + if foundValue != "" { + return true, nil + } + + return false, nil +}