github.com/erda-project/erda-infra@v1.0.9/pkg/strutil/validator.go (about) 1 // Copyright (c) 2021 Terminus, Inc. 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 strutil 16 17 import ( 18 "fmt" 19 "regexp" 20 "unicode" 21 ) 22 23 // Validator defines a validator function. 24 // User can extend validator in their own packages. 25 type Validator func(s string) error 26 27 // Validate validate `s` with composed validators and return error if have 28 func Validate(s string, validators ...Validator) error { 29 for _, v := range validators { 30 if err := v(s); err != nil { 31 return err 32 } 33 } 34 return nil 35 } 36 37 // MinLenValidator verify if `s` meets the minimum length requirement. 38 func MinLenValidator(minLen int) Validator { 39 return func(s string) error { 40 if len(s) < minLen { 41 if minLen == 1 { 42 return fmt.Errorf("cannot be empty") 43 } 44 return fmt.Errorf("less than min length: %d", minLen) 45 } 46 return nil 47 } 48 } 49 50 // MaxLenValidator check whether `s` exceeds the maximum length. 51 func MaxLenValidator(maxLen int) Validator { 52 return func(s string) error { 53 if len(s) > maxLen { 54 return fmt.Errorf("over max length: %d", maxLen) 55 } 56 return nil 57 } 58 } 59 60 // MaxRuneCountValidator check max rune count. 61 func MaxRuneCountValidator(maxLen int) Validator { 62 return func(s string) error { 63 if len([]rune(s)) > maxLen { 64 return fmt.Errorf("over max rune count: %d", maxLen) 65 } 66 return nil 67 } 68 } 69 70 var envKeyRegexp = regexp.MustCompilePOSIX(`^[a-zA-Z_]+[a-zA-Z0-9_]*$`) 71 72 // EnvKeyValidator check whether `s` meets the linux env key specification. 73 var EnvKeyValidator Validator = func(s string) error { 74 valid := envKeyRegexp.MatchString(s) 75 if !valid { 76 return fmt.Errorf("illegal env key, validated by regexp: %s", envKeyRegexp.String()) 77 } 78 return nil 79 } 80 81 // EnvValueLenValidator check whether `s` exceeds the maximum length of linux env value. 82 var EnvValueLenValidator = MaxLenValidator(128 * 1024) 83 84 // NoChineseValidator check whether `s` contains Chinese characters. 85 var NoChineseValidator Validator = func(s string) error { 86 var chineseCharacters []string 87 for _, runeValue := range s { 88 if unicode.Is(unicode.Han, runeValue) { 89 chineseCharacters = append(chineseCharacters, string(runeValue)) 90 } 91 } 92 if len(chineseCharacters) > 0 { 93 return fmt.Errorf("found %d chinese characters: %s", len(chineseCharacters), 94 Join(chineseCharacters, " ", true)) 95 } 96 return nil 97 } 98 99 // AlphaNumericDashUnderscoreValidator regular expression verification, can only: 100 // - start with uppercase and lowercase letters or numbers 101 // - supports uppercase and lowercase letters, numbers, underscores, underscores, and dots 102 var AlphaNumericDashUnderscoreValidator Validator = func(s string) error { 103 exp := `^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$` 104 valid := regexp.MustCompile(exp).MatchString(s) 105 if !valid { 106 return fmt.Errorf("valid regexp: %s", exp) 107 } 108 return nil 109 }