Commit 0f204c3222e741e1dbd732f30a676c81a45abaa4

Authored by Dmitriy Zaporozhets
2 parents 63a8af67 c02e3d44

Merge branch 'project-permissions' into 'master'

API: Project permissions
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
... ... @@ -48,7 +48,7 @@ module API
48 48 # Example Request:
49 49 # GET /projects/:id
50 50 get ":id" do
51   - present user_project, with: Entities::Project
  51 + present user_project, with: Entities::ProjectWithAccess, user: current_user
52 52 end
53 53  
54 54 # Get a single project events
... ...
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
... ...