1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
# frozen_string_literal: true
module API
class Members < Grape::API
include PaginationParams
before { authenticate! }
helpers ::API::Helpers::MembersHelpers
%w[group project].each do |source_type|
params do
requires :id, type: String, desc: "The #{source_type} ID"
end
resource source_type.pluralize, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Gets a list of group or project members viewable by the authenticated user.' do
success Entities::Member
end
params do
optional :query, type: String, desc: 'A query string to search for members'
use :pagination
end
# rubocop: disable CodeReuse/ActiveRecord
get ":id/members" do
source = find_source(source_type, params[:id])
members = source.members.where.not(user_id: nil).includes(:user)
members = members.joins(:user).merge(User.search(params[:query])) if params[:query].present?
members = paginate(members)
present members, with: Entities::Member
end
# rubocop: enable CodeReuse/ActiveRecord
desc 'Gets a list of group or project members viewable by the authenticated user, including those who gained membership through ancestor group.' do
success Entities::Member
end
params do
optional :query, type: String, desc: 'A query string to search for members'
use :pagination
end
# rubocop: disable CodeReuse/ActiveRecord
get ":id/members/all" do
source = find_source(source_type, params[:id])
members = find_all_members(source_type, source)
members = members.includes(:user).references(:user).merge(User.search(params[:query])) if params[:query].present?
members = paginate(members)
present members, with: Entities::Member
end
# rubocop: enable CodeReuse/ActiveRecord
desc 'Gets a member of a group or project.' do
success Entities::Member
end
params do
requires :user_id, type: Integer, desc: 'The user ID of the member'
end
# rubocop: disable CodeReuse/ActiveRecord
get ":id/members/:user_id" do
source = find_source(source_type, params[:id])
members = source.members
member = members.find_by!(user_id: params[:user_id])
present member, with: Entities::Member
end
# rubocop: enable CodeReuse/ActiveRecord
desc 'Adds a member to a group or project.' do
success Entities::Member
end
params do
requires :user_id, type: Integer, desc: 'The user ID of the new member'
requires :access_level, type: Integer, desc: 'A valid access level (defaults: `30`, developer access level)'
optional :expires_at, type: DateTime, desc: 'Date string in the format YEAR-MONTH-DAY'
end
# rubocop: disable CodeReuse/ActiveRecord
post ":id/members" do
source = find_source(source_type, params[:id])
authorize_admin_source!(source_type, source)
member = source.members.find_by(user_id: params[:user_id])
conflict!('Member already exists') if member
user = User.find_by_id(params[:user_id])
not_found!('User') unless user
member = source.add_user(user, params[:access_level], current_user: current_user, expires_at: params[:expires_at])
if !member
not_allowed! # This currently can only be reached in EE
elsif member.persisted? && member.valid?
present member, with: Entities::Member
else
render_validation_error!(member)
end
end
# rubocop: enable CodeReuse/ActiveRecord
desc 'Updates a member of a group or project.' do
success Entities::Member
end
params do
requires :user_id, type: Integer, desc: 'The user ID of the new member'
requires :access_level, type: Integer, desc: 'A valid access level'
optional :expires_at, type: DateTime, desc: 'Date string in the format YEAR-MONTH-DAY'
end
# rubocop: disable CodeReuse/ActiveRecord
put ":id/members/:user_id" do
source = find_source(source_type, params.delete(:id))
authorize_admin_source!(source_type, source)
member = source.members.find_by!(user_id: params[:user_id])
updated_member =
::Members::UpdateService
.new(current_user, declared_params(include_missing: false))
.execute(member)
if updated_member.valid?
present updated_member, with: Entities::Member
else
render_validation_error!(updated_member)
end
end
# rubocop: enable CodeReuse/ActiveRecord
desc 'Removes a user from a group or project.'
params do
requires :user_id, type: Integer, desc: 'The user ID of the member'
end
# rubocop: disable CodeReuse/ActiveRecord
delete ":id/members/:user_id" do
source = find_source(source_type, params[:id])
member = source.members.find_by!(user_id: params[:user_id])
destroy_conditionally!(member) do
::Members::DestroyService.new(current_user).execute(member)
end
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
end
end
|