Feature: Deploy keys between projects
This commit is contained in:
parent
8e4625af61
commit
1882baa1aa
13 changed files with 86 additions and 105 deletions
|
@ -5,7 +5,8 @@ class DeployKeysController < ProjectResourceController
|
||||||
before_filter :authorize_admin_project!
|
before_filter :authorize_admin_project!
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@keys = @project.deploy_keys.all
|
@enabled_keys = @project.deploy_keys.all
|
||||||
|
@available_keys = available_keys - @enabled_keys
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -19,8 +20,9 @@ class DeployKeysController < ProjectResourceController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@key = @project.deploy_keys.new(params[:key])
|
@key = DeployKey.new(params[:deploy_key])
|
||||||
if @key.save
|
|
||||||
|
if @key.valid? && @project.deploy_keys << @key
|
||||||
redirect_to project_deploy_keys_path(@project)
|
redirect_to project_deploy_keys_path(@project)
|
||||||
else
|
else
|
||||||
render "new"
|
render "new"
|
||||||
|
@ -36,4 +38,22 @@ class DeployKeysController < ProjectResourceController
|
||||||
format.js { render nothing: true }
|
format.js { render nothing: true }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enable
|
||||||
|
project.deploy_keys << available_keys.find(params[:id])
|
||||||
|
|
||||||
|
redirect_to project_deploy_keys_path(@project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable
|
||||||
|
@project.deploy_keys_projects.where(deploy_key_id: params[:id]).last.destroy
|
||||||
|
|
||||||
|
redirect_to project_deploy_keys_path(@project)
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def available_keys
|
||||||
|
@available_keys ||= DeployKey.in_projects(current_user.owned_projects)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class DeployKey < Key
|
class DeployKey < Key
|
||||||
has_many :deploy_keys_projects, dependent: :destroy
|
has_many :deploy_keys_projects, dependent: :destroy
|
||||||
has_many :projects, through: :deploy_keys_projects
|
has_many :projects, through: :deploy_keys_projects
|
||||||
|
|
||||||
|
scope :in_projects, ->(projects) { joins(:deploy_keys_projects).where('deploy_keys_projects.project_id in (?)', projects) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,10 +46,6 @@ class Key < ActiveRecord::Base
|
||||||
errors.add(:key, "can't be fingerprinted") if $?.exitstatus != 0
|
errors.add(:key, "can't be fingerprinted") if $?.exitstatus != 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_deploy_key
|
|
||||||
project.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
# projects that has this key
|
# projects that has this key
|
||||||
def projects
|
def projects
|
||||||
user.authorized_projects
|
user.authorized_projects
|
||||||
|
|
|
@ -55,7 +55,6 @@ class Project < ActiveRecord::Base
|
||||||
has_many :users_projects, dependent: :destroy
|
has_many :users_projects, dependent: :destroy
|
||||||
has_many :notes, dependent: :destroy
|
has_many :notes, dependent: :destroy
|
||||||
has_many :snippets, dependent: :destroy
|
has_many :snippets, dependent: :destroy
|
||||||
has_many :deploy_keys, dependent: :destroy, class_name: "Key", foreign_key: "project_id"
|
|
||||||
has_many :hooks, dependent: :destroy, class_name: "ProjectHook"
|
has_many :hooks, dependent: :destroy, class_name: "ProjectHook"
|
||||||
has_many :protected_branches, dependent: :destroy
|
has_many :protected_branches, dependent: :destroy
|
||||||
has_many :user_team_project_relationships, dependent: :destroy
|
has_many :user_team_project_relationships, dependent: :destroy
|
||||||
|
@ -65,6 +64,9 @@ class Project < ActiveRecord::Base
|
||||||
has_many :user_team_user_relationships, through: :user_teams
|
has_many :user_team_user_relationships, through: :user_teams
|
||||||
has_many :user_teams_members, through: :user_team_user_relationships
|
has_many :user_teams_members, through: :user_team_user_relationships
|
||||||
|
|
||||||
|
has_many :deploy_keys_projects, dependent: :destroy
|
||||||
|
has_many :deploy_keys, through: :deploy_keys_projects
|
||||||
|
|
||||||
delegate :name, to: :owner, allow_nil: true, prefix: true
|
delegate :name, to: :owner, allow_nil: true, prefix: true
|
||||||
|
|
||||||
# Validations
|
# Validations
|
||||||
|
|
|
@ -89,7 +89,7 @@ class User < ActiveRecord::Base
|
||||||
|
|
||||||
has_many :personal_projects, through: :namespace, source: :projects
|
has_many :personal_projects, through: :namespace, source: :projects
|
||||||
has_many :projects, through: :users_projects
|
has_many :projects, through: :users_projects
|
||||||
has_many :own_projects, foreign_key: :creator_id
|
has_many :own_projects, foreign_key: :creator_id, class_name: 'Project'
|
||||||
has_many :owned_projects, through: :namespaces, source: :projects
|
has_many :owned_projects, through: :namespaces, source: :projects
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
25
app/views/deploy_keys/_deploy_key.html.haml
Normal file
25
app/views/deploy_keys/_deploy_key.html.haml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
%li
|
||||||
|
.pull-right
|
||||||
|
- if @available_keys.include?(deploy_key)
|
||||||
|
= link_to enable_project_deploy_key_path(@project, deploy_key), class: 'btn btn-small', method: :put do
|
||||||
|
%i.icon-plus
|
||||||
|
Enable
|
||||||
|
- else
|
||||||
|
- if deploy_key.projects.count > 1
|
||||||
|
= link_to disable_project_deploy_key_path(@project, deploy_key), class: 'btn btn-small', method: :put do
|
||||||
|
%i.icon-off
|
||||||
|
Disable
|
||||||
|
- else
|
||||||
|
= link_to 'Remove', project_deploy_key_path(@project, deploy_key), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove delete-key btn-small pull-right"
|
||||||
|
|
||||||
|
|
||||||
|
= link_to project_deploy_key_path(@project, deploy_key) do
|
||||||
|
%i.icon-key
|
||||||
|
%strong= deploy_key.title
|
||||||
|
|
||||||
|
%p.light.prepend-top-10
|
||||||
|
- deploy_key.projects.map(&:name_with_namespace).each do |project_name|
|
||||||
|
%span.label= project_name
|
||||||
|
%small.pull-right
|
||||||
|
Created #{time_ago_in_words(deploy_key.created_at)} ago
|
||||||
|
|
|
@ -18,6 +18,6 @@
|
||||||
= link_to "here", help_ssh_path
|
= link_to "here", help_ssh_path
|
||||||
|
|
||||||
.actions
|
.actions
|
||||||
= f.submit 'Save', class: "btn-save btn"
|
= f.submit 'Create', class: "btn-create btn"
|
||||||
= link_to "Cancel", project_deploy_keys_path(@project), class: "btn btn-cancel"
|
= link_to "Cancel", project_deploy_keys_path(@project), class: "btn btn-cancel"
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
%tr
|
|
||||||
%td
|
|
||||||
%a{href: project_deploy_key_path(key.project, key)}
|
|
||||||
%strong= key.title
|
|
||||||
%td
|
|
||||||
%span.update-author
|
|
||||||
Added
|
|
||||||
= time_ago_in_words(key.created_at)
|
|
||||||
ago
|
|
||||||
%td
|
|
||||||
= link_to 'Remove', project_deploy_key_path(key.project, key), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove delete-key btn-small pull-right"
|
|
||||||
|
|
|
@ -1,17 +1,26 @@
|
||||||
= render "projects/settings_nav"
|
= render "projects/settings_nav"
|
||||||
|
|
||||||
%p.slead
|
%p.slead
|
||||||
Deploy keys allow read-only access to repository. They can be used for CI, staging or production servers. A deploy key can be added to only one project. If you need to add the same key to multiple projects you can create a deploy user and add that user to multiple projects.
|
Deploy keys allow read-only access to repository. They can be used for CI, staging or production servers
|
||||||
|
|
||||||
- if can? current_user, :admin_project, @project
|
%p
|
||||||
= link_to new_project_deploy_key_path(@project), class: "btn btn-small", title: "New Deploy Key" do
|
You can create a deploy key or add existing one
|
||||||
Add Deploy Key
|
= link_to new_project_deploy_key_path(@project), class: "btn btn-primary pull-right", title: "New Deploy Key" do
|
||||||
- if @keys.any?
|
%i.icon-plus
|
||||||
%table
|
New Deploy Key
|
||||||
%thead
|
|
||||||
%tr
|
%hr.clearfix
|
||||||
%th Keys
|
|
||||||
%th
|
.row
|
||||||
%th
|
.span6.enabled-keys
|
||||||
- @keys.each do |key|
|
%h5.cgreen
|
||||||
= render(partial: 'show', locals: {key: key})
|
Enabled deploy keys
|
||||||
|
%small for this project
|
||||||
|
%ul.bordered-list
|
||||||
|
= render @enabled_keys
|
||||||
|
.span6.available-keys
|
||||||
|
%h5
|
||||||
|
Available deploy keys
|
||||||
|
%small from projects you are able to manage
|
||||||
|
%ul.bordered-list
|
||||||
|
= render @available_keys
|
||||||
|
|
|
@ -12,4 +12,4 @@
|
||||||
%hr
|
%hr
|
||||||
%pre= @key.key
|
%pre= @key.key
|
||||||
.pull-right
|
.pull-right
|
||||||
= link_to 'Remove', project_deploy_key_path(@key.project, @key), confirm: 'Are you sure?', method: :delete, class: "btn-remove btn delete-key"
|
= link_to 'Remove', project_deploy_key_path(@project, @key), confirm: 'Are you sure?', method: :delete, class: "btn-remove btn delete-key"
|
||||||
|
|
|
@ -215,7 +215,13 @@ Gitlab::Application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :deploy_keys
|
resources :deploy_keys do
|
||||||
|
member do
|
||||||
|
put :enable
|
||||||
|
put :disable
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
resources :protected_branches, only: [:index, :create, :destroy]
|
resources :protected_branches, only: [:index, :create, :destroy]
|
||||||
|
|
||||||
resources :refs, only: [] do
|
resources :refs, only: [] do
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe "Projects", "DeployKeys" do
|
|
||||||
let(:project) { create(:project) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
login_as :user
|
|
||||||
project.team << [@user, :master]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET /keys" do
|
|
||||||
before do
|
|
||||||
@key = create(:key, project: project)
|
|
||||||
visit project_deploy_keys_path(project)
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { page }
|
|
||||||
|
|
||||||
it { should have_content(@key.title) }
|
|
||||||
|
|
||||||
describe "Destroy" do
|
|
||||||
before { visit project_deploy_key_path(project, @key) }
|
|
||||||
|
|
||||||
it "should remove entry" do
|
|
||||||
expect {
|
|
||||||
click_link "Remove"
|
|
||||||
}.to change { project.deploy_keys.count }.by(-1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "New key" do
|
|
||||||
before do
|
|
||||||
visit project_deploy_keys_path(project)
|
|
||||||
click_link "New Deploy Key"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should open new key popup" do
|
|
||||||
page.should have_content("New Deploy key")
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "fill in" do
|
|
||||||
before do
|
|
||||||
fill_in "key_title", with: "laptop"
|
|
||||||
fill_in "key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop"
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect { click_button "Save" }.to change {Key.count}.by(1) }
|
|
||||||
|
|
||||||
it "should add new key to table" do
|
|
||||||
click_button "Save"
|
|
||||||
|
|
||||||
page.should have_content "laptop"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "Show page" do
|
|
||||||
before do
|
|
||||||
@key = create(:key, project: project)
|
|
||||||
visit project_deploy_key_path(project, @key)
|
|
||||||
end
|
|
||||||
|
|
||||||
it { page.should have_content @key.title }
|
|
||||||
it { page.should have_content @key.key[0..10] }
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in a new issue