code.gitea.io/gitea@v1.21.7/models/db/name.go (about)

     1  // Copyright 2021 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package db
     5  
     6  import (
     7  	"fmt"
     8  	"regexp"
     9  	"strings"
    10  	"unicode/utf8"
    11  
    12  	"code.gitea.io/gitea/modules/util"
    13  )
    14  
    15  var (
    16  	// ErrNameEmpty name is empty error
    17  	ErrNameEmpty = util.SilentWrap{Message: "name is empty", Err: util.ErrInvalidArgument}
    18  
    19  	// AlphaDashDotPattern characters prohibited in a user name (anything except A-Za-z0-9_.-)
    20  	AlphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
    21  )
    22  
    23  // ErrNameReserved represents a "reserved name" error.
    24  type ErrNameReserved struct {
    25  	Name string
    26  }
    27  
    28  // IsErrNameReserved checks if an error is a ErrNameReserved.
    29  func IsErrNameReserved(err error) bool {
    30  	_, ok := err.(ErrNameReserved)
    31  	return ok
    32  }
    33  
    34  func (err ErrNameReserved) Error() string {
    35  	return fmt.Sprintf("name is reserved [name: %s]", err.Name)
    36  }
    37  
    38  // Unwrap unwraps this as a ErrInvalid err
    39  func (err ErrNameReserved) Unwrap() error {
    40  	return util.ErrInvalidArgument
    41  }
    42  
    43  // ErrNamePatternNotAllowed represents a "pattern not allowed" error.
    44  type ErrNamePatternNotAllowed struct {
    45  	Pattern string
    46  }
    47  
    48  // IsErrNamePatternNotAllowed checks if an error is an ErrNamePatternNotAllowed.
    49  func IsErrNamePatternNotAllowed(err error) bool {
    50  	_, ok := err.(ErrNamePatternNotAllowed)
    51  	return ok
    52  }
    53  
    54  func (err ErrNamePatternNotAllowed) Error() string {
    55  	return fmt.Sprintf("name pattern is not allowed [pattern: %s]", err.Pattern)
    56  }
    57  
    58  // Unwrap unwraps this as a ErrInvalid err
    59  func (err ErrNamePatternNotAllowed) Unwrap() error {
    60  	return util.ErrInvalidArgument
    61  }
    62  
    63  // ErrNameCharsNotAllowed represents a "character not allowed in name" error.
    64  type ErrNameCharsNotAllowed struct {
    65  	Name string
    66  }
    67  
    68  // IsErrNameCharsNotAllowed checks if an error is an ErrNameCharsNotAllowed.
    69  func IsErrNameCharsNotAllowed(err error) bool {
    70  	_, ok := err.(ErrNameCharsNotAllowed)
    71  	return ok
    72  }
    73  
    74  func (err ErrNameCharsNotAllowed) Error() string {
    75  	return fmt.Sprintf("name is invalid [%s]: must be valid alpha or numeric or dash(-_) or dot characters", err.Name)
    76  }
    77  
    78  // Unwrap unwraps this as a ErrInvalid err
    79  func (err ErrNameCharsNotAllowed) Unwrap() error {
    80  	return util.ErrInvalidArgument
    81  }
    82  
    83  // IsUsableName checks if name is reserved or pattern of name is not allowed
    84  // based on given reserved names and patterns.
    85  // Names are exact match, patterns can be prefix or suffix match with placeholder '*'.
    86  func IsUsableName(names, patterns []string, name string) error {
    87  	name = strings.TrimSpace(strings.ToLower(name))
    88  	if utf8.RuneCountInString(name) == 0 {
    89  		return ErrNameEmpty
    90  	}
    91  
    92  	for i := range names {
    93  		if name == names[i] {
    94  			return ErrNameReserved{name}
    95  		}
    96  	}
    97  
    98  	for _, pat := range patterns {
    99  		if pat[0] == '*' && strings.HasSuffix(name, pat[1:]) ||
   100  			(pat[len(pat)-1] == '*' && strings.HasPrefix(name, pat[:len(pat)-1])) {
   101  			return ErrNamePatternNotAllowed{pat}
   102  		}
   103  	}
   104  
   105  	return nil
   106  }