Commit 1882baa1 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Feature: Deploy keys between projects

parent 8e4625af
...@@ -5,7 +5,8 @@ class DeployKeysController < ProjectResourceController ...@@ -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 ...@@ -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 ...@@ -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
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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
# #
......
%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 @@ ...@@ -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"
%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"
= 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 @@ ...@@ -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 ...@@ -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
......
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment