2014-03-06 11:21:44 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"net/http"
"reflect"
2014-03-06 11:59:44 +04:00
"strings"
2014-03-06 11:21:44 +04:00
"github.com/codegangsta/martini"
"github.com/gogits/binding"
"github.com/gogits/gogs/modules/base"
2014-03-08 02:22:15 +04:00
"github.com/gogits/gogs/modules/log"
2014-03-06 11:21:44 +04:00
)
2014-03-09 06:25:38 +04:00
// Web form interface.
2014-03-06 20:10:35 +04:00
type Form interface {
Name ( field string ) string
}
2014-03-06 11:21:44 +04:00
type RegisterForm struct {
2014-03-06 20:10:35 +04:00
UserName string ` form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)" `
Email string ` form:"email" binding:"Required;Email;MaxSize(50)" `
Password string ` form:"passwd" binding:"Required;MinSize(6);MaxSize(30)" `
RetypePasswd string ` form:"retypepasswd" `
}
2014-03-06 20:42:14 +04:00
func ( f * RegisterForm ) Name ( field string ) string {
2014-03-06 20:10:35 +04:00
names := map [ string ] string {
"UserName" : "Username" ,
"Email" : "E-mail address" ,
"Password" : "Password" ,
"RetypePasswd" : "Re-type password" ,
}
return names [ field ]
2014-03-06 11:21:44 +04:00
}
2014-03-06 20:42:14 +04:00
func ( f * RegisterForm ) Validate ( errors * binding . Errors , req * http . Request , context martini . Context ) {
if req . Method == "GET" || errors . Count ( ) == 0 {
return
}
data := context . Get ( reflect . TypeOf ( base . TmplData { } ) ) . Interface ( ) . ( base . TmplData )
data [ "HasError" ] = true
AssignForm ( f , data )
if len ( errors . Overall ) > 0 {
for _ , err := range errors . Overall {
log . Error ( "RegisterForm.Validate: %v" , err )
}
return
}
validate ( errors , data , f )
}
type LogInForm struct {
UserName string ` form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)" `
Password string ` form:"passwd" binding:"Required;MinSize(6);MaxSize(30)" `
}
func ( f * LogInForm ) Name ( field string ) string {
names := map [ string ] string {
"UserName" : "Username" ,
"Password" : "Password" ,
}
return names [ field ]
}
func ( f * LogInForm ) Validate ( errors * binding . Errors , req * http . Request , context martini . Context ) {
if req . Method == "GET" || errors . Count ( ) == 0 {
return
}
data := context . Get ( reflect . TypeOf ( base . TmplData { } ) ) . Interface ( ) . ( base . TmplData )
data [ "HasError" ] = true
AssignForm ( f , data )
if len ( errors . Overall ) > 0 {
for _ , err := range errors . Overall {
log . Error ( "LogInForm.Validate: %v" , err )
}
return
}
validate ( errors , data , f )
}
2014-03-06 11:59:44 +04:00
func getMinMaxSize ( field reflect . StructField ) string {
for _ , rule := range strings . Split ( field . Tag . Get ( "binding" ) , ";" ) {
if strings . HasPrefix ( rule , "MinSize(" ) || strings . HasPrefix ( rule , "MaxSize(" ) {
return rule [ 8 : len ( rule ) - 1 ]
}
}
return ""
}
2014-03-06 20:10:35 +04:00
func validate ( errors * binding . Errors , data base . TmplData , form Form ) {
2014-03-06 11:59:44 +04:00
typ := reflect . TypeOf ( form )
val := reflect . ValueOf ( form )
if typ . Kind ( ) == reflect . Ptr {
typ = typ . Elem ( )
val = val . Elem ( )
}
for i := 0 ; i < typ . NumField ( ) ; i ++ {
field := typ . Field ( i )
fieldName := field . Tag . Get ( "form" )
// Allow ignored fields in the struct
if fieldName == "-" {
continue
}
if err , ok := errors . Fields [ field . Name ] ; ok {
data [ "Err_" + field . Name ] = true
switch err {
case binding . RequireError :
2014-03-06 20:10:35 +04:00
data [ "ErrorMsg" ] = form . Name ( field . Name ) + " cannot be empty"
2014-03-06 11:59:44 +04:00
case binding . AlphaDashError :
2014-03-06 20:10:35 +04:00
data [ "ErrorMsg" ] = form . Name ( field . Name ) + " must be valid alpha or numeric or dash(-_) characters"
2014-03-06 11:59:44 +04:00
case binding . MinSizeError :
2014-03-06 20:10:35 +04:00
data [ "ErrorMsg" ] = form . Name ( field . Name ) + " must contain at least " + getMinMaxSize ( field ) + " characters"
2014-03-06 11:59:44 +04:00
case binding . MaxSizeError :
2014-03-06 20:10:35 +04:00
data [ "ErrorMsg" ] = form . Name ( field . Name ) + " must contain at most " + getMinMaxSize ( field ) + " characters"
2014-03-06 11:59:44 +04:00
case binding . EmailError :
2014-03-06 20:10:35 +04:00
data [ "ErrorMsg" ] = form . Name ( field . Name ) + " is not valid"
2014-03-06 11:59:44 +04:00
default :
data [ "ErrorMsg" ] = "Unknown error: " + err
}
return
}
}
}
2014-03-06 11:21:44 +04:00
// AssignForm assign form values back to the template data.
func AssignForm ( form interface { } , data base . TmplData ) {
typ := reflect . TypeOf ( form )
val := reflect . ValueOf ( form )
if typ . Kind ( ) == reflect . Ptr {
typ = typ . Elem ( )
val = val . Elem ( )
}
for i := 0 ; i < typ . NumField ( ) ; i ++ {
field := typ . Field ( i )
fieldName := field . Tag . Get ( "form" )
// Allow ignored fields in the struct
if fieldName == "-" {
continue
}
data [ fieldName ] = val . Field ( i ) . Interface ( )
}
}