github.com/astaxie/beego@v1.12.3/validation/validators.go (about)

     1  // Copyright 2014 beego Author. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package validation
    16  
    17  import (
    18  	"fmt"
    19  	"reflect"
    20  	"regexp"
    21  	"strings"
    22  	"sync"
    23  	"time"
    24  	"unicode/utf8"
    25  
    26  	"github.com/astaxie/beego/logs"
    27  )
    28  
    29  // CanSkipFuncs will skip valid if RequiredFirst is true and the struct field's value is empty
    30  var CanSkipFuncs = map[string]struct{}{
    31  	"Email":   {},
    32  	"IP":      {},
    33  	"Mobile":  {},
    34  	"Tel":     {},
    35  	"Phone":   {},
    36  	"ZipCode": {},
    37  }
    38  
    39  // MessageTmpls store commond validate template
    40  var MessageTmpls = map[string]string{
    41  	"Required":     "Can not be empty",
    42  	"Min":          "Minimum is %d",
    43  	"Max":          "Maximum is %d",
    44  	"Range":        "Range is %d to %d",
    45  	"MinSize":      "Minimum size is %d",
    46  	"MaxSize":      "Maximum size is %d",
    47  	"Length":       "Required length is %d",
    48  	"Alpha":        "Must be valid alpha characters",
    49  	"Numeric":      "Must be valid numeric characters",
    50  	"AlphaNumeric": "Must be valid alpha or numeric characters",
    51  	"Match":        "Must match %s",
    52  	"NoMatch":      "Must not match %s",
    53  	"AlphaDash":    "Must be valid alpha or numeric or dash(-_) characters",
    54  	"Email":        "Must be a valid email address",
    55  	"IP":           "Must be a valid ip address",
    56  	"Base64":       "Must be valid base64 characters",
    57  	"Mobile":       "Must be valid mobile number",
    58  	"Tel":          "Must be valid telephone number",
    59  	"Phone":        "Must be valid telephone or mobile phone number",
    60  	"ZipCode":      "Must be valid zipcode",
    61  }
    62  
    63  var once sync.Once
    64  
    65  // SetDefaultMessage set default messages
    66  // if not set, the default messages are
    67  //  "Required":     "Can not be empty",
    68  //  "Min":          "Minimum is %d",
    69  //  "Max":          "Maximum is %d",
    70  //  "Range":        "Range is %d to %d",
    71  //  "MinSize":      "Minimum size is %d",
    72  //  "MaxSize":      "Maximum size is %d",
    73  //  "Length":       "Required length is %d",
    74  //  "Alpha":        "Must be valid alpha characters",
    75  //  "Numeric":      "Must be valid numeric characters",
    76  //  "AlphaNumeric": "Must be valid alpha or numeric characters",
    77  //  "Match":        "Must match %s",
    78  //  "NoMatch":      "Must not match %s",
    79  //  "AlphaDash":    "Must be valid alpha or numeric or dash(-_) characters",
    80  //  "Email":        "Must be a valid email address",
    81  //  "IP":           "Must be a valid ip address",
    82  //  "Base64":       "Must be valid base64 characters",
    83  //  "Mobile":       "Must be valid mobile number",
    84  //  "Tel":          "Must be valid telephone number",
    85  //  "Phone":        "Must be valid telephone or mobile phone number",
    86  //  "ZipCode":      "Must be valid zipcode",
    87  func SetDefaultMessage(msg map[string]string) {
    88  	if len(msg) == 0 {
    89  		return
    90  	}
    91  
    92  	once.Do(func() {
    93  		for name := range msg {
    94  			MessageTmpls[name] = msg[name]
    95  		}
    96  	})
    97  	logs.Warn(`you must SetDefaultMessage at once`)
    98  }
    99  
   100  // Validator interface
   101  type Validator interface {
   102  	IsSatisfied(interface{}) bool
   103  	DefaultMessage() string
   104  	GetKey() string
   105  	GetLimitValue() interface{}
   106  }
   107  
   108  // Required struct
   109  type Required struct {
   110  	Key string
   111  }
   112  
   113  // IsSatisfied judge whether obj has value
   114  func (r Required) IsSatisfied(obj interface{}) bool {
   115  	if obj == nil {
   116  		return false
   117  	}
   118  
   119  	if str, ok := obj.(string); ok {
   120  		return len(strings.TrimSpace(str)) > 0
   121  	}
   122  	if _, ok := obj.(bool); ok {
   123  		return true
   124  	}
   125  	if i, ok := obj.(int); ok {
   126  		return i != 0
   127  	}
   128  	if i, ok := obj.(uint); ok {
   129  		return i != 0
   130  	}
   131  	if i, ok := obj.(int8); ok {
   132  		return i != 0
   133  	}
   134  	if i, ok := obj.(uint8); ok {
   135  		return i != 0
   136  	}
   137  	if i, ok := obj.(int16); ok {
   138  		return i != 0
   139  	}
   140  	if i, ok := obj.(uint16); ok {
   141  		return i != 0
   142  	}
   143  	if i, ok := obj.(uint32); ok {
   144  		return i != 0
   145  	}
   146  	if i, ok := obj.(int32); ok {
   147  		return i != 0
   148  	}
   149  	if i, ok := obj.(int64); ok {
   150  		return i != 0
   151  	}
   152  	if i, ok := obj.(uint64); ok {
   153  		return i != 0
   154  	}
   155  	if t, ok := obj.(time.Time); ok {
   156  		return !t.IsZero()
   157  	}
   158  	v := reflect.ValueOf(obj)
   159  	if v.Kind() == reflect.Slice {
   160  		return v.Len() > 0
   161  	}
   162  	return true
   163  }
   164  
   165  // DefaultMessage return the default error message
   166  func (r Required) DefaultMessage() string {
   167  	return MessageTmpls["Required"]
   168  }
   169  
   170  // GetKey return the r.Key
   171  func (r Required) GetKey() string {
   172  	return r.Key
   173  }
   174  
   175  // GetLimitValue return nil now
   176  func (r Required) GetLimitValue() interface{} {
   177  	return nil
   178  }
   179  
   180  // Min check struct
   181  type Min struct {
   182  	Min int
   183  	Key string
   184  }
   185  
   186  // IsSatisfied judge whether obj is valid
   187  // not support int64 on 32-bit platform
   188  func (m Min) IsSatisfied(obj interface{}) bool {
   189  	var v int
   190  	switch obj.(type) {
   191  	case int64:
   192  		if wordsize == 32 {
   193  			return false
   194  		}
   195  		v = int(obj.(int64))
   196  	case int:
   197  		v = obj.(int)
   198  	case int32:
   199  		v = int(obj.(int32))
   200  	case int16:
   201  		v = int(obj.(int16))
   202  	case int8:
   203  		v = int(obj.(int8))
   204  	default:
   205  		return false
   206  	}
   207  
   208  	return v >= m.Min
   209  }
   210  
   211  // DefaultMessage return the default min error message
   212  func (m Min) DefaultMessage() string {
   213  	return fmt.Sprintf(MessageTmpls["Min"], m.Min)
   214  }
   215  
   216  // GetKey return the m.Key
   217  func (m Min) GetKey() string {
   218  	return m.Key
   219  }
   220  
   221  // GetLimitValue return the limit value, Min
   222  func (m Min) GetLimitValue() interface{} {
   223  	return m.Min
   224  }
   225  
   226  // Max validate struct
   227  type Max struct {
   228  	Max int
   229  	Key string
   230  }
   231  
   232  // IsSatisfied judge whether obj is valid
   233  // not support int64 on 32-bit platform
   234  func (m Max) IsSatisfied(obj interface{}) bool {
   235  	var v int
   236  	switch obj.(type) {
   237  	case int64:
   238  		if wordsize == 32 {
   239  			return false
   240  		}
   241  		v = int(obj.(int64))
   242  	case int:
   243  		v = obj.(int)
   244  	case int32:
   245  		v = int(obj.(int32))
   246  	case int16:
   247  		v = int(obj.(int16))
   248  	case int8:
   249  		v = int(obj.(int8))
   250  	default:
   251  		return false
   252  	}
   253  
   254  	return v <= m.Max
   255  }
   256  
   257  // DefaultMessage return the default max error message
   258  func (m Max) DefaultMessage() string {
   259  	return fmt.Sprintf(MessageTmpls["Max"], m.Max)
   260  }
   261  
   262  // GetKey return the m.Key
   263  func (m Max) GetKey() string {
   264  	return m.Key
   265  }
   266  
   267  // GetLimitValue return the limit value, Max
   268  func (m Max) GetLimitValue() interface{} {
   269  	return m.Max
   270  }
   271  
   272  // Range Requires an integer to be within Min, Max inclusive.
   273  type Range struct {
   274  	Min
   275  	Max
   276  	Key string
   277  }
   278  
   279  // IsSatisfied judge whether obj is valid
   280  // not support int64 on 32-bit platform
   281  func (r Range) IsSatisfied(obj interface{}) bool {
   282  	return r.Min.IsSatisfied(obj) && r.Max.IsSatisfied(obj)
   283  }
   284  
   285  // DefaultMessage return the default Range error message
   286  func (r Range) DefaultMessage() string {
   287  	return fmt.Sprintf(MessageTmpls["Range"], r.Min.Min, r.Max.Max)
   288  }
   289  
   290  // GetKey return the m.Key
   291  func (r Range) GetKey() string {
   292  	return r.Key
   293  }
   294  
   295  // GetLimitValue return the limit value, Max
   296  func (r Range) GetLimitValue() interface{} {
   297  	return []int{r.Min.Min, r.Max.Max}
   298  }
   299  
   300  // MinSize Requires an array or string to be at least a given length.
   301  type MinSize struct {
   302  	Min int
   303  	Key string
   304  }
   305  
   306  // IsSatisfied judge whether obj is valid
   307  func (m MinSize) IsSatisfied(obj interface{}) bool {
   308  	if str, ok := obj.(string); ok {
   309  		return utf8.RuneCountInString(str) >= m.Min
   310  	}
   311  	v := reflect.ValueOf(obj)
   312  	if v.Kind() == reflect.Slice {
   313  		return v.Len() >= m.Min
   314  	}
   315  	return false
   316  }
   317  
   318  // DefaultMessage return the default MinSize error message
   319  func (m MinSize) DefaultMessage() string {
   320  	return fmt.Sprintf(MessageTmpls["MinSize"], m.Min)
   321  }
   322  
   323  // GetKey return the m.Key
   324  func (m MinSize) GetKey() string {
   325  	return m.Key
   326  }
   327  
   328  // GetLimitValue return the limit value
   329  func (m MinSize) GetLimitValue() interface{} {
   330  	return m.Min
   331  }
   332  
   333  // MaxSize Requires an array or string to be at most a given length.
   334  type MaxSize struct {
   335  	Max int
   336  	Key string
   337  }
   338  
   339  // IsSatisfied judge whether obj is valid
   340  func (m MaxSize) IsSatisfied(obj interface{}) bool {
   341  	if str, ok := obj.(string); ok {
   342  		return utf8.RuneCountInString(str) <= m.Max
   343  	}
   344  	v := reflect.ValueOf(obj)
   345  	if v.Kind() == reflect.Slice {
   346  		return v.Len() <= m.Max
   347  	}
   348  	return false
   349  }
   350  
   351  // DefaultMessage return the default MaxSize error message
   352  func (m MaxSize) DefaultMessage() string {
   353  	return fmt.Sprintf(MessageTmpls["MaxSize"], m.Max)
   354  }
   355  
   356  // GetKey return the m.Key
   357  func (m MaxSize) GetKey() string {
   358  	return m.Key
   359  }
   360  
   361  // GetLimitValue return the limit value
   362  func (m MaxSize) GetLimitValue() interface{} {
   363  	return m.Max
   364  }
   365  
   366  // Length Requires an array or string to be exactly a given length.
   367  type Length struct {
   368  	N   int
   369  	Key string
   370  }
   371  
   372  // IsSatisfied judge whether obj is valid
   373  func (l Length) IsSatisfied(obj interface{}) bool {
   374  	if str, ok := obj.(string); ok {
   375  		return utf8.RuneCountInString(str) == l.N
   376  	}
   377  	v := reflect.ValueOf(obj)
   378  	if v.Kind() == reflect.Slice {
   379  		return v.Len() == l.N
   380  	}
   381  	return false
   382  }
   383  
   384  // DefaultMessage return the default Length error message
   385  func (l Length) DefaultMessage() string {
   386  	return fmt.Sprintf(MessageTmpls["Length"], l.N)
   387  }
   388  
   389  // GetKey return the m.Key
   390  func (l Length) GetKey() string {
   391  	return l.Key
   392  }
   393  
   394  // GetLimitValue return the limit value
   395  func (l Length) GetLimitValue() interface{} {
   396  	return l.N
   397  }
   398  
   399  // Alpha check the alpha
   400  type Alpha struct {
   401  	Key string
   402  }
   403  
   404  // IsSatisfied judge whether obj is valid
   405  func (a Alpha) IsSatisfied(obj interface{}) bool {
   406  	if str, ok := obj.(string); ok {
   407  		for _, v := range str {
   408  			if ('Z' < v || v < 'A') && ('z' < v || v < 'a') {
   409  				return false
   410  			}
   411  		}
   412  		return true
   413  	}
   414  	return false
   415  }
   416  
   417  // DefaultMessage return the default Length error message
   418  func (a Alpha) DefaultMessage() string {
   419  	return MessageTmpls["Alpha"]
   420  }
   421  
   422  // GetKey return the m.Key
   423  func (a Alpha) GetKey() string {
   424  	return a.Key
   425  }
   426  
   427  // GetLimitValue return the limit value
   428  func (a Alpha) GetLimitValue() interface{} {
   429  	return nil
   430  }
   431  
   432  // Numeric check number
   433  type Numeric struct {
   434  	Key string
   435  }
   436  
   437  // IsSatisfied judge whether obj is valid
   438  func (n Numeric) IsSatisfied(obj interface{}) bool {
   439  	if str, ok := obj.(string); ok {
   440  		for _, v := range str {
   441  			if '9' < v || v < '0' {
   442  				return false
   443  			}
   444  		}
   445  		return true
   446  	}
   447  	return false
   448  }
   449  
   450  // DefaultMessage return the default Length error message
   451  func (n Numeric) DefaultMessage() string {
   452  	return MessageTmpls["Numeric"]
   453  }
   454  
   455  // GetKey return the n.Key
   456  func (n Numeric) GetKey() string {
   457  	return n.Key
   458  }
   459  
   460  // GetLimitValue return the limit value
   461  func (n Numeric) GetLimitValue() interface{} {
   462  	return nil
   463  }
   464  
   465  // AlphaNumeric check alpha and number
   466  type AlphaNumeric struct {
   467  	Key string
   468  }
   469  
   470  // IsSatisfied judge whether obj is valid
   471  func (a AlphaNumeric) IsSatisfied(obj interface{}) bool {
   472  	if str, ok := obj.(string); ok {
   473  		for _, v := range str {
   474  			if ('Z' < v || v < 'A') && ('z' < v || v < 'a') && ('9' < v || v < '0') {
   475  				return false
   476  			}
   477  		}
   478  		return true
   479  	}
   480  	return false
   481  }
   482  
   483  // DefaultMessage return the default Length error message
   484  func (a AlphaNumeric) DefaultMessage() string {
   485  	return MessageTmpls["AlphaNumeric"]
   486  }
   487  
   488  // GetKey return the a.Key
   489  func (a AlphaNumeric) GetKey() string {
   490  	return a.Key
   491  }
   492  
   493  // GetLimitValue return the limit value
   494  func (a AlphaNumeric) GetLimitValue() interface{} {
   495  	return nil
   496  }
   497  
   498  // Match Requires a string to match a given regex.
   499  type Match struct {
   500  	Regexp *regexp.Regexp
   501  	Key    string
   502  }
   503  
   504  // IsSatisfied judge whether obj is valid
   505  func (m Match) IsSatisfied(obj interface{}) bool {
   506  	return m.Regexp.MatchString(fmt.Sprintf("%v", obj))
   507  }
   508  
   509  // DefaultMessage return the default Match error message
   510  func (m Match) DefaultMessage() string {
   511  	return fmt.Sprintf(MessageTmpls["Match"], m.Regexp.String())
   512  }
   513  
   514  // GetKey return the m.Key
   515  func (m Match) GetKey() string {
   516  	return m.Key
   517  }
   518  
   519  // GetLimitValue return the limit value
   520  func (m Match) GetLimitValue() interface{} {
   521  	return m.Regexp.String()
   522  }
   523  
   524  // NoMatch Requires a string to not match a given regex.
   525  type NoMatch struct {
   526  	Match
   527  	Key string
   528  }
   529  
   530  // IsSatisfied judge whether obj is valid
   531  func (n NoMatch) IsSatisfied(obj interface{}) bool {
   532  	return !n.Match.IsSatisfied(obj)
   533  }
   534  
   535  // DefaultMessage return the default NoMatch error message
   536  func (n NoMatch) DefaultMessage() string {
   537  	return fmt.Sprintf(MessageTmpls["NoMatch"], n.Regexp.String())
   538  }
   539  
   540  // GetKey return the n.Key
   541  func (n NoMatch) GetKey() string {
   542  	return n.Key
   543  }
   544  
   545  // GetLimitValue return the limit value
   546  func (n NoMatch) GetLimitValue() interface{} {
   547  	return n.Regexp.String()
   548  }
   549  
   550  var alphaDashPattern = regexp.MustCompile(`[^\d\w-_]`)
   551  
   552  // AlphaDash check not Alpha
   553  type AlphaDash struct {
   554  	NoMatch
   555  	Key string
   556  }
   557  
   558  // DefaultMessage return the default AlphaDash error message
   559  func (a AlphaDash) DefaultMessage() string {
   560  	return MessageTmpls["AlphaDash"]
   561  }
   562  
   563  // GetKey return the n.Key
   564  func (a AlphaDash) GetKey() string {
   565  	return a.Key
   566  }
   567  
   568  // GetLimitValue return the limit value
   569  func (a AlphaDash) GetLimitValue() interface{} {
   570  	return nil
   571  }
   572  
   573  var emailPattern = regexp.MustCompile(`^[\w!#$%&'*+/=?^_` + "`" + `{|}~-]+(?:\.[\w!#$%&'*+/=?^_` + "`" + `{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[a-zA-Z0-9](?:[\w-]*[\w])?$`)
   574  
   575  // Email check struct
   576  type Email struct {
   577  	Match
   578  	Key string
   579  }
   580  
   581  // DefaultMessage return the default Email error message
   582  func (e Email) DefaultMessage() string {
   583  	return MessageTmpls["Email"]
   584  }
   585  
   586  // GetKey return the n.Key
   587  func (e Email) GetKey() string {
   588  	return e.Key
   589  }
   590  
   591  // GetLimitValue return the limit value
   592  func (e Email) GetLimitValue() interface{} {
   593  	return nil
   594  }
   595  
   596  var ipPattern = regexp.MustCompile(`^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$`)
   597  
   598  // IP check struct
   599  type IP struct {
   600  	Match
   601  	Key string
   602  }
   603  
   604  // DefaultMessage return the default IP error message
   605  func (i IP) DefaultMessage() string {
   606  	return MessageTmpls["IP"]
   607  }
   608  
   609  // GetKey return the i.Key
   610  func (i IP) GetKey() string {
   611  	return i.Key
   612  }
   613  
   614  // GetLimitValue return the limit value
   615  func (i IP) GetLimitValue() interface{} {
   616  	return nil
   617  }
   618  
   619  var base64Pattern = regexp.MustCompile(`^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$`)
   620  
   621  // Base64 check struct
   622  type Base64 struct {
   623  	Match
   624  	Key string
   625  }
   626  
   627  // DefaultMessage return the default Base64 error message
   628  func (b Base64) DefaultMessage() string {
   629  	return MessageTmpls["Base64"]
   630  }
   631  
   632  // GetKey return the b.Key
   633  func (b Base64) GetKey() string {
   634  	return b.Key
   635  }
   636  
   637  // GetLimitValue return the limit value
   638  func (b Base64) GetLimitValue() interface{} {
   639  	return nil
   640  }
   641  
   642  // just for chinese mobile phone number
   643  var mobilePattern = regexp.MustCompile(`^((\+86)|(86))?1([356789][0-9]|4[579]|6[67]|7[0135678]|9[189])[0-9]{8}$`)
   644  
   645  // Mobile check struct
   646  type Mobile struct {
   647  	Match
   648  	Key string
   649  }
   650  
   651  // DefaultMessage return the default Mobile error message
   652  func (m Mobile) DefaultMessage() string {
   653  	return MessageTmpls["Mobile"]
   654  }
   655  
   656  // GetKey return the m.Key
   657  func (m Mobile) GetKey() string {
   658  	return m.Key
   659  }
   660  
   661  // GetLimitValue return the limit value
   662  func (m Mobile) GetLimitValue() interface{} {
   663  	return nil
   664  }
   665  
   666  // just for chinese telephone number
   667  var telPattern = regexp.MustCompile(`^(0\d{2,3}(\-)?)?\d{7,8}$`)
   668  
   669  // Tel check telephone struct
   670  type Tel struct {
   671  	Match
   672  	Key string
   673  }
   674  
   675  // DefaultMessage return the default Tel error message
   676  func (t Tel) DefaultMessage() string {
   677  	return MessageTmpls["Tel"]
   678  }
   679  
   680  // GetKey return the t.Key
   681  func (t Tel) GetKey() string {
   682  	return t.Key
   683  }
   684  
   685  // GetLimitValue return the limit value
   686  func (t Tel) GetLimitValue() interface{} {
   687  	return nil
   688  }
   689  
   690  // Phone just for chinese telephone or mobile phone number
   691  type Phone struct {
   692  	Mobile
   693  	Tel
   694  	Key string
   695  }
   696  
   697  // IsSatisfied judge whether obj is valid
   698  func (p Phone) IsSatisfied(obj interface{}) bool {
   699  	return p.Mobile.IsSatisfied(obj) || p.Tel.IsSatisfied(obj)
   700  }
   701  
   702  // DefaultMessage return the default Phone error message
   703  func (p Phone) DefaultMessage() string {
   704  	return MessageTmpls["Phone"]
   705  }
   706  
   707  // GetKey return the p.Key
   708  func (p Phone) GetKey() string {
   709  	return p.Key
   710  }
   711  
   712  // GetLimitValue return the limit value
   713  func (p Phone) GetLimitValue() interface{} {
   714  	return nil
   715  }
   716  
   717  // just for chinese zipcode
   718  var zipCodePattern = regexp.MustCompile(`^[1-9]\d{5}$`)
   719  
   720  // ZipCode check the zip struct
   721  type ZipCode struct {
   722  	Match
   723  	Key string
   724  }
   725  
   726  // DefaultMessage return the default Zip error message
   727  func (z ZipCode) DefaultMessage() string {
   728  	return MessageTmpls["ZipCode"]
   729  }
   730  
   731  // GetKey return the z.Key
   732  func (z ZipCode) GetKey() string {
   733  	return z.Key
   734  }
   735  
   736  // GetLimitValue return the limit value
   737  func (z ZipCode) GetLimitValue() interface{} {
   738  	return nil
   739  }