51 lines
1.9 KiB
Ruby
51 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Pages
|
|
class RandomDomain
|
|
PROJECT_PATH_LIMIT = 48
|
|
SUBDOMAIN_LABEL_LIMIT = 63
|
|
|
|
def self.generate(project_path:, namespace_path:)
|
|
new(project_path: project_path, namespace_path: namespace_path).generate
|
|
end
|
|
|
|
def initialize(project_path:, namespace_path:)
|
|
@project_path = project_path
|
|
@namespace_path = namespace_path
|
|
end
|
|
|
|
# Subdomains have a limit of 63 bytes (https://www.freesoft.org/CIE/RFC/1035/9.htm)
|
|
# For this reason we're limiting each part of the unique subdomain
|
|
#
|
|
# The domain is made up of 3 parts, like: projectpath-namespacepath-randomstring
|
|
# - project path: between 1 and 48 chars
|
|
# - namespace path: when the project path has less than 48 chars,
|
|
# the namespace full path will be used to fill the value up to 48 chars
|
|
# - random hexadecimal: to ensure a random value, the domain is then filled
|
|
# with a random hexadecimal value to complete 63 chars
|
|
def generate
|
|
domain = project_path.byteslice(0, PROJECT_PATH_LIMIT)
|
|
|
|
# if the project_path has less than PROJECT_PATH_LIMIT chars,
|
|
# fill the domain with the parent full_path up to 48 chars like:
|
|
# projectpath-namespacepath
|
|
if domain.length < PROJECT_PATH_LIMIT
|
|
namespace_size = PROJECT_PATH_LIMIT - domain.length - 1
|
|
domain.concat('-', namespace_path.byteslice(0, namespace_size))
|
|
end
|
|
|
|
# Complete the domain with random hexadecimal values util it is 63 chars long
|
|
# PS.: SecureRandom.hex return an string twice the size passed as argument.
|
|
domain.concat('-', SecureRandom.hex(SUBDOMAIN_LABEL_LIMIT - domain.length - 1))
|
|
|
|
# Slugify ensures the format and size (63 chars) of the given string
|
|
Gitlab::Utils.slugify(domain)
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :project_path, :namespace_path
|
|
end
|
|
end
|
|
end
|