369 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			369 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
require 'spec_helper'
 | 
						|
 | 
						|
RSpec.describe Projects::DeployKeysController do
 | 
						|
  let(:project) { create(:project, :repository) }
 | 
						|
  let(:user) { create(:user) }
 | 
						|
  let(:admin) { create(:admin) }
 | 
						|
 | 
						|
  before do
 | 
						|
    project.add_maintainer(user)
 | 
						|
 | 
						|
    sign_in(user)
 | 
						|
  end
 | 
						|
 | 
						|
  describe 'GET index' do
 | 
						|
    let(:params) do
 | 
						|
      { namespace_id: project.namespace, project_id: project }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when html requested' do
 | 
						|
      it 'redirects to project settings with the correct anchor' do
 | 
						|
        get :index, params: params
 | 
						|
 | 
						|
        expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when json requested' do
 | 
						|
      let(:project2) { create(:project, :internal)}
 | 
						|
      let(:project_private) { create(:project, :private)}
 | 
						|
 | 
						|
      let(:deploy_key_internal) { create(:deploy_key) }
 | 
						|
      let(:deploy_key_actual) { create(:deploy_key) }
 | 
						|
      let!(:deploy_key_public) { create(:deploy_key, public: true) }
 | 
						|
 | 
						|
      let!(:deploy_keys_project_internal) do
 | 
						|
        create(:deploy_keys_project, project: project2, deploy_key: deploy_key_internal)
 | 
						|
      end
 | 
						|
 | 
						|
      let!(:deploy_keys_project_actual) do
 | 
						|
        create(:deploy_keys_project, project: project, deploy_key: deploy_key_actual)
 | 
						|
      end
 | 
						|
 | 
						|
      let!(:deploy_keys_project_private) do
 | 
						|
        create(:deploy_keys_project, project: project_private, deploy_key: create(:another_deploy_key))
 | 
						|
      end
 | 
						|
 | 
						|
      context 'when user has access to all projects where deploy keys are used' do
 | 
						|
        before do
 | 
						|
          project2.add_developer(user)
 | 
						|
        end
 | 
						|
 | 
						|
        it 'returns json in a correct format' do
 | 
						|
          get :index, params: params.merge(format: :json)
 | 
						|
 | 
						|
          expect(json_response.keys).to match_array(%w(enabled_keys available_project_keys public_keys))
 | 
						|
          expect(json_response['enabled_keys'].count).to eq(1)
 | 
						|
          expect(json_response['available_project_keys'].count).to eq(1)
 | 
						|
          expect(json_response['public_keys'].count).to eq(1)
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      context 'when user has no access to all projects where deploy keys are used' do
 | 
						|
        it 'returns json in a correct format' do
 | 
						|
          get :index, params: params.merge(format: :json)
 | 
						|
 | 
						|
          expect(json_response['available_project_keys'].count).to eq(0)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe 'POST create' do
 | 
						|
    def create_params(title = 'my-key')
 | 
						|
      {
 | 
						|
        namespace_id: project.namespace.path,
 | 
						|
        project_id: project.path,
 | 
						|
        deploy_key: {
 | 
						|
          title: title,
 | 
						|
          key: attributes_for(:deploy_key)[:key],
 | 
						|
          deploy_keys_projects_attributes: { '0' => { can_push: '1' } }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    end
 | 
						|
 | 
						|
    it 'creates a new deploy key for the project' do
 | 
						|
      expect { post :create, params: create_params }.to change(project.deploy_keys, :count).by(1)
 | 
						|
 | 
						|
      expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
 | 
						|
    end
 | 
						|
 | 
						|
    it 'redirects to project settings with the correct anchor' do
 | 
						|
      post :create, params: create_params
 | 
						|
 | 
						|
      expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when the deploy key is invalid' do
 | 
						|
      it 'shows an alert with the validations errors' do
 | 
						|
        post :create, params: create_params(nil)
 | 
						|
 | 
						|
        expect(flash[:alert]).to eq("Title can't be blank, Deploy keys projects deploy key title can't be blank")
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '/enable/:id' do
 | 
						|
    let(:deploy_key) { create(:deploy_key) }
 | 
						|
    let(:project2) { create(:project) }
 | 
						|
    let!(:deploy_keys_project_internal) do
 | 
						|
      create(:deploy_keys_project, project: project2, deploy_key: deploy_key)
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with anonymous user' do
 | 
						|
      before do
 | 
						|
        sign_out(:user)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'redirects to login' do
 | 
						|
        expect do
 | 
						|
          put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
 | 
						|
        end.not_to change { DeployKeysProject.count }
 | 
						|
 | 
						|
        expect(response).to have_gitlab_http_status(:found)
 | 
						|
        expect(response).to redirect_to(new_user_session_path)
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with user with no permission' do
 | 
						|
      before do
 | 
						|
        sign_in(create(:user))
 | 
						|
      end
 | 
						|
 | 
						|
      it 'returns 404' do
 | 
						|
        expect do
 | 
						|
          put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
 | 
						|
        end.not_to change { DeployKeysProject.count }
 | 
						|
 | 
						|
        expect(response).to have_gitlab_http_status(:not_found)
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with user with permission' do
 | 
						|
      before do
 | 
						|
        project2.add_maintainer(user)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'returns 302' do
 | 
						|
        expect do
 | 
						|
          put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
 | 
						|
        end.to change { DeployKeysProject.count }.by(1)
 | 
						|
 | 
						|
        expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
 | 
						|
        expect(response).to have_gitlab_http_status(:found)
 | 
						|
        expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
 | 
						|
      end
 | 
						|
 | 
						|
      it 'returns 404' do
 | 
						|
        put :enable, params: { id: 0, namespace_id: project.namespace, project_id: project }
 | 
						|
 | 
						|
        expect(response).to have_gitlab_http_status(:not_found)
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with admin', :enable_admin_mode do
 | 
						|
      before do
 | 
						|
        sign_in(admin)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'returns 302' do
 | 
						|
        expect do
 | 
						|
          put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
 | 
						|
        end.to change { DeployKeysProject.count }.by(1)
 | 
						|
 | 
						|
        expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
 | 
						|
        expect(response).to have_gitlab_http_status(:found)
 | 
						|
        expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '/disable/:id' do
 | 
						|
    let(:deploy_key) { create(:deploy_key) }
 | 
						|
    let!(:deploy_key_project) { create(:deploy_keys_project, project: project, deploy_key: deploy_key) }
 | 
						|
 | 
						|
    context 'with anonymous user' do
 | 
						|
      before do
 | 
						|
        sign_out(:user)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'redirects to login' do
 | 
						|
        put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
 | 
						|
 | 
						|
        expect(response).to have_gitlab_http_status(:found)
 | 
						|
        expect(response).to redirect_to(new_user_session_path)
 | 
						|
        expect(DeployKey.find(deploy_key.id)).to eq(deploy_key)
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with user with no permission' do
 | 
						|
      before do
 | 
						|
        sign_in(create(:user))
 | 
						|
      end
 | 
						|
 | 
						|
      it 'returns 404' do
 | 
						|
        put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
 | 
						|
 | 
						|
        expect(response).to have_gitlab_http_status(:not_found)
 | 
						|
        expect(DeployKey.find(deploy_key.id)).to eq(deploy_key)
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with user with permission' do
 | 
						|
      it 'returns 302' do
 | 
						|
        put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
 | 
						|
 | 
						|
        expect(response).to have_gitlab_http_status(:found)
 | 
						|
        expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
 | 
						|
 | 
						|
        expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'returns 404' do
 | 
						|
        put :disable, params: { id: 0, namespace_id: project.namespace, project_id: project }
 | 
						|
 | 
						|
        expect(response).to have_gitlab_http_status(:not_found)
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with admin', :enable_admin_mode do
 | 
						|
      before do
 | 
						|
        sign_in(admin)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'returns 302' do
 | 
						|
        expect do
 | 
						|
          put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
 | 
						|
        end.to change { DeployKey.count }.by(-1)
 | 
						|
 | 
						|
        expect(response).to have_gitlab_http_status(:found)
 | 
						|
        expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
 | 
						|
 | 
						|
        expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound)
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe 'PUT update' do
 | 
						|
    let(:extra_params) { {} }
 | 
						|
 | 
						|
    subject do
 | 
						|
      put :update, params: extra_params.reverse_merge(id: deploy_key.id,
 | 
						|
                                                      namespace_id: project.namespace,
 | 
						|
                                                      project_id: project)
 | 
						|
    end
 | 
						|
 | 
						|
    def deploy_key_params(title, can_push)
 | 
						|
      deploy_keys_projects_attributes = { '0' => { can_push: can_push } }
 | 
						|
      { deploy_key: { title: title, deploy_keys_projects_attributes: deploy_keys_projects_attributes } }
 | 
						|
    end
 | 
						|
 | 
						|
    let(:deploy_key) { create(:deploy_key, public: true) }
 | 
						|
    let(:project) { create(:project) }
 | 
						|
    let!(:deploy_keys_project) do
 | 
						|
      create(:deploy_keys_project, project: project, deploy_key: deploy_key)
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with project maintainer' do
 | 
						|
      before do
 | 
						|
        project.add_maintainer(user)
 | 
						|
      end
 | 
						|
 | 
						|
      context 'public deploy key attached to project' do
 | 
						|
        let(:extra_params) { deploy_key_params('updated title', '1') }
 | 
						|
 | 
						|
        it 'does not update the title of the deploy key' do
 | 
						|
          expect { subject }.not_to change { deploy_key.reload.title }
 | 
						|
        end
 | 
						|
 | 
						|
        it 'updates can_push of deploy_keys_project' do
 | 
						|
          expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with admin', :enable_admin_mode do
 | 
						|
      before do
 | 
						|
        sign_in(admin)
 | 
						|
      end
 | 
						|
 | 
						|
      context 'public deploy key attached to project' do
 | 
						|
        let(:extra_params) { deploy_key_params('updated title', '1') }
 | 
						|
 | 
						|
        it 'updates the title of the deploy key' do
 | 
						|
          expect { subject }.to change { deploy_key.reload.title }.to('updated title')
 | 
						|
        end
 | 
						|
 | 
						|
        it 'updates can_push of deploy_keys_project' do
 | 
						|
          expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true)
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      context 'when a different deploy key id param is injected' do
 | 
						|
        let(:extra_params) { deploy_key_params('updated title', '1') }
 | 
						|
        let(:hacked_params) do
 | 
						|
          extra_params.reverse_merge(id: other_deploy_key_id,
 | 
						|
                                     namespace_id: project.namespace,
 | 
						|
                                     project_id: project)
 | 
						|
        end
 | 
						|
 | 
						|
        subject { put :update, params: hacked_params }
 | 
						|
 | 
						|
        context 'and that deploy key id exists' do
 | 
						|
          let(:other_project) { create(:project) }
 | 
						|
          let(:other_deploy_key) do
 | 
						|
            key = create(:deploy_key)
 | 
						|
            project.deploy_keys << key
 | 
						|
            key
 | 
						|
          end
 | 
						|
 | 
						|
          let(:other_deploy_key_id) { other_deploy_key.id }
 | 
						|
 | 
						|
          it 'does not update the can_push attribute' do
 | 
						|
            expect { subject }.not_to change { deploy_key.deploy_keys_project_for(project).can_push }
 | 
						|
          end
 | 
						|
        end
 | 
						|
 | 
						|
        context 'and that deploy key id does not exist' do
 | 
						|
          let(:other_deploy_key_id) { 9999 }
 | 
						|
 | 
						|
          it 'returns 404' do
 | 
						|
            subject
 | 
						|
 | 
						|
            expect(response).to have_gitlab_http_status(:not_found)
 | 
						|
          end
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with admin as project maintainer' do
 | 
						|
      before do
 | 
						|
        sign_in(admin)
 | 
						|
        project.add_maintainer(admin)
 | 
						|
      end
 | 
						|
 | 
						|
      context 'public deploy key attached to project' do
 | 
						|
        let(:extra_params) { deploy_key_params('updated title', '1') }
 | 
						|
 | 
						|
        context 'admin mode disabled' do
 | 
						|
          it 'does not update the title of the deploy key' do
 | 
						|
            expect { subject }.not_to change { deploy_key.reload.title }
 | 
						|
          end
 | 
						|
        end
 | 
						|
 | 
						|
        context 'admin mode enabled', :enable_admin_mode do
 | 
						|
          it 'updates the title of the deploy key' do
 | 
						|
            expect { subject }.to change { deploy_key.reload.title }.to('updated title')
 | 
						|
          end
 | 
						|
        end
 | 
						|
 | 
						|
        it 'updates can_push of deploy_keys_project' do
 | 
						|
          expect { subject }.to change { deploy_keys_project.reload.can_push }.from(false).to(true)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |