Skip to content
Snippets Groups Projects
Commit edc4a56d authored by Douwe Maan's avatar Douwe Maan
Browse files

Allow admin to create public deploy keys that are accessible to any project.

parent 9157985c
No related branches found
No related tags found
1 merge request!469Allow admin to create public deploy keys that are accessible to any project.
Showing
with 233 additions and 36 deletions
Loading
Loading
@@ -58,6 +58,7 @@ v 7.10.0 (unreleased)
- Fix "Hello @username." references not working by no longer allowing usernames to end in period.
- Archive repositories in background worker.
- Import GitHub, Bitbucket or GitLab.com projects owned by authenticated user into current namespace.
- Allow admin to create public deploy keys that are accessible to any project.
 
 
v 7.9.2
Loading
Loading
class Admin::DeployKeysController < Admin::ApplicationController
before_filter :deploy_key, only: [:show, :destroy]
def index
@deploy_keys = DeployKey.are_public
end
def show
end
def new
@deploy_key = DeployKey.new(public: true)
end
def create
@deploy_key = DeployKey.new(deploy_key_params)
@deploy_key.public = true
if @deploy_key.save
redirect_to admin_deploy_keys_path
else
render "new"
end
end
def destroy
deploy_key.destroy
respond_to do |format|
format.html { redirect_to admin_deploy_keys_path }
format.json { head :ok }
end
end
protected
def deploy_key
@deploy_key ||= DeployKey.find(params[:id])
end
def deploy_key_params
params.require(:deploy_key).permit(:key, :title)
end
end
Loading
Loading
@@ -9,6 +9,8 @@ class Projects::DeployKeysController < Projects::ApplicationController
def index
@enabled_keys = @project.deploy_keys
@available_keys = available_keys - @enabled_keys
@available_project_keys = current_user.project_deploy_keys - @enabled_keys
@available_public_keys = DeployKey.are_public - @available_project_keys - @enabled_keys
end
 
def show
Loading
Loading
@@ -32,18 +34,9 @@ class Projects::DeployKeysController < Projects::ApplicationController
end
end
 
def destroy
@key = @project.deploy_keys.find(params[:id])
@key.destroy
respond_to do |format|
format.html { redirect_to namespace_project_deploy_keys_path(@project.namespace, @project) }
format.js { render nothing: true }
end
end
def enable
@project.deploy_keys << available_keys.find(params[:id])
@key = current_user.accessible_deploy_keys.find(params[:id])
@project.deploy_keys << @key
 
redirect_to namespace_project_deploy_keys_path(@project.namespace,
@project)
Loading
Loading
@@ -52,8 +45,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
def disable
@project.deploy_keys_projects.find_by(deploy_key_id: params[:id]).destroy
 
redirect_to namespace_project_deploy_keys_path(@project.namespace,
@project)
redirect_to :back
end
 
protected
Loading
Loading
Loading
Loading
@@ -7,6 +7,7 @@
# created_at :datetime
# updated_at :datetime
# key :text
# public :boolean default(FALSE)
# title :string(255)
# type :string(255)
# fingerprint :string(255)
Loading
Loading
@@ -17,4 +18,10 @@ class DeployKey < Key
has_many :projects, through: :deploy_keys_projects
 
scope :in_projects, ->(projects) { joins(:deploy_keys_projects).where('deploy_keys_projects.project_id in (?)', projects) }
scope :are_public, -> { where(public: true) }
scope :are_private, -> { where(public: false) }
def private?
!public?
end
end
Loading
Loading
@@ -22,6 +22,10 @@ class DeployKeysProject < ActiveRecord::Base
private
 
def destroy_orphaned_deploy_key
self.deploy_key.destroy if self.deploy_key.deploy_keys_projects.length == 0
# Public deploy keys are never automatically deleted
return if self.deploy_key.public?
return if self.deploy_key.deploy_keys_projects.length > 0
self.deploy_key.destroy
end
end
Loading
Loading
@@ -414,8 +414,16 @@ class User < ActiveRecord::Base
@ldap_identity ||= identities.find_by(["provider LIKE ?", "ldap%"])
end
 
