internal_helpers.rb 3.78 KB
Newer Older
1 2 3
module API
  module Helpers
    module InternalHelpers
4 5
      attr_reader :redirected_path

6
      def wiki?
7 8
        set_project unless defined?(@wiki) # rubocop:disable Gitlab/ModuleWithInstanceVariables
        @wiki # rubocop:disable Gitlab/ModuleWithInstanceVariables
9 10 11
      end

      def project
12 13
        set_project unless defined?(@project) # rubocop:disable Gitlab/ModuleWithInstanceVariables
        @project # rubocop:disable Gitlab/ModuleWithInstanceVariables
14
      end
15

16 17 18 19 20 21 22
      def ssh_authentication_abilities
        [
          :read_project,
          :download_code,
          :push_code
        ]
      end
23

24 25
      def parse_env
        return {} if params[:env].blank?
26 27 28

        JSON.parse(params[:env])
      rescue JSON::ParserError
29
        {}
30
      end
31

32 33 34 35 36 37 38 39 40 41 42 43
      def fix_git_env_repository_paths(env, repository_path)
        if obj_dir_relative = env['GIT_OBJECT_DIRECTORY_RELATIVE'].presence
          env['GIT_OBJECT_DIRECTORY'] = File.join(repository_path, obj_dir_relative)
        end

        if alt_obj_dirs_relative = env['GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE'].presence
          env['GIT_ALTERNATE_OBJECT_DIRECTORIES'] = alt_obj_dirs_relative.map { |dir| File.join(repository_path, dir) }
        end

        env
      end

44
      def log_user_activity(actor)
45
        commands = Gitlab::GitAccess::DOWNLOAD_COMMANDS
46 47 48

        ::Users::ActivityService.new(actor, 'Git SSH').execute if commands.include?(params[:action])
      end
49

50 51 52 53
      def merge_request_urls
        ::MergeRequests::GetUrlsService.new(project).execute(params[:changes])
      end

54 55 56 57 58 59 60 61 62
      def redis_ping
        result = Gitlab::Redis::SharedState.with { |redis| redis.ping }

        result == 'PONG'
      rescue => e
        Rails.logger.warn("GitLab: An unexpected error occurred in pinging to Redis: #{e}")
        false
      end

63 64 65 66 67 68
      def project_path
        project&.path || project_path_match[:project_path]
      end

      def namespace_path
        project&.namespace&.full_path || project_path_match[:namespace_path]
Tiago Botelho's avatar
Tiago Botelho committed
69 70
      end

71 72
      private

73 74
      def project_path_match
        @project_path_match ||= params[:project].match(Gitlab::PathRegex.full_project_git_path_regex) || {}
75 76
      end

77
      # rubocop:disable Gitlab/ModuleWithInstanceVariables
78 79 80
      def set_project
        if params[:gl_repository]
          @project, @wiki = Gitlab::GlRepository.parse(params[:gl_repository])
81
          @redirected_path = nil
82
        else
83
          @project, @wiki, @redirected_path = Gitlab::RepoPath.parse(params[:project])
84 85
        end
      end
86
      # rubocop:enable Gitlab/ModuleWithInstanceVariables
87 88 89 90 91 92 93

      # Project id to pass between components that don't share/don't have
      # access to the same filesystem mounts
      def gl_repository
        Gitlab::GlRepository.gl_repository(project, wiki?)
      end

94 95 96
      # Return the repository depending on whether we want the wiki or the
      # regular repository
      def repository
97
        if wiki?
98
          project.wiki.repository
99
        else
100
          project.repository
101 102
        end
      end
103 104 105 106 107 108 109 110 111

      # Return the repository full path so that gitlab-shell has it when
      # handling ssh commands
      def repository_path
        repository.path_to_repo
      end

      # Return the Gitaly Address if it is enabled
      def gitaly_payload(action)
112 113 114 115 116 117 118 119
        return unless %w[git-receive-pack git-upload-pack].include?(action)

        if action == 'git-receive-pack'
          return unless Gitlab::GitalyClient.feature_enabled?(
            :ssh_receive_pack,
            status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT
          )
        end
120 121 122 123 124 125 126

        {
          repository: repository.gitaly_repository,
          address: Gitlab::GitalyClient.address(project.repository_storage),
          token: Gitlab::GitalyClient.token(project.repository_storage)
        }
      end
127 128 129
    end
  end
end