Skip to content
代码片段 群组 项目
提交 4ea1635b 编辑于 作者: Andrew Fontaine's avatar Andrew Fontaine 提交者: Michał Zając
浏览文件

Add endpoints to paginate deploy keys by type

This will give the frontend the ability to fetch a specific set of
deploy keys at at time, reducing page load times and DB query time.
上级 333c352b
No related branches found
No related tags found
无相关合并请求
...@@ -22,6 +22,34 @@ def index ...@@ -22,6 +22,34 @@ def index
end end
end end
def enabled_keys
respond_to do |format|
format.json do
enabled_keys = find_keys(filter: :enabled_keys)
render json: serialize(enabled_keys)
end
end
end
def available_project_keys
respond_to do |format|
format.json do
available_project_keys = find_keys(filter: :available_project_keys)
render json: serialize(available_project_keys)
end
end
end
def available_public_keys
respond_to do |format|
format.json do
available_public_keys = find_keys(filter: :available_public_keys)
render json: serialize(available_public_keys)
end
end
end
def new def new
redirect_to_repository redirect_to_repository
end end
...@@ -108,4 +136,17 @@ def authorize_update_deploy_key! ...@@ -108,4 +136,17 @@ def authorize_update_deploy_key!
def redirect_to_repository def redirect_to_repository
redirect_to_repository_settings(@project, anchor: 'js-deploy-keys-settings') redirect_to_repository_settings(@project, anchor: 'js-deploy-keys-settings')
end end
def find_keys(params)
DeployKeys::DeployKeysFinder.new(@project, current_user, params)
.execute
end
def serialize(keys)
opts = { user: current_user, project: project }
DeployKeys::DeployKeySerializer.new
.with_pagination(request, response)
.represent(keys, opts)
end
end end
# frozen_string_literal: true
module DeployKeys
class DeployKeysFinder
attr_reader :project, :current_user, :params
def initialize(project, current_user, params = {})
@project = project
@current_user = current_user
@params = params
end
def execute
return empty unless can_admin_project?
case params[:filter]
when :enabled_keys
enabled_keys
when :available_project_keys
available_project_keys
when :available_public_keys
available_public_keys
else
empty
end
end
private
def enabled_keys
project.deploy_keys.with_projects
end
def available_project_keys
current_user.project_deploy_keys.with_projects.not_in(enabled_keys)
end
def available_public_keys
DeployKey.are_public.with_projects.not_in(enabled_keys)
end
def empty
DeployKey.none
end
def can_admin_project?
current_user.can?(:admin_project, project)
end
end
end
...@@ -25,6 +25,7 @@ class DeployKey < Key ...@@ -25,6 +25,7 @@ class DeployKey < Key
scope :with_projects, -> { includes(deploy_keys_projects: { project: [:route, namespace: :route] }) } scope :with_projects, -> { includes(deploy_keys_projects: { project: [:route, namespace: :route] }) }
scope :including_projects_with_write_access, -> { includes(:projects_with_write_access) } scope :including_projects_with_write_access, -> { includes(:projects_with_write_access) }
scope :including_projects_with_readonly_access, -> { includes(:projects_with_readonly_access) } scope :including_projects_with_readonly_access, -> { includes(:projects_with_readonly_access) }
scope :not_in, ->(keys) { where.not(id: keys.select(:id)) }
accepts_nested_attributes_for :deploy_keys_projects, reject_if: :reject_deploy_keys_projects? accepts_nested_attributes_for :deploy_keys_projects, reject_if: :reject_deploy_keys_projects?
......
...@@ -3,5 +3,6 @@ ...@@ -3,5 +3,6 @@
module DeployKeys module DeployKeys
class DeployKeySerializer < BaseSerializer class DeployKeySerializer < BaseSerializer
entity DeployKeyEntity entity DeployKeyEntity
include WithPagination
end end
end end
...@@ -186,6 +186,12 @@ ...@@ -186,6 +186,12 @@
end end
resources :deploy_keys, constraints: { id: /\d+/ }, only: [:index, :new, :create, :edit, :update] do resources :deploy_keys, constraints: { id: /\d+/ }, only: [:index, :new, :create, :edit, :update] do
collection do
get :enabled_keys
get :available_project_keys
get :available_public_keys
end
member do member do
put :enable put :enable
put :disable put :disable
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Projects::DeployKeysController do RSpec.describe Projects::DeployKeysController, feature_category: :continuous_delivery do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:admin) { create(:admin) } let(:admin) { create(:admin) }
...@@ -13,60 +13,94 @@ ...@@ -13,60 +13,94 @@
sign_in(user) sign_in(user)
end end
describe 'GET index' do describe 'GET actions' do
let(:params) do let_it_be(:project) { create(:project, :repository) }
{ namespace_id: project.namespace, project_id: project } let_it_be(:user) { create(:user) }
end
context 'when html requested' do let_it_be(:accessible_project) { create(:project, :internal).tap { |p| p.add_developer(user) } }
it 'redirects to project settings with the correct anchor' do let_it_be(:inaccessible_project) { create(:project, :internal) }
get :index, params: params let_it_be(:project_private) { create(:project, :private) }
expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings')) let_it_be(:deploy_key_for_target_project) do
end create(:deploy_keys_project, project: project, deploy_key: create(:deploy_key))
end end
context 'when json requested' do let_it_be(:deploy_key_for_accessible_project) do
let(:project2) { create(:project, :internal) } create(:deploy_keys_project, project: accessible_project, deploy_key: create(:deploy_key))
let(:project_private) { create(:project, :private) } end
let(:deploy_key_internal) { create(:deploy_key) } let_it_be(:deploy_key_for_inaccessible_project) do
let(:deploy_key_actual) { create(:deploy_key) } create(:deploy_keys_project, project: inaccessible_project, deploy_key: create(:deploy_key))
let!(:deploy_key_public) { create(:deploy_key, public: true) } end
let!(:deploy_keys_project_internal) do let_it_be(:deploy_keys_project_private) do
create(:deploy_keys_project, project: project2, deploy_key: deploy_key_internal) create(:deploy_keys_project, project: project_private, deploy_key: create(:another_deploy_key))
end end
let!(:deploy_keys_project_actual) do let_it_be(:deploy_key_public) { create(:deploy_key, public: true) }
create(:deploy_keys_project, project: project, deploy_key: deploy_key_actual)
end
let!(:deploy_keys_project_private) do describe 'GET index' do
create(:deploy_keys_project, project: project_private, deploy_key: create(:another_deploy_key)) let(:params) do
{ namespace_id: project.namespace, project_id: project }
end end
context 'when user has access to all projects where deploy keys are used' do context 'when html requested' do
before do it 'redirects to project settings with the correct anchor' do
project2.add_developer(user) get :index, params: params
expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
end end
end
context 'when json requested' do
it 'returns json in a correct format' do it 'returns json in a correct format' do
get :index, params: params.merge(format: :json) 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.keys).to match_array(%w[enabled_keys available_project_keys public_keys])
expect(json_response['enabled_keys'].count).to eq(1) expect(json_response['enabled_keys'].pluck('id')).to match_array(
expect(json_response['available_project_keys'].count).to eq(1) [deploy_key_for_target_project.deploy_key_id]
expect(json_response['public_keys'].count).to eq(1) )
expect(json_response['available_project_keys'].pluck('id')).to match_array(
[deploy_key_for_accessible_project.deploy_key_id]
)
expect(json_response['public_keys'].pluck('id')).to match_array([deploy_key_public.id])
end end
end end
end
context 'when user has no access to all projects where deploy keys are used' do describe 'GET enabled_keys' do
it 'returns json in a correct format' do let(:params) do
get :index, params: params.merge(format: :json) { namespace_id: project.namespace, project_id: project }
end
expect(json_response['available_project_keys'].count).to eq(0) it 'returns only enabled keys' do
end get :enabled_keys, params: params.merge(format: :json)
expect(json_response.pluck("id")).to match_array([deploy_key_for_target_project.deploy_key_id])
end
end
describe 'GET available_project_keys' do
let(:params) do
{ namespace_id: project.namespace, project_id: project }
end
it 'returns available project keys' do
get :available_project_keys, params: params.merge(format: :json)
expect(json_response.pluck("id")).to match_array([deploy_key_for_accessible_project.deploy_key_id])
end
end
describe 'GET available_public_keys' do
let(:params) do
{ namespace_id: project.namespace, project_id: project }
end
it 'returns available public keys' do
get :available_public_keys, params: params.merge(format: :json)
expect(json_response.pluck("id")).to match_array([deploy_key_public.id])
end end
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe DeployKeys::DeployKeysFinder, feature_category: :continuous_delivery do
describe '#execute' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:accessible_project) { create(:project, :internal).tap { |p| p.add_developer(user) } }
let_it_be(:inaccessible_project) { create(:project, :internal) }
let_it_be(:project_private) { create(:project, :private) }
let_it_be(:deploy_key_for_target_project) do
create(:deploy_keys_project, project: project, deploy_key: create(:deploy_key))
end
let_it_be(:deploy_key_for_accessible_project) do
create(:deploy_keys_project, project: accessible_project, deploy_key: create(:deploy_key))
end
let_it_be(:deploy_key_for_inaccessible_project) do
create(:deploy_keys_project, project: inaccessible_project, deploy_key: create(:deploy_key))
end
let_it_be(:deploy_keys_project_private) do
create(:deploy_keys_project, project: project_private, deploy_key: create(:another_deploy_key))
end
let_it_be(:deploy_key_public) { create(:deploy_key, public: true) }
let(:params) { {} }
subject(:result) { described_class.new(project, user, params).execute }
context 'with access' do
before_all do
project.add_maintainer(user)
end
context 'when filtering for enabled_keys' do
let(:params) { { filter: :enabled_keys } }
it 'returns the correct result' do
expect(result.map(&:id)).to match_array([deploy_key_for_target_project.deploy_key_id])
end
end
context 'when filtering for available project keys' do
let(:params) { { filter: :available_project_keys } }
it 'returns the correct result' do
expect(result.map(&:id)).to match_array([deploy_key_for_accessible_project.deploy_key_id])
end
end
context 'when filtering for available public keys' do
let(:params) { { filter: :available_public_keys } }
it 'returns the correct result' do
expect(result.map(&:id)).to match_array([deploy_key_public.id])
end
end
context 'when there are no set filters' do
it 'returns an empty collection' do
expect(result).to eq DeployKey.none
end
end
end
context 'without access' do
it 'returns an empty collection' do
expect(result).to eq DeployKey.none
end
end
end
end
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册