def project_deploy_keys
DeployKey.in_projects(self.authorized_projects.pluck(:id))
end
def accessible_deploy_keys
DeployKey.in_projects(self.authorized_projects.pluck(:id)).uniq
@accessible_deploy_keys ||= begin
key_ids = project_deploy_keys.pluck(:id)
key_ids.push(*DeployKey.are_public.pluck(:id))
DeployKey.where(id: key_ids)
end
end
 
def created_by
Loading
Loading
.panel.panel-default
.panel-heading
Public deploy keys (#{@deploy_keys.count})
.panel-head-actions
= link_to 'New Deploy Key', new_admin_deploy_key_path, class: "btn btn-new btn-sm"
- if @deploy_keys.any?
%table.table
%thead.panel-heading
%tr
%th Title
%th Fingerprint
%th Added at
%th
%tbody
- @deploy_keys.each do |deploy_key|
%tr
%td
= link_to admin_deploy_key_path(deploy_key) do
%strong= deploy_key.title
%td
%span
(#{deploy_key.fingerprint})
%td
%span.cgray
added #{time_ago_with_tooltip(deploy_key.created_at)}
%td
= link_to 'Remove', admin_deploy_key_path(deploy_key), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-sm btn-remove delete-key pull-right"
%h3.page-title New public deploy key
%hr
%div
= form_for [:admin, @deploy_key], html: { class: 'deploy-key-form form-horizontal' } do |f|
-if @deploy_key.errors.any?
.alert.alert-danger
%ul
- @deploy_key.errors.full_messages.each do |msg|
%li= msg
.form-group
= f.label :title, class: "control-label"
.col-sm-10= f.text_field :title, class: 'form-control'
.form-group
= f.label :key, class: "control-label"
.col-sm-10
%p.light
Paste a machine public key here. Read more about how to generate it
= link_to "here", help_page_path("ssh", "README")
= f.text_area :key, class: "form-control thin_area", rows: 5
.form-actions
= f.submit 'Create', class: "btn-create btn"
= link_to "Cancel", admin_deploy_keys_path, class: "btn btn-cancel"
.row
.col-md-4
.panel.panel-default
.panel-heading
Deploy Key
%ul.well-list
%li
%span.light Title:
%strong= @deploy_key.title
%li
%span.light Created on:
%strong= @deploy_key.created_at.stamp("Aug 21, 2011")
.panel.panel-default
.panel-heading Projects (#{@deploy_key.deploy_keys_projects.count})
- if @deploy_key.deploy_keys_projects.any?
%ul.well-list
- @deploy_key.projects.each do |project|
%li
%span
%strong
= link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project]
.pull-right
= link_to disable_namespace_project_deploy_key_path(project.namespace, project, @deploy_key), data: { confirm: "Are you sure?" }, method: :put, class: "btn-xs btn btn-remove", title: 'Remove deploy key from project' do
%i.fa.fa-times.fa-inverse
.col-md-8
%p
%span.light Fingerprint:
%strong= @deploy_key.fingerprint
%pre.well-pre
= @deploy_key.key
.pull-right
= link_to 'Remove', admin_deploy_key_path(@deploy_key), data: {confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove delete-key"
Loading
Loading
@@ -19,6 +19,11 @@
%i.fa.fa-group
%span
Groups
= nav_link(controller: :deploy_keys) do
= link_to admin_deploy_keys_path, title: 'Deploy Keys' do
%i.fa.fa-key
%span
Deploy Keys
= nav_link(controller: :logs) do
= link_to admin_logs_path, title: 'Logs' do
%i.fa.fa-file-text
Loading
Loading
Loading
Loading
@@ -5,21 +5,38 @@
%i.fa.fa-plus
Enable
- else
- if deploy_key.projects.count > 1
- if deploy_key.projects.count > 1 || deploy_key.public?
= link_to disable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-sm', method: :put do
%i.fa.fa-power-off
Disable
- else
= link_to 'Remove', namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), data: { confirm: 'You are going to remove deploy key. Are you sure?'}, method: :delete, class: "btn btn-remove delete-key btn-sm pull-right"
= link_to 'Remove', disable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), data: { confirm: 'You are going to remove deploy key. Are you sure?'}, method: :put, class: "btn btn-remove delete-key btn-sm pull-right"
 
 
- key_project = deploy_key.projects.include?(@project) ? @project : deploy_key.projects.first
= link_to namespace_project_deploy_key_path(key_project.namespace, key_project, deploy_key) do
- if deploy_key.projects.include?(@project)
- key_project = @project
- else
- key_project = deploy_key.projects.find { |project| can?(current_user, :read_project, project) }
- if key_project
= link_to namespace_project_deploy_key_path(key_project.namespace, key_project, deploy_key) do
%i.fa.fa-key
%strong= deploy_key.title
- else
%i.fa.fa-key
%strong= deploy_key.title
 
%p.light.prepend-top-10
- deploy_key.projects.map(&:name_with_namespace).each do |project_name|
%span.label.label-gray.deploy-project-label= project_name
- if deploy_key.public?
%span.label.label-info.deploy-project-label
Public deploy key
- deploy_key.projects.each do |project|
- if can?(current_user, :read_project, project)
%span.label.label-gray.deploy-project-label
= link_to namespace_project_path(project.namespace, project) do
= project.name_with_namespace
%small.pull-right
Created #{time_ago_with_tooltip(deploy_key.created_at)}
Loading
Loading
@@ -22,11 +22,19 @@
.light-well
.nothing-here-block Create a #{link_to 'new deploy key', new_namespace_project_deploy_key_path(@project.namespace, @project)} or add an existing one
.col-md-6.available-keys
%h5
%strong Deploy keys
from projects available to you
%ul.bordered-list
= render @available_keys
- if @available_keys.blank?
.light-well
.nothing-here-block Deploy keys from projects you have access to will be displayed here
- unless @available_project_keys.blank? && @available_public_keys.any?
%h5
%strong Deploy keys
from projects you have access to
%ul.bordered-list
= render @available_project_keys
- if @available_project_keys.blank?
.light-well
.nothing-here-block Deploy keys from projects you have access to will be displayed here
- if @available_public_keys.any?
%h5
%strong Public deploy keys
available to any project
%ul.bordered-list
= render @available_public_keys
Loading
Loading
@@ -145,6 +145,8 @@ Gitlab::Application.routes.draw do
end
end
 
resources :deploy_keys, only: [:index, :show, :new, :create, :destroy]
resources :hooks, only: [:index, :create, :destroy] do
get :test
end
Loading
Loading
@@ -393,7 +395,7 @@ Gitlab::Application.routes.draw do
end
end
 
resources :deploy_keys, constraints: { id: /\d+/ } do
resources :deploy_keys, constraints: { id: /\d+/ }, only: [:index, :show, :new, :create] do
member do
put :enable
put :disable
Loading
Loading
class AddPublicToKey < ActiveRecord::Migration
def change
add_column :keys, :public, :boolean, default: false, null: false
end
end
Loading
Loading
@@ -132,6 +132,7 @@ ActiveRecord::Schema.define(version: 20150328132231) do
t.string "title"
t.string "type"
t.string "fingerprint"
t.boolean "public", default: false, null: false
end
 
add_index "keys", ["created_at", "id"], name: "index_keys_on_created_at_and_id", using: :btree
Loading
Loading
Loading
Loading
@@ -28,17 +28,32 @@ describe DeployKeysProject do
let(:deploy_key) { subject.deploy_key }
 
context "when the deploy key is only used by this project" do
it "destroys the deploy key" do
subject.destroy
context "when the deploy key is public" do
before do
deploy_key.update_attribute(:public, true)
end
 
expect {
deploy_key.reload
}.to raise_error(ActiveRecord::RecordNotFound)
it "doesn't destroy the deploy key" do
subject.destroy
expect {
deploy_key.reload
}.not_to raise_error(ActiveRecord::RecordNotFound)
end
end
context "when the deploy key is private" do
it "destroys the deploy key" do
subject.destroy
expect {
deploy_key.reload
}.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
 
context "when the deploy key is used by more than one project" do
let!(:other_project) { create(:project) }
 
before do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment