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 }