deploy_keys.rb 5.63 KB
Newer Older
1 2
# frozen_string_literal: true

3 4
module API
  class DeployKeys < Grape::API
5 6
    include PaginationParams

7
    before { authenticate! }
8

9 10 11 12 13
    helpers do
      def add_deploy_keys_project(project, attrs = {})
        project.deploy_keys_projects.create(attrs)
      end

14
      # rubocop: disable CodeReuse/ActiveRecord
15 16 17
      def find_by_deploy_key(project, key_id)
        project.deploy_keys_projects.find_by!(deploy_key: key_id)
      end
18
      # rubocop: enable CodeReuse/ActiveRecord
19 20
    end

21 22 23 24
    desc 'Return all deploy keys'
    params do
      use :pagination
    end
25 26 27
    get "deploy_keys" do
      authenticated_as_admin!

28
      present paginate(DeployKey.all), with: Entities::SSHKey
29
    end
30

31 32 33
    params do
      requires :id, type: String, desc: 'The ID of the project'
    end
34
    resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
35
      before { authorize_admin_project }
36

37
      desc "Get a specific project's deploy keys" do
38
        success Entities::DeployKeysProject
39
      end
40 41 42
      params do
        use :pagination
      end
43
      # rubocop: disable CodeReuse/ActiveRecord
44
      get ":id/deploy_keys" do
45 46 47
        keys = user_project.deploy_keys_projects.preload(:deploy_key)

        present paginate(keys), with: Entities::DeployKeysProject
48
      end
49
      # rubocop: enable CodeReuse/ActiveRecord
50

51
      desc 'Get single deploy key' do
52
        success Entities::DeployKeysProject
53 54 55 56 57
      end
      params do
        requires :key_id, type: Integer, desc: 'The ID of the deploy key'
      end
      get ":id/deploy_keys/:key_id" do
58 59 60
        key = find_by_deploy_key(user_project, params[:key_id])

        present key, with: Entities::DeployKeysProject
61 62
      end

63
      desc 'Add new deploy key to a project' do
64
        success Entities::DeployKeysProject
65 66 67 68
      end
      params do
        requires :key, type: String, desc: 'The new deploy key'
        requires :title, type: String, desc: 'The name of the deploy key'
69
        optional :can_push, type: Boolean, desc: "Can deploy key push to the project's repository"
70
      end
71
      # rubocop: disable CodeReuse/ActiveRecord
72 73 74 75
      post ":id/deploy_keys" do
        params[:key].strip!

        # Check for an existing key joined to this project
76
        deploy_key_project = user_project.deploy_keys_projects
77 78 79
                          .joins(:deploy_key)
                          .find_by(keys: { key: params[:key] })

80 81
        if deploy_key_project
          present deploy_key_project, with: Entities::DeployKeysProject
82
          break
83
        end
84

85 86 87
        # Check for available deploy keys in other projects
        key = current_user.accessible_deploy_keys.find_by(key: params[:key])
        if key
88
          deploy_key_project = add_deploy_keys_project(user_project, deploy_key: key, can_push: !!params[:can_push])
89

90
          present deploy_key_project, with: Entities::DeployKeysProject
91
          break
92
        end
93

94
        # Create a new deploy key
95 96
        deploy_key_attributes = declared_params.except(:can_push).merge(user: current_user)
        deploy_key_project = add_deploy_keys_project(user_project, deploy_key_attributes: deploy_key_attributes, can_push: !!params[:can_push])
97

98 99
        if deploy_key_project.valid?
          present deploy_key_project, with: Entities::DeployKeysProject
100
        else
101
          render_validation_error!(deploy_key_project)
102 103
        end
      end
104
      # rubocop: enable CodeReuse/ActiveRecord
105 106 107 108 109 110 111 112 113 114 115

      desc 'Update an existing deploy key for a project' do
        success Entities::SSHKey
      end
      params do
        requires :key_id, type: Integer, desc: 'The ID of the deploy key'
        optional :title, type: String, desc: 'The name of the deploy key'
        optional :can_push, type: Boolean, desc: "Can deploy key push to the project's repository"
        at_least_one_of :title, :can_push
      end
      put ":id/deploy_keys/:key_id" do
116
        deploy_keys_project = find_by_deploy_key(user_project, params[:key_id])
117

118
        authorize!(:update_deploy_key, deploy_keys_project.deploy_key)
119

120 121 122
        can_push = params[:can_push].nil? ? deploy_keys_project.can_push : params[:can_push]
        title = params[:title] || deploy_keys_project.deploy_key.title

Lin Jen-Shin's avatar
Lin Jen-Shin committed
123 124 125
        result = deploy_keys_project.update(can_push: can_push,
                                            deploy_key_attributes: { id: params[:key_id],
                                                                     title: title })
Oswaldo Ferreira's avatar
Oswaldo Ferreira committed
126

127 128
        if result
          present deploy_keys_project, with: Entities::DeployKeysProject
129
        else
130
          render_validation_error!(deploy_keys_project)
131
        end
132
      end
133

134 135 136 137 138 139 140 141 142 143
      desc 'Enable a deploy key for a project' do
        detail 'This feature was added in GitLab 8.11'
        success Entities::SSHKey
      end
      params do
        requires :key_id, type: Integer, desc: 'The ID of the deploy key'
      end
      post ":id/deploy_keys/:key_id/enable" do
        key = ::Projects::EnableDeployKeyService.new(user_project,
                                                      current_user, declared_params).execute
144

145 146 147 148
        if key
          present key, with: Entities::SSHKey
        else
          not_found!('Deploy Key')
149
        end
150
      end
151

152 153 154 155 156 157
      desc 'Delete deploy key for a project' do
        success Key
      end
      params do
        requires :key_id, type: Integer, desc: 'The ID of the deploy key'
      end
158
      # rubocop: disable CodeReuse/ActiveRecord
159
      delete ":id/deploy_keys/:key_id" do
160 161
        deploy_key_project = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id])
        not_found!('Deploy Key') unless deploy_key_project
162

163
        destroy_conditionally!(deploy_key_project)
164
      end
165
      # rubocop: enable CodeReuse/ActiveRecord
166 167 168
    end
  end
end