From e60101b78f62dfc8ecb505d4f86fdd5ebb0e5b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Schro=CC=88ter?= Date: Sun, 4 Oct 2020 04:08:17 +0200 Subject: [PATCH] Extend gin validator by password validation and translations --- endpoint/user/endpoint.go | 4 ++-- endpoint/user/util.go | 2 +- endpoint/util.go | 15 ++++++++++++++ setup/setup.go | 42 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/endpoint/user/endpoint.go b/endpoint/user/endpoint.go index 2ed207a..33a678b 100755 --- a/endpoint/user/endpoint.go +++ b/endpoint/user/endpoint.go @@ -70,7 +70,7 @@ func RegisterUser(repository UserQuery, tokenFactory otp.TokenFactory, verifyEma } // check password rules - if ok := checkPasswordOK(signUpForm.Password); !ok { + if ok := CheckPasswordOK(signUpForm.Password); !ok { ctx.String(http.StatusBadRequest, "Password violates the password rules") return } @@ -296,7 +296,7 @@ func patchPassword(repository UserQuery) gin.HandlerFunc { } // check password rules - if ok := checkPasswordOK(requestData.Password); !ok { + if ok := CheckPasswordOK(requestData.Password); !ok { ctx.String(http.StatusBadRequest, "Password violates the password rules") return } diff --git a/endpoint/user/util.go b/endpoint/user/util.go index 335266f..67c77ab 100644 --- a/endpoint/user/util.go +++ b/endpoint/user/util.go @@ -12,7 +12,7 @@ const minLength = 8 var emailPasslist = [...]string{"@stud.tu-darmstadt.de", "@akamu.de"} -func checkPasswordOK(pw string) bool { +func CheckPasswordOK(pw string) bool { if len(pw) < minLength { return false } diff --git a/endpoint/util.go b/endpoint/util.go index 873056a..f5858c4 100644 --- a/endpoint/util.go +++ b/endpoint/util.go @@ -5,6 +5,9 @@ import ( "net/http" "github.com/getsentry/raven-go" + "github.com/go-playground/locales" + "github.com/go-playground/locales/en" + ut "github.com/go-playground/universal-translator" "github.com/gin-gonic/gin" "gitlab.akamu.de/akamu/game-server-go/schemas" @@ -14,6 +17,9 @@ var ErrFetchingSessionPayload = errors.New("failed to fetch session payload") var errFetchingUserID = errors.New("failed fetching user id") var errFetchingUsername = errors.New("failed fetching username") +var transEngl locales.Translator +var translator ut.Translator + // GetSessionPayload returns the payload of the current session. // Returns error if unable to receive the session payload. func GetSessionPayload(ctx *gin.Context) (*schemas.TokenPayload, error) { @@ -56,3 +62,12 @@ func GetUsername(ctx *gin.Context) (string, error) { tokenPayload := identity.(schemas.TokenPayload) return tokenPayload.Username, nil } + +func GetTranslator() ut.Translator { + if transEngl == nil { + transEngl = en.New() + translator, _ = ut.New(transEngl).GetTranslator("en") + } + + return translator +} diff --git a/setup/setup.go b/setup/setup.go index dec295f..5331ce8 100644 --- a/setup/setup.go +++ b/setup/setup.go @@ -9,6 +9,7 @@ import ( "net/mail" "time" + "gitlab.akamu.de/akamu/game-server-go/endpoint" "gitlab.akamu.de/akamu/game-server-go/sendmail" "gitlab.akamu.de/akamu/game-server-go/token/otp" "gitlab.akamu.de/akamu/game-server-go/version" @@ -16,8 +17,11 @@ import ( "gitlab.akamu.de/akamu/game-server-go/schemas" "github.com/getsentry/raven-go" + ut "github.com/go-playground/universal-translator" + validator "github.com/go-playground/validator/v10" "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" jwt "gitlab.akamu.de/akamu/gin-jwt" "gitlab.akamu.de/akamu/game-server-go/config" @@ -121,6 +125,44 @@ func SetupRoutes(courseRepository course.CourseQuery, flashcardRepository flashc //gin.SetMode(gin.ReleaseMode) router := gin.Default() + if v, ok := binding.Validator.Engine().(*validator.Validate); ok { + // Register Password Validator + v.RegisterValidation("password", func(fl validator.FieldLevel) bool { + password, ok := fl.Field().Interface().(string) + if ok { + return user.CheckPasswordOK(password) + } + + return false + }) + + t := endpoint.GetTranslator() + + // Register custom error messages + v.RegisterTranslation("required", t, func(ut ut.Translator) error { + return ut.Add("required", "{0} cannot be empty.", true) + }, func(ut ut.Translator, fe validator.FieldError) string { + m, _ := ut.T("required", fe.Field()) + return m + }) + + v.RegisterTranslation("eqfield", t, func(ut ut.Translator) error { + return ut.Add("eqfield", "{0} must match the value of {1}.", true) + }, func(ut ut.Translator, fe validator.FieldError) string { + m, _ := ut.T("eqfield", fe.Field(), fe.Param()) + return m + }) + + v.RegisterTranslation("password", t, func(ut ut.Translator) error { + return ut.Add("password", "A valid password must be at least 8 characters long and must contain at least one uppercase and one lowercase letter.", true) + }, func(ut ut.Translator, fe validator.FieldError) string { + m, _ := ut.T("password") + return m + }) + } else { + panic("failed setting up password validator") + } + router.GET("/", getRoot) s := "secret" -- GitLab