summaryrefslogtreecommitdiff
path: root/lib/api/v3/runners.rb
blob: faa265f3314c3ccf51d09718d026812487af0b15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module API
  module V3
    class Runners < Grape::API
      include PaginationParams

      before { authenticate! }

      resource :runners do
        desc 'Remove a runner' do
          success ::API::Entities::Runner
        end
        params do
          requires :id, type: Integer, desc: 'The ID of the runner'
        end
        delete ':id' do
          runner = Ci::Runner.find(params[:id])
          not_found!('Runner') unless runner

          authenticate_delete_runner!(runner)

          status(200)
          runner.destroy
        end
      end

      params do
        requires :id, type: String, desc: 'The ID of a project'
      end
      resource :projects, requirements: { id: %r{[^/]+} } do
        before { authorize_admin_project }

        desc "Disable project's runner" do
          success ::API::Entities::Runner
        end
        params do
          requires :runner_id, type: Integer, desc: 'The ID of the runner'
        end
        delete ':id/runners/:runner_id' do
          runner_project = user_project.runner_projects.find_by(runner_id: params[:runner_id])
          not_found!('Runner') unless runner_project

          runner = runner_project.runner
          forbidden!("Only one project associated with the runner. Please remove the runner instead") if runner.projects.count == 1

          runner_project.destroy

          present runner, with: ::API::Entities::Runner
        end
      end

      helpers do
        def authenticate_delete_runner!(runner)
          return if current_user.admin?
          forbidden!("Runner is shared") if runner.is_shared?
          forbidden!("Runner associated with more than one project") if runner.projects.count > 1
          forbidden!("No access granted") unless user_can_access_runner?(runner)
        end

        def user_can_access_runner?(runner)
          current_user.ci_authorized_runners.exists?(runner.id)
        end
      end
    end
  end
end