Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0

Merge pull request #155 from akuma06/master

Added Form Validation
Cette révision appartient à :
akuma06 2017-05-07 20:04:27 +02:00 révisé par GitHub
révision 097639e208
7 fichiers modifiés avec 167 ajouts et 72 suppressions

Voir le fichier

@ -31,28 +31,12 @@ func GormInit(conf *config.Config) (*gorm.DB, error) {
if config.Environment == "DEVELOPMENT" {
db.LogMode(true)
// db.DropTable(&model.User{}, "UserFollower")
db.AutoMigrate(&model.Torrents{})
// db.AutoMigrate(&model.User{}, &model.Role{}, &model.Connection{}, &model.Language{}, &model.Article{}, &model.Location{}, &model.Comment{}, &model.File{})
db.AutoMigrate(&model.Torrents{}, &model.User{}, &model.Role{}, &model.Connection{}, &model.Language{})
// db.AutoMigrate(&model.Article{}, &model.Location{}, &model.Comment{}, &model.File{})
// db.Model(&model.User{}).AddIndex("idx_user_token", "token")
}
log.CheckError(err)
// relation := gorm.Relationship{}
// relation.Kind = "many2many"
// relation.ForeignFieldNames = []string{"id"} //(M1 pkey)
// relation.ForeignDBNames = []string{"user_id"} //(M1 fkey in m1m2join)
// relation.AssociationForeignFieldNames = []string{"id"} //(M2 pkey)
// // relation.AssociationForeignStructFieldNames = []string{"id", "ID"} //(m2 pkey name in m2 struct?)
// relation.AssociationForeignDBNames = []string{"follower_id"} //(m2 fkey in m1m2join)
// m1Type := reflect.TypeOf(model.User{})
// m2Type := reflect.TypeOf(model.User{})
// handler := gorm.JoinTableHandler{}
// // ORDER BELOW MATTERS
// // Install handler
// db.SetJoinTableHandler(&model.User{}, "Likings", &handler)
// // Configure handler to use the relation that we've defined
// handler.Setup(&relation, "users_followers", m1Type, m2Type)
return db, err
}

Voir le fichier

