Commit 0f204c3222e741e1dbd732f30a676c81a45abaa4
Exists in
spb-stable
and in
3 other branches
Merge branch 'project-permissions' into 'master'
API: Project permissions
Showing
6 changed files
with
72 additions
and
20 deletions
Show diff stats
Gemfile
... | ... | @@ -48,7 +48,8 @@ gem "gitlab-linguist", "~> 3.0.0", require: "linguist" |
48 | 48 | |
49 | 49 | # API |
50 | 50 | gem "grape", "~> 0.6.1" |
51 | -gem "grape-entity", "~> 0.3.0" | |
51 | +# Replace with rubygems when nesteted entities get released | |
52 | +gem "grape-entity", "~> 0.4.1", ref: 'd904381c951e86250c3f44213b349a3dd8e83fb1', git: 'https://github.com/intridea/grape-entity.git' | |
52 | 53 | gem 'rack-cors', require: 'rack/cors' |
53 | 54 | |
54 | 55 | # Email validation | ... | ... |
Gemfile.lock
... | ... | @@ -5,6 +5,15 @@ GIT |
5 | 5 | specs: |
6 | 6 | github-markup (0.7.6) |
7 | 7 | |
8 | +GIT | |
9 | + remote: https://github.com/intridea/grape-entity.git | |
10 | + revision: d904381c951e86250c3f44213b349a3dd8e83fb1 | |
11 | + ref: d904381c951e86250c3f44213b349a3dd8e83fb1 | |
12 | + specs: | |
13 | + grape-entity (0.4.1) | |
14 | + activesupport | |
15 | + multi_json (>= 1.3.2) | |
16 | + | |
8 | 17 | GEM |
9 | 18 | remote: https://rubygems.org/ |
10 | 19 | specs: |
... | ... | @@ -206,9 +215,6 @@ GEM |
206 | 215 | rack-accept |
207 | 216 | rack-mount |
208 | 217 | virtus (>= 1.0.0) |
209 | - grape-entity (0.3.0) | |
210 | - activesupport | |
211 | - multi_json (>= 1.3.2) | |
212 | 218 | growl (1.0.3) |
213 | 219 | guard (2.2.4) |
214 | 220 | formatador (>= 0.2.4) |
... | ... | @@ -596,7 +602,7 @@ DEPENDENCIES |
596 | 602 | gitlab_omniauth-ldap (= 1.0.4) |
597 | 603 | gon (~> 5.0.0) |
598 | 604 | grape (~> 0.6.1) |
599 | - grape-entity (~> 0.3.0) | |
605 | + grape-entity (~> 0.4.1)! | |
600 | 606 | growl |
601 | 607 | guard-rspec |
602 | 608 | guard-spinach | ... | ... |
doc/api/projects.md
... | ... | @@ -148,6 +148,16 @@ Parameters: |
148 | 148 | "path": "diaspora", |
149 | 149 | "updated_at": "2013-09-30T13: 46: 02Z" |
150 | 150 | } |
151 | + "permissions": { | |
152 | + "project_access": { | |
153 | + "access_level": 10, | |
154 | + "notification_level": 3 | |
155 | + }, | |
156 | + "group_access": { | |
157 | + "access_level": 50, | |
158 | + "notification_level": 3 | |
159 | + } | |
160 | + } | |
151 | 161 | } |
152 | 162 | ``` |
153 | 163 | ... | ... |
lib/api/entities.rb
... | ... | @@ -44,7 +44,7 @@ module API |
44 | 44 | expose :id, :description, :default_branch |
45 | 45 | expose :public?, as: :public |
46 | 46 | expose :visibility_level, :ssh_url_to_repo, :http_url_to_repo, :web_url |
47 | - expose :owner, using: Entities::UserBasic | |
47 | + expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } | |
48 | 48 | expose :name, :name_with_namespace |
49 | 49 | expose :path, :path_with_namespace |
50 | 50 | expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :snippets_enabled, :created_at, :last_activity_at |
... | ... | @@ -58,18 +58,6 @@ module API |
58 | 58 | end |
59 | 59 | end |
60 | 60 | |
61 | - class TeamMember < UserBasic | |
62 | - expose :permission, as: :access_level do |user, options| | |
63 | - options[:user_team].user_team_user_relationships.find_by(user_id: user.id).permission | |
64 | - end | |
65 | - end | |
66 | - | |
67 | - class TeamProject < Project | |
68 | - expose :greatest_access, as: :greatest_access_level do |project, options| | |
69 | - options[:user_team].user_team_project_relationships.find_by(project_id: project.id).greatest_access | |
70 | - end | |
71 | - end | |
72 | - | |
73 | 61 | class Group < Grape::Entity |
74 | 62 | expose :id, :name, :path, :owner_id |
75 | 63 | end |
... | ... | @@ -144,7 +132,7 @@ module API |
144 | 132 | end |
145 | 133 | |
146 | 134 | class MergeRequest < ProjectEntity |
147 | - expose :target_branch, :source_branch, :title, :state, :upvotes, :downvotes | |
135 | + expose :target_branch, :source_branch, :title, :state, :upvotes, :downvotes, :description | |
148 | 136 | expose :author, :assignee, using: Entities::UserBasic |
149 | 137 | expose :source_project_id, :target_project_id |
150 | 138 | end |
... | ... | @@ -175,5 +163,29 @@ module API |
175 | 163 | class Namespace < Grape::Entity |
176 | 164 | expose :id, :path, :kind |
177 | 165 | end |
166 | + | |
167 | + class ProjectAccess < Grape::Entity | |
168 | + expose :project_access, as: :access_level | |
169 | + expose :notification_level | |
170 | + end | |
171 | + | |
172 | + class GroupAccess < Grape::Entity | |
173 | + expose :group_access, as: :access_level | |
174 | + expose :notification_level | |
175 | + end | |
176 | + | |
177 | + class ProjectWithAccess < Project | |
178 | + expose :permissions do | |
179 | + expose :project_access, using: Entities::ProjectAccess do |project, options| | |
180 | + project.users_projects.find_by(user_id: options[:user].id) | |
181 | + end | |
182 | + | |
183 | + expose :group_access, using: Entities::GroupAccess do |project, options| | |
184 | + if project.group | |
185 | + project.group.users_groups.find_by(user_id: options[:user].id) | |
186 | + end | |
187 | + end | |
188 | + end | |
189 | + end | |
178 | 190 | end |
179 | 191 | end | ... | ... |
lib/api/projects.rb
spec/requests/api/projects_spec.rb
... | ... | @@ -259,6 +259,7 @@ describe API::API do |
259 | 259 | |
260 | 260 | describe "GET /projects/:id" do |
261 | 261 | before { project } |
262 | + before { users_project } | |
262 | 263 | |
263 | 264 | it "should return a project by id" do |
264 | 265 | get api("/projects/#{project.id}", user) |
... | ... | @@ -284,6 +285,28 @@ describe API::API do |
284 | 285 | get api("/projects/#{project.id}", other_user) |
285 | 286 | response.status.should == 404 |
286 | 287 | end |
288 | + | |
289 | + describe 'permissions' do | |
290 | + context 'personal project' do | |
291 | + before { get api("/projects/#{project.id}", user) } | |
292 | + | |
293 | + it { response.status.should == 200 } | |
294 | + it { json_response['permissions']["project_access"]["access_level"].should == Gitlab::Access::MASTER } | |
295 | + it { json_response['permissions']["group_access"].should be_nil } | |
296 | + end | |
297 | + | |
298 | + context 'group project' do | |
299 | + before do | |
300 | + project2 = create(:project, group: create(:group)) | |
301 | + project2.group.add_owner(user) | |
302 | + get api("/projects/#{project2.id}", user) | |
303 | + end | |
304 | + | |
305 | + it { response.status.should == 200 } | |
306 | + it { json_response['permissions']["project_access"].should be_nil } | |
307 | + it { json_response['permissions']["group_access"]["access_level"].should == Gitlab::Access::OWNER } | |
308 | + end | |
309 | + end | |
287 | 310 | end |
288 | 311 | |
289 | 312 | describe "GET /projects/:id/events" do | ... | ... |