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,7 +48,8 @@ gem "gitlab-linguist", "~> 3.0.0", require: "linguist" | ||
48 | 48 | ||
49 | # API | 49 | # API |
50 | gem "grape", "~> 0.6.1" | 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 | gem 'rack-cors', require: 'rack/cors' | 53 | gem 'rack-cors', require: 'rack/cors' |
53 | 54 | ||
54 | # Email validation | 55 | # Email validation |
Gemfile.lock
@@ -5,6 +5,15 @@ GIT | @@ -5,6 +5,15 @@ GIT | ||
5 | specs: | 5 | specs: |
6 | github-markup (0.7.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 | GEM | 17 | GEM |
9 | remote: https://rubygems.org/ | 18 | remote: https://rubygems.org/ |
10 | specs: | 19 | specs: |
@@ -206,9 +215,6 @@ GEM | @@ -206,9 +215,6 @@ GEM | ||
206 | rack-accept | 215 | rack-accept |
207 | rack-mount | 216 | rack-mount |
208 | virtus (>= 1.0.0) | 217 | virtus (>= 1.0.0) |
209 | - grape-entity (0.3.0) | ||
210 | - activesupport | ||
211 | - multi_json (>= 1.3.2) | ||
212 | growl (1.0.3) | 218 | growl (1.0.3) |
213 | guard (2.2.4) | 219 | guard (2.2.4) |
214 | formatador (>= 0.2.4) | 220 | formatador (>= 0.2.4) |
@@ -596,7 +602,7 @@ DEPENDENCIES | @@ -596,7 +602,7 @@ DEPENDENCIES | ||
596 | gitlab_omniauth-ldap (= 1.0.4) | 602 | gitlab_omniauth-ldap (= 1.0.4) |
597 | gon (~> 5.0.0) | 603 | gon (~> 5.0.0) |
598 | grape (~> 0.6.1) | 604 | grape (~> 0.6.1) |
599 | - grape-entity (~> 0.3.0) | 605 | + grape-entity (~> 0.4.1)! |
600 | growl | 606 | growl |
601 | guard-rspec | 607 | guard-rspec |
602 | guard-spinach | 608 | guard-spinach |
doc/api/projects.md
@@ -148,6 +148,16 @@ Parameters: | @@ -148,6 +148,16 @@ Parameters: | ||
148 | "path": "diaspora", | 148 | "path": "diaspora", |
149 | "updated_at": "2013-09-30T13: 46: 02Z" | 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,7 +44,7 @@ module API | ||
44 | expose :id, :description, :default_branch | 44 | expose :id, :description, :default_branch |
45 | expose :public?, as: :public | 45 | expose :public?, as: :public |
46 | expose :visibility_level, :ssh_url_to_repo, :http_url_to_repo, :web_url | 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 | expose :name, :name_with_namespace | 48 | expose :name, :name_with_namespace |
49 | expose :path, :path_with_namespace | 49 | expose :path, :path_with_namespace |
50 | expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :snippets_enabled, :created_at, :last_activity_at | 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,18 +58,6 @@ module API | ||
58 | end | 58 | end |
59 | end | 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 | class Group < Grape::Entity | 61 | class Group < Grape::Entity |
74 | expose :id, :name, :path, :owner_id | 62 | expose :id, :name, :path, :owner_id |
75 | end | 63 | end |
@@ -144,7 +132,7 @@ module API | @@ -144,7 +132,7 @@ module API | ||
144 | end | 132 | end |
145 | 133 | ||
146 | class MergeRequest < ProjectEntity | 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 | expose :author, :assignee, using: Entities::UserBasic | 136 | expose :author, :assignee, using: Entities::UserBasic |
149 | expose :source_project_id, :target_project_id | 137 | expose :source_project_id, :target_project_id |
150 | end | 138 | end |
@@ -175,5 +163,29 @@ module API | @@ -175,5 +163,29 @@ module API | ||
175 | class Namespace < Grape::Entity | 163 | class Namespace < Grape::Entity |
176 | expose :id, :path, :kind | 164 | expose :id, :path, :kind |
177 | end | 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 | end | 190 | end |
179 | end | 191 | end |
lib/api/projects.rb
@@ -48,7 +48,7 @@ module API | @@ -48,7 +48,7 @@ module API | ||
48 | # Example Request: | 48 | # Example Request: |
49 | # GET /projects/:id | 49 | # GET /projects/:id |
50 | get ":id" do | 50 | get ":id" do |
51 | - present user_project, with: Entities::Project | 51 | + present user_project, with: Entities::ProjectWithAccess, user: current_user |
52 | end | 52 | end |
53 | 53 | ||
54 | # Get a single project events | 54 | # Get a single project events |
spec/requests/api/projects_spec.rb
@@ -259,6 +259,7 @@ describe API::API do | @@ -259,6 +259,7 @@ describe API::API do | ||
259 | 259 | ||
260 | describe "GET /projects/:id" do | 260 | describe "GET /projects/:id" do |
261 | before { project } | 261 | before { project } |
262 | + before { users_project } | ||
262 | 263 | ||
263 | it "should return a project by id" do | 264 | it "should return a project by id" do |
264 | get api("/projects/#{project.id}", user) | 265 | get api("/projects/#{project.id}", user) |
@@ -284,6 +285,28 @@ describe API::API do | @@ -284,6 +285,28 @@ describe API::API do | ||
284 | get api("/projects/#{project.id}", other_user) | 285 | get api("/projects/#{project.id}", other_user) |
285 | response.status.should == 404 | 286 | response.status.should == 404 |
286 | end | 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 | end | 310 | end |
288 | 311 | ||
289 | describe "GET /projects/:id/events" do | 312 | describe "GET /projects/:id/events" do |