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  }