BigW Consortium Gitlab

regex.rb 4.91 KB
Newer Older
1 2 3 4
module Gitlab
  module Regex
    extend self

5 6 7
    # The namespace regex is used in Javascript to validate usernames in the "Register" form. However, Javascript
    # does not support the negative lookbehind assertion (?<!) that disallows usernames ending in `.git` and `.atom`.
    # Since this is a non-trivial problem to solve in Javascript (heavily complicate the regex, modify view code to
8
    # allow non-regex validatiions, etc), `NAMESPACE_REGEX_STR_JS` serves as a Javascript-compatible version of
9 10
    # `NAMESPACE_REGEX_STR`, with the negative lookbehind assertion removed. This means that the client-side validation
    # will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation.
11
    PATH_REGEX_STR = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*'.freeze
12 13 14 15
    NAMESPACE_REGEX_STR_JS = PATH_REGEX_STR + '[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze
    NO_SUFFIX_REGEX_STR = '(?<!\.git|\.atom)'.freeze
    NAMESPACE_REGEX_STR = "(?:#{NAMESPACE_REGEX_STR_JS})#{NO_SUFFIX_REGEX_STR}".freeze
    PROJECT_REGEX_STR = "(?:#{PATH_REGEX_STR})#{NO_SUFFIX_REGEX_STR}".freeze
16

17 18
    # Same as NAMESPACE_REGEX_STR but allows `/` in the path.
    # So `group/subgroup` will match this regex but not NAMESPACE_REGEX_STR
19
    FULL_NAMESPACE_REGEX_STR = "(?:#{NAMESPACE_REGEX_STR}/)*#{NAMESPACE_REGEX_STR}".freeze
20

21 22
    def namespace_regex
      @namespace_regex ||= /\A#{NAMESPACE_REGEX_STR}\z/.freeze
23 24
    end

25 26 27 28
    def full_namespace_regex
      @full_namespace_regex ||= %r{\A#{FULL_NAMESPACE_REGEX_STR}\z}
    end

29 30 31 32
    def namespace_route_regex
      @namespace_route_regex ||= /#{NAMESPACE_REGEX_STR}/.freeze
    end

33
    def namespace_regex_message
34
      "can contain only letters, digits, '_', '-' and '.'. " \
35
      "Cannot start with '-' or end in '.', '.git' or '.atom'." \
36 37 38
    end

    def namespace_name_regex
39
      @namespace_name_regex ||= /\A[\p{Alnum}\p{Pd}_\. ]*\z/.freeze
40 41
    end

42
    def namespace_name_regex_message
43
      "can contain only letters, digits, '_', '.', dash and space."
44 45
    end

46
    def project_name_regex
47
      @project_name_regex ||= /\A[\p{Alnum}\u{00A9}-\u{1f9c0}_][\p{Alnum}\p{Pd}\u{00A9}-\u{1f9c0}_\. ]*\z/.freeze
48 49
    end

50
    def project_name_regex_message
51 52
      "can contain only letters, digits, emojis, '_', '.', dash, space. " \
      "It must start with letter, digit, emoji or '_'."
53 54
    end

55
    def project_path_regex
56 57 58 59 60 61 62 63 64
      @project_path_regex ||= /\A#{PROJECT_REGEX_STR}\z/.freeze
    end

    def project_route_regex
      @project_route_regex ||= /#{PROJECT_REGEX_STR}/.freeze
    end

    def project_git_route_regex
      @project_route_git_regex ||= /#{PATH_REGEX_STR}\.git/.freeze
65 66
    end

67 68
    def project_path_regex_message
      "can contain only letters, digits, '_', '-' and '.'. " \
69
      "Cannot start with '-', end in '.git' or end in '.atom'" \
70 71
    end

72
    def file_name_regex
73
      @file_name_regex ||= /\A[[[:alnum:]]_\-\.\@\+]*\z/.freeze
74
    end
75

76
    def file_name_regex_message
77
      "can contain only letters, digits, '_', '-', '@', '+' and '.'."
78 79
    end

80
    def archive_formats_regex
81 82
      #                           |zip|tar|    tar.gz    |         tar.bz2         |
      @archive_formats_regex ||= /(zip|tar|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/.freeze
83
    end
84

85 86 87 88
    def git_reference_regex
      # Valid git ref regex, see:
      # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html

89
      @git_reference_regex ||= %r{
90
        (?!
91 92 93
           (?# doesn't begins with)
           \/|                    (?# rule #6)
           (?# doesn't contain)
94
           .*(?:
95 96 97 98
              [\/.]\.|            (?# rule #1,3)
              \/\/|               (?# rule #6)
              @\{|                (?# rule #8)
              \\                  (?# rule #9)
99 100
           )
        )
101 102 103 104
        [^\000-\040\177~^:?*\[]+  (?# rule #4-5)
        (?# doesn't end with)
        (?<!\.lock)               (?# rule #1)
        (?<![\/.])                (?# rule #6-7)
105
      }x.freeze
106
    end
107

Kamil Trzcinski committed
108
    def container_registry_reference_regex
109 110
      git_reference_regex
    end
111

112 113 114 115 116 117 118
    ##
    # Docker Distribution Registry 2.4.1 repository name rules
    #
    def container_repository_name_regex
      @container_repository_regex ||= %r{\A[a-z0-9]+(?:[-._/][a-z0-9]+)*\Z}
    end

119
    def environment_name_regex
120
      @environment_name_regex ||= /\A[a-zA-Z0-9_\\\/\${}. -]+\z/.freeze
121 122 123
    end

    def environment_name_regex_message
124
      "can contain only letters, digits, '-', '_', '/', '$', '{', '}', '.' and spaces"
125
    end
126 127 128 129 130 131 132 133

    def kubernetes_namespace_regex
      /\A[a-z0-9]([-a-z0-9]*[a-z0-9])?\z/
    end

    def kubernetes_namespace_regex_message
      "can contain only letters, digits or '-', and cannot start or end with '-'"
    end
Nick Thomas committed
134 135 136 137 138 139 140 141 142

    def environment_slug_regex
      @environment_slug_regex ||= /\A[a-z]([a-z0-9-]*[a-z0-9])?\z/.freeze
    end

    def environment_slug_regex_message
      "can contain only lowercase letters, digits, and '-'. " \
      "Must start with a letter, and cannot end with '-'"
    end
143 144
  end
end