From c4b804c6dbf0183e0cec1cb95b7da743b21ff2c4 Mon Sep 17 00:00:00 2001
From: Krasimir Angelov <kangelov@gitlab.com>
Date: Wed, 4 Sep 2019 10:07:49 +1200
Subject: [PATCH] Rename API::Internal class to API::Internal::Base

so that we can use API::Internal namespace.

Related to https://gitlab.com/gitlab-org/gitlab-ce/issues/61927.
---
 .rubocop_todo.yml                             |   2 +-
 lib/api/api.rb                                |   2 +-
 lib/api/internal.rb                           | 294 -----------------
 lib/api/internal/base.rb                      | 296 ++++++++++++++++++
 .../base_spec.rb}                             |   2 +-
 5 files changed, 299 insertions(+), 297 deletions(-)
 delete mode 100644 lib/api/internal.rb
 create mode 100644 lib/api/internal/base.rb
 rename spec/requests/api/{internal_spec.rb => internal/base_spec.rb} (99%)

diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index be147d72f71..f1f8ff6e862 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -218,7 +218,7 @@ Lint/UriEscapeUnescape:
     - 'app/models/project_services/drone_ci_service.rb'
     - 'spec/lib/google_api/auth_spec.rb'
     - 'spec/requests/api/files_spec.rb'
-    - 'spec/requests/api/internal_spec.rb'
+    - 'spec/requests/api/internal/base_spec.rb'
 
 # Offense count: 1
 # Configuration parameters: CheckForMethodsWithNoSideEffects.
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 219ed45eff6..aa6a67d817a 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -118,7 +118,7 @@ module API
     mount ::API::GroupContainerRepositories
     mount ::API::GroupVariables
     mount ::API::ImportGithub