@ -38,6 +38,7 @@ type ViewTemplateVariables struct {
type UserRegisterTemplateVariables struct {
RegistrationForm userForms.RegistrationForm
FormErrors map[string][]string
Search SearchForm
Navigation Navigation
URL *url.URL // For parsing Url in templates

Voir le fichier

@ -7,6 +7,7 @@ import (
"github.com/ewhal/nyaa/service/user"
"github.com/ewhal/nyaa/service/user/form"
"github.com/ewhal/nyaa/util/languages"
"github.com/ewhal/nyaa/util/log"
"github.com/ewhal/nyaa/util/modelHelper"
"github.com/gorilla/mux"
)
@ -20,7 +21,7 @@ func UserRegisterFormHandler(w http.ResponseWriter, r *http.Request) {
modelHelper.BindValueForm(&b, r)
b.CaptchaID = captcha.GetID()
languages.SetTranslation("en-us", viewRegisterTemplate)
htv := UserRegisterTemplateVariables{b, NewSearchForm(), Navigation{}, r.URL, mux.CurrentRoute(r)}
htv := UserRegisterTemplateVariables{b, form.NewErrors(), NewSearchForm(), Navigation{}, r.URL, mux.CurrentRoute(r)}
err := viewRegisterTemplate.ExecuteTemplate(w, "index.html", htv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@ -52,31 +53,43 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
// Post Registration controller, we do some check on the form here, the rest on user service
func UserRegisterPostHandler(w http.ResponseWriter, r *http.Request) {
// Check same Password
b := form.RegistrationForm{}
err := form.NewErrors()
if !captcha.Authenticate(captcha.Extract(r)) {
// TODO: Prettier passing of mistyoed captcha errors
http.Error(w, captcha.ErrInvalidCaptcha.Error(), 403)
return
err["errors"] = append(err["errors"], "Wrong captcha!")
}
if (r.PostFormValue("password") == r.PostFormValue("password_confirm")) && (r.PostFormValue("password") != "") {
if (form.EmailValidation(r.PostFormValue("email"))) &&
(form.ValidateUsername(r.PostFormValue("username"))) &&
(form.IsAgreed(r.PostFormValue("t_and_c"))) {
_, err := userService.CreateUser(w, r)
if err == nil {
b := form.RegistrationForm{}
htv := UserRegisterTemplateVariables{b, NewSearchForm(), Navigation{}, r.URL, mux.CurrentRoute(r)}
err = viewRegisterSuccessTemplate.ExecuteTemplate(w, "index.html", htv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
} else {
UserRegisterFormHandler(w, r)
}
} else {
UserRegisterFormHandler(w, r)
if (len(err) == 0) {
_, err = form.EmailValidation(r.PostFormValue("email"), err)
_, err = form.ValidateUsername(r.PostFormValue("username"), err)
log.Info("test lets see 3")
if (len(err) == 0) {
modelHelper.BindValueForm(&b, r)
err = modelHelper.ValidateForm(&b, err)
log.Info("test lets see 1")
if (len(err) == 0) {
_, errorUser := userService.CreateUser(w, r)
err["errors"] = append(err["errors"], errorUser.Error())
log.Info("test lets see 2")
if (len(err) == 0) {
b := form.RegistrationForm{}
htv := UserRegisterTemplateVariables{b, err, NewSearchForm(), Navigation{}, r.URL, mux.CurrentRoute(r)}
errorTmpl := viewRegisterSuccessTemplate.ExecuteTemplate(w, "index.html", htv)
if errorTmpl != nil {
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
}
}
}
}
}
if (len(err) > 0) {
log.Info("test lets see 4")
b.CaptchaID = captcha.GetID()
languages.SetTranslation("en-us", viewRegisterTemplate)
htv := UserRegisterTemplateVariables{b, err, NewSearchForm(), Navigation{}, r.URL, mux.CurrentRoute(r)}
errorTmpl := viewRegisterTemplate.ExecuteTemplate(w, "index.html", htv)
if errorTmpl != nil {
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
}
} else {
UserRegisterFormHandler(w, r)
}
}

Voir le fichier

@ -89,7 +89,7 @@ func SetCookieHandler(w http.ResponseWriter, email string, pass string) (int, er
if email != "" && pass != "" {
log.Debugf("User email : %s , password : %s", email, pass)
var user model.User
isValidEmail := formStruct.EmailValidation(email)
isValidEmail, _ := formStruct.EmailValidation(email, formStruct.NewErrors())
if isValidEmail {
log.Debug("User entered valid email.")
if db.ORM.Where("email = ?", email).First(&user).RecordNotFound() {

Voir le fichier

@ -9,34 +9,34 @@ import (
const EMAIL_REGEX = `(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})`
const USERNAME_REGEX = `(\W)`
func EmailValidation(email string) bool {
exp, err := regexp.Compile(EMAIL_REGEX)
if regexpCompiled := log.CheckError(err); regexpCompiled {
func EmailValidation(email string, err map[string][]string) (bool, map[string][]string) {
exp, errorRegex := regexp.Compile(EMAIL_REGEX)
if regexpCompiled := log.CheckError(errorRegex); regexpCompiled {
if exp.MatchString(email) {
return true
}
}
return false
}
func ValidateUsername(username string) bool {
exp, err := regexp.Compile(USERNAME_REGEX)
if username == "" {
return false
}
if (len(username) < 3) || (len(username) > 15) {
return false
}
if regexpCompiled := log.CheckError(err); regexpCompiled {
if exp.MatchString(username) {
return false
err["email"] = append(err["email"], "Email Address is not valid")
return true, err
}
} else {
return false
return false, err
}
return true
return false, err
}
func ValidateUsername(username string, err map[string][]string) (bool, map[string][]string) {
exp, errorRegex := regexp.Compile(USERNAME_REGEX)
if regexpCompiled := log.CheckError(errorRegex); regexpCompiled {
if exp.MatchString(username) {
err["username"] = append(err["username"], "Username contains illegal characters")
return false, err
}
} else {
return false, err
}
return true, err
}
func NewErrors() map[string][]string {
err := make(map[string][]string)
return err
}
func IsAgreed(t_and_c string) bool {
if t_and_c == "1" {
@ -47,10 +47,12 @@ func IsAgreed(t_and_c string) bool {
// RegistrationForm is used when creating a user.
type RegistrationForm struct {
Username string `form:"registrationUsername"`
Email string `form:"registrationEmail"`
Password string `form:"registrationPassword"`
CaptchaID string `form:"captchaID" inmodel:"false"`
Username string `form:"username" needed:"true" min_len:"3" max_len:"20"`
Email string `form:"email" needed:"true"`
Password string `form:"password" needed:"true" min_len:"6" max_len:"25"`
Confirm_Password string `form:"password_confirmation" omit:"true" needed:"true"`
CaptchaID string `form:"captchaID" omit:"true" needed:"true"`
T_and_C bool `form:"t_and_c" omit:"true" needed:"true" equal:"true" hum_name:"Terms and Conditions"`
}
// RegistrationForm is used when creating a user authentication.

Voir le fichier

@ -8,21 +8,36 @@
<form role="form" method="POST">
<h2>{{T "signup_box_title" }}</h2>
<hr class="colorgraph">
{{ range (index $.FormErrors "errors")}}
<div class="alert alert-danger">{{ . }}</div>
{{end}}
<div class="form-group">
<input type="text" name="username" id="display_name" class="form-control input-lg" placeholder="{{T "username" }}" tabindex="1" value="{{ .Username }}">
{{ range (index $.FormErrors "username")}}
<p class="bg-danger">{{ . }}</p>
{{end}}
</div>
<div class="form-group">
<input type="email" name="email" id="email" class="form-control input-lg" placeholder="{{T "email_address" }}" tabindex="2" value="{{ .Email }}">
{{ range (index $.FormErrors "email")}}
<p class="bg-danger">{{ . }}</p>
{{end}}
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg" placeholder="{{T "password" }}" tabindex="3" value="{{ .Password }}">
</div>
{{ range (index $.FormErrors "password")}}
<p class="bg-danger">{{ . }}</p>
{{end}}
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
<input type="password" name="password_confirmation" id="password_confirmation" class="form-control input-lg" placeholder="{{T "confirm_password" }}" tabindex="4">
{{ range (index $.FormErrors "password_confirmation")}}
<p class="bg-danger">{{ . }}</p>
{{end}}
</div>
</div>
</div>
@ -31,6 +46,9 @@
<span class="button-checkbox">
<button type="button" class="btn hidden" data-color="info" tabindex="5">{{T "i_agree" }}</button>
<input type="checkbox" name="t_and_c" id="t_and_c" value="1">
{{ range (index $.FormErrors "t_and_c")}}
<p class="bg-danger">{{ . }}</p>
{{end}}
</span>
</div>
<div class="col-xs-8 col-sm-9 col-md-9">

Voir le fichier

@ -5,6 +5,7 @@ import (
"net/http"
"github.com/ewhal/nyaa/util/log"
"strconv"
"fmt"
)
func IsZeroOfUnderlyingType(x interface{}) bool {
@ -18,7 +19,7 @@ func AssignValue(model interface{}, form interface{}) {
typeOfTForm := formElem.Type()
for i := 0; i < formElem.NumField(); i++ {
tag := typeOfTForm.Field(i).Tag
if tag.Get("omit") != "false" {
if tag.Get("omit") != "true" {
modelField := modelIndirect.FieldByName(typeOfTForm.Field(i).Name)
if modelField.IsValid() {
formField := formElem.Field(i)
@ -46,6 +47,82 @@ func BindValueForm(form interface{}, r *http.Request) {
case "float" :
nbr, _ := strconv.Atoi(r.PostFormValue(tag.Get("form")))
formElem.Field(i).SetFloat(float64(nbr))
case "bool" :
nbr, _ := strconv.ParseBool(r.PostFormValue(tag.Get("form")))
formElem.Field(i).SetBool(nbr)
}
}
}
func ValidateForm(form interface{}, errorForm map[string][]string) (map[string][]string) {
formElem := reflect.ValueOf(form).Elem()
for i := 0; i < formElem.NumField(); i++ {
typeField := formElem.Type().Field(i)
tag := typeField.Tag
inputName := typeField.Name
if (tag.Get("hum_name") != "") { // For more human input name than gibberish
inputName = tag.Get("hum_name")
}
if tag.Get("len_min") != "" { // Check minimum length
lenMin, _ := strconv.Atoi(tag.Get("len_min"))
if formElem.Field(i).Len() < lenMin {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Minimal length of %s required for the input: %s", lenMin, inputName))
}
}
if tag.Get("len_max") != "" { // Check minimum length
lenMax, _ := strconv.Atoi(tag.Get("len_max"))
if formElem.Field(i).Len() > lenMax {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Maximal length of %s required for the input: %s", lenMax, inputName))
}
}
if tag.Get("equalInput") != "" {
otherInput := formElem.FieldByName(tag.Get("equalForm"))
if formElem.Field(i).Interface() != otherInput.Interface() {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
}
}
switch typeField.Type.Name() {
case "string" :
if tag.Get("equal") != "" && formElem.Field(i).String() != tag.Get("equal") {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
}
if tag.Get("needed") != "" && formElem.Field(i).String() == "" {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
}
case "int" :
if tag.Get("equal") != "" { // Check minimum length
equal, _ := strconv.Atoi(tag.Get("equal"))
if formElem.Field(i).Int() > int64(equal) {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
}
if tag.Get("needed") != "" && formElem.Field(i).Int() == 0 {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
}
}
case "float" :
if tag.Get("equal") != "" { // Check minimum length
equal, _ := strconv.Atoi(tag.Get("equal"))
if formElem.Field(i).Float() != float64(equal) {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
}
if tag.Get("needed") != "" && formElem.Field(i).Float() == 0 {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
}
}
case "bool" :
if tag.Get("equal") != "" { // Check minimum length
equal, _ := strconv.ParseBool(tag.Get("equal"))
if formElem.Field(i).Bool() != equal {
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
}
}
}
}
if (len(errorForm) == 0) { // If no error, return nil
return nil
}
return errorForm
}