New Members::ApproveAccessRequestService
Signed-off-by: Rémy Coutable <remy@rymai.me>
This commit is contained in:
		
							parent
							
								
									8071dc83fa
								
							
						
					
					
						commit
						b3f0a82f50
					
				|  | @ -1,6 +1,5 @@ | |||
| module MembershipActions | ||||
|   extend ActiveSupport::Concern | ||||
|   include MembersHelper | ||||
| 
 | ||||
|   def request_access | ||||
|     membershipable.request_access(current_user) | ||||
|  | @ -10,11 +9,7 @@ module MembershipActions | |||
|   end | ||||
| 
 | ||||
|   def approve_access_request | ||||
|     @member = membershipable.requesters.find(params[:id]) | ||||
| 
 | ||||
|     return render_403 unless can?(current_user, action_member_permission(:update, @member), @member) | ||||
| 
 | ||||
|     @member.accept_request | ||||
|     Members::ApproveAccessRequestService.new(membershipable, current_user, user_id: params[:id]).execute | ||||
| 
 | ||||
|     redirect_to polymorphic_url([membershipable, :members]) | ||||
|   end | ||||
|  |  | |||
|  | @ -0,0 +1,30 @@ | |||
| module Members | ||||
|   class ApproveAccessRequestService < BaseService | ||||
|     include MembersHelper | ||||
| 
 | ||||
|     attr_accessor :source | ||||
| 
 | ||||
|     def initialize(source, current_user, params = {}) | ||||
|       @source = source | ||||
|       @current_user = current_user | ||||
|       @params = params | ||||
|     end | ||||
| 
 | ||||
|     def execute | ||||
|       access_requester = source.requesters.find_by!(user_id: params[:user_id]) | ||||
| 
 | ||||
|       raise Gitlab::Access::AccessDeniedError if cannot_update_access_requester?(access_requester) | ||||
| 
 | ||||
|       access_requester.access_level = params[:access_level] if params[:access_level] | ||||
|       access_requester.accept_request | ||||
| 
 | ||||
|       access_requester | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def cannot_update_access_requester?(access_requester) | ||||
|       !access_requester || !can?(current_user, action_member_permission(:update, access_requester), access_requester) | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | @ -55,13 +55,8 @@ module API | |||
|         put ':id/access_requests/:user_id/approve' do | ||||
|           required_attributes! [:user_id] | ||||
|           source = find_source(source_type, params[:id]) | ||||
|           authorize_admin_source!(source_type, source) | ||||
| 
 | ||||
|           member = source.requesters.find_by!(user_id: params[:user_id]) | ||||
|           if params[:access_level] | ||||
|             member.update(access_level: params[:access_level]) | ||||
|           end | ||||
|           member.accept_request | ||||
|           member = ::Members::ApproveAccessRequestService.new(source, current_user, params).execute | ||||
| 
 | ||||
|           status :created | ||||
|           present member.user, with: Entities::Member, member: member | ||||
|  |  | |||
|  | @ -0,0 +1,88 @@ | |||
| require 'spec_helper' | ||||
| 
 | ||||
| describe Members::ApproveAccessRequestService, services: true do | ||||
|   let(:user) { create(:user) } | ||||
|   let(:access_requester) { create(:user) } | ||||
|   let(:project) { create(:project, :public) } | ||||
|   let(:group) { create(:group, :public) } | ||||
| 
 | ||||
|   shared_examples 'a service raising ActiveRecord::RecordNotFound' do | ||||
|     it 'raises ActiveRecord::RecordNotFound' do | ||||
|       expect { described_class.new(source, user, params).execute }.to raise_error(ActiveRecord::RecordNotFound) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   shared_examples 'a service raising Gitlab::Access::AccessDeniedError' do | ||||
|     it 'raises Gitlab::Access::AccessDeniedError' do | ||||
|       expect { described_class.new(source, user, params).execute }.to raise_error(Gitlab::Access::AccessDeniedError) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   shared_examples 'a service approving an access request' do | ||||
|     it 'succeeds' do | ||||
|       expect { described_class.new(source, user, params).execute }.to change { source.requesters.count }.by(-1) | ||||
|     end | ||||
| 
 | ||||
|     it 'returns a <Source>Member' do | ||||
|       member = described_class.new(source, user, params).execute | ||||
| 
 | ||||
|       expect(member).to be_a "#{source.class.to_s}Member".constantize | ||||
|       expect(member.requested_at).to be_nil | ||||
|     end | ||||
| 
 | ||||
|     context 'with a custom access level' do | ||||
|       let(:params) { { user_id: access_requester.id, access_level: Gitlab::Access::MASTER } } | ||||
| 
 | ||||
|       it 'returns a ProjectMember with the custom access level' do | ||||
|         member = described_class.new(source, user, params).execute | ||||
| 
 | ||||
|         expect(member.access_level).to eq Gitlab::Access::MASTER | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   context 'when no access requester are found' do | ||||
|     let(:params) { { user_id: 42 } } | ||||
| 
 | ||||
|     it_behaves_like 'a service raising ActiveRecord::RecordNotFound' do | ||||
|       let(:source) { project } | ||||
|     end | ||||
| 
 | ||||
|     it_behaves_like 'a service raising ActiveRecord::RecordNotFound' do | ||||
|       let(:source) { group } | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   context 'when an access requester is found' do | ||||
|     before do | ||||
|       project.request_access(access_requester) | ||||
|       group.request_access(access_requester) | ||||
|     end | ||||
|     let(:params) { { user_id: access_requester.id } } | ||||
| 
 | ||||
|     context 'when current user cannot approve access request to the project' do | ||||
|       it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError' do | ||||
|         let(:source) { project } | ||||
|       end | ||||
| 
 | ||||
|       it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError' do | ||||
|         let(:source) { group } | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'when current user can approve access request to the project' do | ||||
|       before do | ||||
|         project.team << [user, :master] | ||||
|         group.add_owner(user) | ||||
|       end | ||||
| 
 | ||||
|       it_behaves_like 'a service approving an access request' do | ||||
|         let(:source) { project } | ||||
|       end | ||||
| 
 | ||||
|       it_behaves_like 'a service approving an access request' do | ||||
|         let(:source) { group } | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
		Loading…
	
		Reference in New Issue