-    mount ::API::Internal
+    mount ::API::Internal::Base
     mount ::API::Issues
     mount ::API::JobArtifacts
     mount ::API::Jobs
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
deleted file mode 100644
index 088ea5bd79a..00000000000
--- a/lib/api/internal.rb
+++ /dev/null
@@ -1,294 +0,0 @@
-# frozen_string_literal: true
-
-module API
-  # Internal access API
-  class Internal < Grape::API
-    before { authenticate_by_gitlab_shell_token! }
-
-    helpers ::API::Helpers::InternalHelpers
-    helpers ::Gitlab::Identifier
-
-    UNKNOWN_CHECK_RESULT_ERROR = 'Unknown check result'.freeze
-
-    helpers do
-      def response_with_status(code: 200, success: true, message: nil, **extra_options)
-        status code
-        { status: success, message: message }.merge(extra_options).compact
-      end
-
-      def lfs_authentication_url(project)
-        # This is a separate method so that EE can alter its behaviour more
-        # easily.
-        project.http_url_to_repo
-      end
-    end
-
-    namespace 'internal' do
-      # Check if git command is allowed for project
-      #
-      # Params:
-      #   key_id - ssh key id for Git over SSH
-      #   user_id - user id for Git over HTTP or over SSH in keyless SSH CERT mode
-      #   username - user name for Git over SSH in keyless SSH cert mode
-      #   protocol - Git access protocol being used, e.g. HTTP or SSH
-      #   project - project full_path (not path on disk)
-      #   action - git action (git-upload-pack or git-receive-pack)
-      #   changes - changes as "oldrev newrev ref", see Gitlab::ChangesList
-      # rubocop: disable CodeReuse/ActiveRecord
-      post "/allowed" do
-        # Stores some Git-specific env thread-safely
-        env = parse_env
-        Gitlab::Git::HookEnv.set(gl_repository, env) if project
-
-        actor =
-          if params[:key_id]
-            Key.find_by(id: params[:key_id])
-          elsif params[:user_id]
-            User.find_by(id: params[:user_id])
-          elsif params[:username]
-            UserFinder.new(params[:username]).find_by_username
-          end
-
-        protocol = params[:protocol]
-
-        actor.update_last_used_at if actor.is_a?(Key)
-        user =
-          if actor.is_a?(Key)
-            actor.user
-          else
-            actor
-          end
-
-        access_checker_klass = repo_type.access_checker_class
-        access_checker = access_checker_klass.new(actor, project,
-          protocol, authentication_abilities: ssh_authentication_abilities,
-                    namespace_path: namespace_path, project_path: project_path,
-                    redirected_path: redirected_path)
-
-        check_result = begin
-                         result = access_checker.check(params[:action], params[:changes])
-                         @project ||= access_checker.project
-                         result
-                       rescue Gitlab::GitAccess::UnauthorizedError => e
-                         break response_with_status(code: 401, success: false, message: e.message)
-                       rescue Gitlab::GitAccess::TimeoutError => e
-                         break response_with_status(code: 503, success: false, message: e.message)
-                       rescue Gitlab::GitAccess::NotFoundError => e
-                         break response_with_status(code: 404, success: false, message: e.message)
-                       end
-
-        log_user_activity(actor)
-
-        case check_result
-        when ::Gitlab::GitAccessResult::Success
-          payload = {
-            gl_repository: gl_repository,
-            gl_project_path: gl_project_path,
-            gl_id: Gitlab::GlId.gl_id(user),
-            gl_username: user&.username,
-            git_config_options: [],
-            gitaly: gitaly_payload(params[:action]),
-            gl_console_messages: check_result.console_messages
-          }
-
-          # Custom option for git-receive-pack command
-          receive_max_input_size = Gitlab::CurrentSettings.receive_max_input_size.to_i
-          if receive_max_input_size > 0
-            payload[:git_config_options] << "receive.maxInputSize=#{receive_max_input_size.megabytes}"
-          end
-
-          response_with_status(**payload)
-        when ::Gitlab::GitAccessResult::CustomAction
-          response_with_status(code: 300, message: check_result.message, payload: check_result.payload)
-        else
-          response_with_status(code: 500, success: false, message: UNKNOWN_CHECK_RESULT_ERROR)
-        end
-      end
-      # rubocop: enable CodeReuse/ActiveRecord
-
-      # rubocop: disable CodeReuse/ActiveRecord
-      post "/lfs_authenticate" do
-        status 200
-
-        if params[:key_id]
-          actor = Key.find(params[:key_id])
-          actor.update_last_used_at
-        elsif params[:user_id]
-          actor = User.find_by(id: params[:user_id])
-          raise ActiveRecord::RecordNotFound.new("No such user id!") unless actor
-        else
-          raise ActiveRecord::RecordNotFound.new("No key_id or user_id passed!")
-        end
-
-        Gitlab::LfsToken
-          .new(actor)
-          .authentication_payload(lfs_authentication_url(project))
-      end
-      # rubocop: enable CodeReuse/ActiveRecord
-
-      get "/merge_request_urls" do
-        merge_request_urls
-      end
-
-      #
-      # Get a ssh key using the fingerprint
-      #
-      # rubocop: disable CodeReuse/ActiveRecord
-      get "/authorized_keys" do
-        fingerprint = params.fetch(:fingerprint) do
-          Gitlab::InsecureKeyFingerprint.new(params.fetch(:key)).fingerprint
-        end
-        key = Key.find_by(fingerprint: fingerprint)
-        not_found!("Key") if key.nil?
-        present key, with: Entities::SSHKey
-      end
-      # rubocop: enable CodeReuse/ActiveRecord
-
-      #
-      # Discover user by ssh key, user id or username
-      #
-      # rubocop: disable CodeReuse/ActiveRecord
-      get "/discover" do
-        if params[:key_id]
-          key = Key.find(params[:key_id])
-          user = key.user
-        elsif params[:user_id]
-          user = User.find_by(id: params[:user_id])
-        elsif params[:username]
-          user = UserFinder.new(params[:username]).find_by_username
-        end
-
-        present user, with: Entities::UserSafe
-      end
-      # rubocop: enable CodeReuse/ActiveRecord
-
-      get "/check" do
-        {
-          api_version: API.version,
-          gitlab_version: Gitlab::VERSION,
-          gitlab_rev: Gitlab.revision,
-          redis: redis_ping
-        }
-      end
-
-      get "/broadcast_messages" do
-        if messages = BroadcastMessage.current
-          present messages, with: Entities::BroadcastMessage
-        else
-          []
-        end
-      end
-
-      get "/broadcast_message" do
-        if message = BroadcastMessage.current&.last
-          present message, with: Entities::BroadcastMessage
-        else
-          {}
-        end
-      end
-
-      # rubocop: disable CodeReuse/ActiveRecord
-      post '/two_factor_recovery_codes' do
-        status 200
-
-        if params[:key_id]
-          key = Key.find_by(id: params[:key_id])
-
-          if key
-            key.update_last_used_at
-          else
-            break { 'success' => false, 'message' => 'Could not find the given key' }
-          end
-
-          if key.is_a?(DeployKey)
-            break { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' }
-          end
-
-          user = key.user
-
-          unless user
-            break { success: false, message: 'Could not find a user for the given key' }
-          end
-        elsif params[:user_id]
-          user = User.find_by(id: params[:user_id])
-
-          unless user
-            break { success: false, message: 'Could not find the given user' }
-          end
-        end
-
-        unless user.two_factor_enabled?
-          break { success: false, message: 'Two-factor authentication is not enabled for this user' }
-        end
-
-        codes = nil
-
-        ::Users::UpdateService.new(current_user, user: user).execute! do |user|
-          codes = user.generate_otp_backup_codes!
-        end
-
-        { success: true, recovery_codes: codes }
-      end
-      # rubocop: enable CodeReuse/ActiveRecord
-
-      post '/pre_receive' do
-        status 200
-
-        reference_counter_increased = Gitlab::ReferenceCounter.new(params[:gl_repository]).increase
-
-        { reference_counter_increased: reference_counter_increased }
-      end
-
-      post "/notify_post_receive" do
-        status 200
-
-        # TODO: Re-enable when Gitaly is processing the post-receive notification
-        # return unless Gitlab::GitalyClient.enabled?
-        #
-        # begin
-        #   repository = wiki? ? project.wiki.repository : project.repository
-        #   Gitlab::GitalyClient::NotificationService.new(repository.raw_repository).post_receive
-        # rescue GRPC::Unavailable => e
-        #   render_api_error!(e, 500)
-        # end
-      end
-
-      post '/post_receive' do
-        status 200
-
-        response = Gitlab::InternalPostReceive::Response.new
-        user = identify(params[:identifier])
-        project = Gitlab::GlRepository.parse(params[:gl_repository]).first
-        push_options = Gitlab::PushOptions.new(params[:push_options])
-
-        response.reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease
-
-        PostReceive.perform_async(params[:gl_repository], params[:identifier],
-          params[:changes], push_options.as_json)
-
-        mr_options = push_options.get(:merge_request)
-        if mr_options.present?
-          message = process_mr_push_options(mr_options, project, user, params[:changes])
-          response.add_alert_message(message)
-        end
-
-        broadcast_message = BroadcastMessage.current&.last&.message
-        response.add_alert_message(broadcast_message)
-
-        response.add_merge_request_urls(merge_request_urls)
-
-        # A user is not guaranteed to be returned; an orphaned write deploy
-        # key could be used
-        if user
-          redirect_message = Gitlab::Checks::ProjectMoved.fetch_message(user.id, project.id)
-          project_created_message = Gitlab::Checks::ProjectCreated.fetch_message(user.id, project.id)
-
-          response.add_basic_message(redirect_message)
-          response.add_basic_message(project_created_message)
-        end
-
-        present response, with: Entities::InternalPostReceive::Response
-      end
-    end
-  end
-end
diff --git a/lib/api/internal/base.rb b/lib/api/internal/base.rb
new file mode 100644
index 00000000000..622032b8355
--- /dev/null
+++ b/lib/api/internal/base.rb
@@ -0,0 +1,296 @@
+# frozen_string_literal: true
+
+module API
+  # Internal access API
+  module Internal
+    class Base < Grape::API
+      before { authenticate_by_gitlab_shell_token! }
+
+      helpers ::API::Helpers::InternalHelpers
+      helpers ::Gitlab::Identifier
+
+      UNKNOWN_CHECK_RESULT_ERROR = 'Unknown check result'.freeze
+
+      helpers do
+        def response_with_status(code: 200, success: true, message: nil, **extra_options)
+          status code
+          { status: success, message: message }.merge(extra_options).compact
+        end
+
+        def lfs_authentication_url(project)
+          # This is a separate method so that EE can alter its behaviour more
+          # easily.
+          project.http_url_to_repo
+        end
+      end
+
+      namespace 'internal' do
+        # Check if git command is allowed for project
+        #
+        # Params:
+        #   key_id - ssh key id for Git over SSH
+        #   user_id - user id for Git over HTTP or over SSH in keyless SSH CERT mode
+        #   username - user name for Git over SSH in keyless SSH cert mode
+        #   protocol - Git access protocol being used, e.g. HTTP or SSH
+        #   project - project full_path (not path on disk)
+        #   action - git action (git-upload-pack or git-receive-pack)
+        #   changes - changes as "oldrev newrev ref", see Gitlab::ChangesList
+        # rubocop: disable CodeReuse/ActiveRecord
+        post "/allowed" do
+          # Stores some Git-specific env thread-safely
+          env = parse_env
+          Gitlab::Git::HookEnv.set(gl_repository, env) if project
+
+          actor =
+            if params[:key_id]
+              Key.find_by(id: params[:key_id])
+            elsif params[:user_id]
+              User.find_by(id: params[:user_id])
+            elsif params[:username]
+              UserFinder.new(params[:username]).find_by_username
+            end
+
+          protocol = params[:protocol]
+
+          actor.update_last_used_at if actor.is_a?(Key)
+          user =
+            if actor.is_a?(Key)
+              actor.user
+            else
+              actor
+            end
+
+          access_checker_klass = repo_type.access_checker_class
+          access_checker = access_checker_klass.new(actor, project,
+                                                    protocol, authentication_abilities: ssh_authentication_abilities,
+                                                    namespace_path: namespace_path, project_path: project_path,
+                                                    redirected_path: redirected_path)
+
+          check_result = begin
+                           result = access_checker.check(params[:action], params[:changes])
+                           @project ||= access_checker.project
+                           result
+                         rescue Gitlab::GitAccess::UnauthorizedError => e
+                           break response_with_status(code: 401, success: false, message: e.message)
+                         rescue Gitlab::GitAccess::TimeoutError => e
+                           break response_with_status(code: 503, success: false, message: e.message)
+                         rescue Gitlab::GitAccess::NotFoundError => e
+                           break response_with_status(code: 404, success: false, message: e.message)
+                         end
+
+          log_user_activity(actor)
+
+          case check_result
+          when ::Gitlab::GitAccessResult::Success
+            payload = {
+              gl_repository: gl_repository,
+              gl_project_path: gl_project_path,
+              gl_id: Gitlab::GlId.gl_id(user),
+              gl_username: user&.username,
+              git_config_options: [],
+              gitaly: gitaly_payload(params[:action]),
+              gl_console_messages: check_result.console_messages
+            }
+
+            # Custom option for git-receive-pack command
+            receive_max_input_size = Gitlab::CurrentSettings.receive_max_input_size.to_i
+            if receive_max_input_size > 0
+              payload[:git_config_options] << "receive.maxInputSize=#{receive_max_input_size.megabytes}"
+            end
+
+            response_with_status(**payload)
+          when ::Gitlab::GitAccessResult::CustomAction
+            response_with_status(code: 300, message: check_result.message, payload: check_result.payload)
+          else
+            response_with_status(code: 500, success: false, message: UNKNOWN_CHECK_RESULT_ERROR)
+          end
+        end
+        # rubocop: enable CodeReuse/ActiveRecord
+
+        # rubocop: disable CodeReuse/ActiveRecord
+        post "/lfs_authenticate" do
+          status 200
+
+          if params[:key_id]
+            actor = Key.find(params[:key_id])
+            actor.update_last_used_at
+          elsif params[:user_id]
+            actor = User.find_by(id: params[:user_id])
+            raise ActiveRecord::RecordNotFound.new("No such user id!") unless actor
+          else
+            raise ActiveRecord::RecordNotFound.new("No key_id or user_id passed!")
+          end
+
+          Gitlab::LfsToken
+            .new(actor)
+            .authentication_payload(lfs_authentication_url(project))
+        end
+        # rubocop: enable CodeReuse/ActiveRecord
+
+        get "/merge_request_urls" do
+          merge_request_urls
+        end
+
+        #
+        # Get a ssh key using the fingerprint
+        #
+        # rubocop: disable CodeReuse/ActiveRecord
+        get "/authorized_keys" do
+          fingerprint = params.fetch(:fingerprint) do
+            Gitlab::InsecureKeyFingerprint.new(params.fetch(:key)).fingerprint
+          end
+          key = Key.find_by(fingerprint: fingerprint)
+          not_found!("Key") if key.nil?
+          present key, with: Entities::SSHKey
+        end
+        # rubocop: enable CodeReuse/ActiveRecord
+
+        #
+        # Discover user by ssh key, user id or username
+        #
+        # rubocop: disable CodeReuse/ActiveRecord
+        get "/discover" do
+          if params[:key_id]
+            key = Key.find(params[:key_id])
+            user = key.user
+          elsif params[:user_id]
+            user = User.find_by(id: params[:user_id])
+          elsif params[:username]
+            user = UserFinder.new(params[:username]).find_by_username
+          end
+
+          present user, with: Entities::UserSafe
+        end
+        # rubocop: enable CodeReuse/ActiveRecord
+
+        get "/check" do
+          {
+            api_version: API.version,
+            gitlab_version: Gitlab::VERSION,
+            gitlab_rev: Gitlab.revision,
+            redis: redis_ping
+          }
+        end
+
+        get "/broadcast_messages" do
+          if messages = BroadcastMessage.current
+            present messages, with: Entities::BroadcastMessage
+          else
+            []
+          end
+        end
+
+        get "/broadcast_message" do
+          if message = BroadcastMessage.current&.last
+            present message, with: Entities::BroadcastMessage
+          else
+            {}
+          end
+        end
+
+        # rubocop: disable CodeReuse/ActiveRecord
+        post '/two_factor_recovery_codes' do
+          status 200
+
+          if params[:key_id]
+            key = Key.find_by(id: params[:key_id])
+
+            if key
+              key.update_last_used_at
+            else
+              break { 'success' => false, 'message' => 'Could not find the given key' }
+            end
+
+            if key.is_a?(DeployKey)
+              break { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' }
+            end
+
+            user = key.user
+
+            unless user
+              break { success: false, message: 'Could not find a user for the given key' }
+            end
+          elsif params[:user_id]
+            user = User.find_by(id: params[:user_id])
+
+            unless user
+              break { success: false, message: 'Could not find the given user' }
+            end
+          end
+
+          unless user.two_factor_enabled?
+            break { success: false, message: 'Two-factor authentication is not enabled for this user' }
+          end
+
+          codes = nil
+
+          ::Users::UpdateService.new(current_user, user: user).execute! do |user|
+            codes = user.generate_otp_backup_codes!
+          end
+
+          { success: true, recovery_codes: codes }
+        end
+        # rubocop: enable CodeReuse/ActiveRecord
+
+        post '/pre_receive' do
+          status 200
+
+          reference_counter_increased = Gitlab::ReferenceCounter.new(params[:gl_repository]).increase
+
+          { reference_counter_increased: reference_counter_increased }
+        end
+
+        post "/notify_post_receive" do
+          status 200
+
+          # TODO: Re-enable when Gitaly is processing the post-receive notification
+          # return unless Gitlab::GitalyClient.enabled?
+          #
+          # begin
+          #   repository = wiki? ? project.wiki.repository : project.repository
+          #   Gitlab::GitalyClient::NotificationService.new(repository.raw_repository).post_receive
+          # rescue GRPC::Unavailable => e
+          #   render_api_error!(e, 500)
+          # end
+        end
+
+        post '/post_receive' do
+          status 200
+
+          response = Gitlab::InternalPostReceive::Response.new
+          user = identify(params[:identifier])
+          project = Gitlab::GlRepository.parse(params[:gl_repository]).first
+          push_options = Gitlab::PushOptions.new(params[:push_options])
+
+          response.reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease
+
+          PostReceive.perform_async(params[:gl_repository], params[:identifier],
+                                    params[:changes], push_options.as_json)
+
+          mr_options = push_options.get(:merge_request)
+          if mr_options.present?
+            message = process_mr_push_options(mr_options, project, user, params[:changes])
+            response.add_alert_message(message)
+          end
+
+          broadcast_message = BroadcastMessage.current&.last&.message
+          response.add_alert_message(broadcast_message)
+
+          response.add_merge_request_urls(merge_request_urls)
+
+          # A user is not guaranteed to be returned; an orphaned write deploy
+          # key could be used
+          if user
+            redirect_message = Gitlab::Checks::ProjectMoved.fetch_message(user.id, project.id)
+            project_created_message = Gitlab::Checks::ProjectCreated.fetch_message(user.id, project.id)
+
+            response.add_basic_message(redirect_message)
+            response.add_basic_message(project_created_message)
+          end
+
+          present response, with: Entities::InternalPostReceive::Response
+        end
+      end
+    end
+  end
+end
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal/base_spec.rb
similarity index 99%
rename from spec/requests/api/internal_spec.rb
rename to spec/requests/api/internal/base_spec.rb
index c94f6d22e74..a56527073c7 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal/base_spec.rb
@@ -1,6 +1,6 @@
 require 'spec_helper'
 
-describe API::Internal do
+describe API::Internal::Base do
   set(:user) { create(:user) }
   let(:key) { create(:key, user: user) }
   set(:project) { create(:project, :repository, :wiki_repo) }
-- 
2.30.9