Commit 2fc236177f70244101b285bde8ee6a77f779c0ce
Exists in
master
and in
4 other branches
Merge pull request #3801 from holdtotherod/feature/internally-public-projects
Internally public projects
Showing
8 changed files
with
276 additions
and
4 deletions
Show diff stats
app/controllers/application_controller.rb
@@ -88,7 +88,7 @@ class ApplicationController < ActionController::Base | @@ -88,7 +88,7 @@ class ApplicationController < ActionController::Base | ||
88 | end | 88 | end |
89 | 89 | ||
90 | def authorize_code_access! | 90 | def authorize_code_access! |
91 | - return access_denied! unless can?(current_user, :download_code, project) | 91 | + return access_denied! unless can?(current_user, :download_code, project) or project.public? |
92 | end | 92 | end |
93 | 93 | ||
94 | def authorize_create_team! | 94 | def authorize_create_team! |
app/models/ability.rb
@@ -37,7 +37,7 @@ class Ability | @@ -37,7 +37,7 @@ class Ability | ||
37 | elsif team.reporters.include?(user) | 37 | elsif team.reporters.include?(user) |
38 | rules << project_report_rules | 38 | rules << project_report_rules |
39 | 39 | ||
40 | - elsif team.guests.include?(user) | 40 | + elsif team.guests.include?(user) or project.public? |
41 | rules << project_guest_rules | 41 | rules << project_guest_rules |
42 | end | 42 | end |
43 | 43 |
app/views/projects/_form.html.haml
@@ -48,7 +48,7 @@ | @@ -48,7 +48,7 @@ | ||
48 | Public mode: | 48 | Public mode: |
49 | .control-group | 49 | .control-group |
50 | = f.label :public, class: 'control-label' do | 50 | = f.label :public, class: 'control-label' do |
51 | - %span Public clone access | 51 | + %span Public access |
52 | .controls | 52 | .controls |
53 | = f.check_box :public | 53 | = f.check_box :public |
54 | %span.descr | 54 | %span.descr |
@@ -56,6 +56,8 @@ | @@ -56,6 +56,8 @@ | ||
56 | %em without any | 56 | %em without any |
57 | authentication. | 57 | authentication. |
58 | It will also be listed on the #{link_to "public access directory", public_root_path}. | 58 | It will also be listed on the #{link_to "public access directory", public_root_path}. |
59 | + %em Any | ||
60 | + user will have #{link_to "Guest", help_permissions_path} permissions on the repository. | ||
59 | 61 | ||
60 | %fieldset.features | 62 | %fieldset.features |
61 | %legend | 63 | %legend |
app/views/public/projects/index.html.haml
@@ -9,7 +9,10 @@ | @@ -9,7 +9,10 @@ | ||
9 | %li.clearfix | 9 | %li.clearfix |
10 | %h5 | 10 | %h5 |
11 | %i.icon-share | 11 | %i.icon-share |
12 | - = project.name_with_namespace | 12 | + - if current_user |
13 | + = link_to_project project | ||
14 | + - else | ||
15 | + = project.name_with_namespace | ||
13 | .pull-right | 16 | .pull-right |
14 | %pre.dark.tiny git clone #{project.http_url_to_repo} | 17 | %pre.dark.tiny git clone #{project.http_url_to_repo} |
15 | %p.description | 18 | %p.description |
features/steps/shared/paths.rb
@@ -263,6 +263,14 @@ module SharedPaths | @@ -263,6 +263,14 @@ module SharedPaths | ||
263 | visit project_wiki_path(@project, :home) | 263 | visit project_wiki_path(@project, :home) |
264 | end | 264 | end |
265 | 265 | ||
266 | + # ---------------------------------------- | ||
267 | + # Public Projects | ||
268 | + # ---------------------------------------- | ||
269 | + | ||
270 | + Given 'I visit the public projects area' do | ||
271 | + visit public_root_path | ||
272 | + end | ||
273 | + | ||
266 | def root_ref | 274 | def root_ref |
267 | @project.repository.root_ref | 275 | @project.repository.root_ref |
268 | end | 276 | end |
spec/features/security/project_access_spec.rb
@@ -229,4 +229,246 @@ describe "Application access" do | @@ -229,4 +229,246 @@ describe "Application access" do | ||
229 | it { should be_denied_for :visitor } | 229 | it { should be_denied_for :visitor } |
230 | end | 230 | end |
231 | end | 231 | end |
232 | + | ||
233 | + | ||
234 | + describe "PublicProject" do | ||
235 | + let(:project) { create(:project_with_code) } | ||
236 | + | ||
237 | + let(:master) { create(:user) } | ||
238 | + let(:guest) { create(:user) } | ||
239 | + let(:reporter) { create(:user) } | ||
240 | + | ||
241 | + let(:admin) { create(:user) } | ||
242 | + | ||
243 | + before do | ||
244 | + # public project | ||
245 | + project.public = true | ||
246 | + project.save! | ||
247 | + | ||
248 | + # full access | ||
249 | + project.team << [master, :master] | ||
250 | + | ||
251 | + # readonly | ||
252 | + project.team << [reporter, :reporter] | ||
253 | + | ||
254 | + end | ||
255 | + | ||
256 | + describe "Project should be public" do | ||
257 | + subject { project } | ||
258 | + | ||
259 | + its(:public?) { should be_true } | ||
260 | + end | ||
261 | + | ||
262 | + describe "GET /project_code" do | ||
263 | + subject { project_path(project) } | ||
264 | + | ||
265 | + it { should be_allowed_for master } | ||
266 | + it { should be_allowed_for reporter } | ||
267 | + it { should be_allowed_for admin } | ||
268 | + it { should be_allowed_for guest } | ||
269 | + it { should be_allowed_for :user } | ||
270 | + it { should be_denied_for :visitor } | ||
271 | + end | ||
272 | + | ||
273 | + describe "GET /project_code/tree/master" do | ||
274 | + subject { project_tree_path(project, project.repository.root_ref) } | ||
275 | + | ||
276 | + it { should be_allowed_for master } | ||
277 | + it { should be_allowed_for reporter } | ||
278 | + it { should be_allowed_for :admin } | ||
279 | + it { should be_allowed_for guest } | ||
280 | + it { should be_allowed_for :user } | ||
281 | + it { should be_denied_for :visitor } | ||
282 | + end | ||
283 | + | ||
284 | + describe "GET /project_code/commits/master" do | ||
285 | + subject { project_commits_path(project, project.repository.root_ref, limit: 1) } | ||
286 | + | ||
287 | + it { should be_allowed_for master } | ||
288 | + it { should be_allowed_for reporter } | ||
289 | + it { should be_allowed_for :admin } | ||
290 | + it { should be_allowed_for guest } | ||
291 | + it { should be_allowed_for :user } | ||
292 | + it { should be_denied_for :visitor } | ||
293 | + end | ||
294 | + | ||
295 | + describe "GET /project_code/commit/:sha" do | ||
296 | + subject { project_commit_path(project, project.repository.commit) } | ||
297 | + | ||
298 | + it { should be_allowed_for master } | ||
299 | + it { should be_allowed_for reporter } | ||
300 | + it { should be_allowed_for :admin } | ||
301 | + it { should be_allowed_for guest } | ||
302 | + it { should be_allowed_for :user } | ||
303 | + it { should be_denied_for :visitor } | ||
304 | + end | ||
305 | + | ||
306 | + describe "GET /project_code/compare" do | ||
307 | + subject { project_compare_index_path(project) } | ||
308 | + | ||
309 | + it { should be_allowed_for master } | ||
310 | + it { should be_allowed_for reporter } | ||
311 | + it { should be_allowed_for :admin } | ||
312 | + it { should be_allowed_for guest } | ||
313 | + it { should be_allowed_for :user } | ||
314 | + it { should be_denied_for :visitor } | ||
315 | + end | ||
316 | + | ||
317 | + describe "GET /project_code/team" do | ||
318 | + subject { project_team_index_path(project) } | ||
319 | + | ||
320 | + it { should be_allowed_for master } | ||
321 | + it { should be_allowed_for reporter } | ||
322 | + it { should be_allowed_for :admin } | ||
323 | + it { should be_allowed_for guest } | ||
324 | + it { should be_allowed_for :user } | ||
325 | + it { should be_denied_for :visitor } | ||
326 | + end | ||
327 | + | ||
328 | + describe "GET /project_code/wall" do | ||
329 | + subject { project_wall_path(project) } | ||
330 | + | ||
331 | + it { should be_allowed_for master } | ||
332 | + it { should be_allowed_for reporter } | ||
333 | + it { should be_allowed_for :admin } | ||
334 | + it { should be_allowed_for guest } | ||
335 | + it { should be_allowed_for :user } | ||
336 | + it { should be_denied_for :visitor } | ||
337 | + end | ||
338 | + | ||
339 | + describe "GET /project_code/blob" do | ||
340 | + before do | ||
341 | + commit = project.repository.commit | ||
342 | + path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name | ||
343 | + @blob_path = project_blob_path(project, File.join(commit.id, path)) | ||
344 | + end | ||
345 | + | ||
346 | + it { @blob_path.should be_allowed_for master } | ||
347 | + it { @blob_path.should be_allowed_for reporter } | ||
348 | + it { @blob_path.should be_allowed_for :admin } | ||
349 | + it { @blob_path.should be_allowed_for guest } | ||
350 | + it { @blob_path.should be_allowed_for :user } | ||
351 | + it { @blob_path.should be_denied_for :visitor } | ||
352 | + end | ||
353 | + | ||
354 | + describe "GET /project_code/edit" do | ||
355 | + subject { edit_project_path(project) } | ||
356 | + | ||
357 | + it { should be_allowed_for master } | ||
358 | + it { should be_denied_for reporter } | ||
359 | + it { should be_allowed_for :admin } | ||
360 | + it { should be_denied_for guest } | ||
361 | + it { should be_denied_for :user } | ||
362 | + it { should be_denied_for :visitor } | ||
363 | + end | ||
364 | + | ||
365 | + describe "GET /project_code/deploy_keys" do | ||
366 | + subject { project_deploy_keys_path(project) } | ||
367 | + | ||
368 | + it { should be_allowed_for master } | ||
369 | + it { should be_denied_for reporter } | ||
370 | + it { should be_allowed_for :admin } | ||
371 | + it { should be_denied_for guest } | ||
372 | + it { should be_denied_for :user } | ||
373 | + it { should be_denied_for :visitor } | ||
374 | + end | ||
375 | + | ||
376 | + describe "GET /project_code/issues" do | ||
377 | + subject { project_issues_path(project) } | ||
378 | + | ||
379 | + it { should be_allowed_for master } | ||
380 | + it { should be_allowed_for reporter } | ||
381 | + it { should be_allowed_for :admin } | ||
382 | + it { should be_allowed_for guest } | ||
383 | + it { should be_allowed_for :user } | ||
384 | + it { should be_denied_for :visitor } | ||
385 | + end | ||
386 | + | ||
387 | + describe "GET /project_code/snippets" do | ||
388 | + subject { project_snippets_path(project) } | ||
389 | + | ||
390 | + it { should be_allowed_for master } | ||
391 | + it { should be_allowed_for reporter } | ||
392 | + it { should be_allowed_for :admin } | ||
393 | + it { should be_allowed_for guest } | ||
394 | + it { should be_allowed_for :user } | ||
395 | + it { should be_denied_for :visitor } | ||
396 | + end | ||
397 | + | ||
398 | + describe "GET /project_code/snippets/new" do | ||
399 | + subject { new_project_snippet_path(project) } | ||
400 | + | ||
401 | + it { should be_allowed_for master } | ||
402 | + it { should be_allowed_for reporter } | ||
403 | + it { should be_allowed_for :admin } | ||
404 | + it { should be_denied_for guest } | ||
405 | + it { should be_denied_for :user } | ||
406 | + it { should be_denied_for :visitor } | ||
407 | + end | ||
408 | + | ||
409 | + describe "GET /project_code/merge_requests" do | ||
410 | + subject { project_merge_requests_path(project) } | ||
411 | + | ||
412 | + it { should be_allowed_for master } | ||
413 | + it { should be_allowed_for reporter } | ||
414 | + it { should be_allowed_for :admin } | ||
415 | + it { should be_allowed_for guest } | ||
416 | + it { should be_allowed_for :user } | ||
417 | + it { should be_denied_for :visitor } | ||
418 | + end | ||
419 | + | ||
420 | + describe "GET /project_code/repository" do | ||
421 | + subject { project_repository_path(project) } | ||
422 | + | ||
423 | + it { should be_allowed_for master } | ||
424 | + it { should be_allowed_for reporter } | ||
425 | + it { should be_allowed_for :admin } | ||
426 | + it { should be_allowed_for guest } | ||
427 | + it { should be_allowed_for :user } | ||
428 | + it { should be_denied_for :visitor } | ||
429 | + end | ||
430 | + | ||
431 | + describe "GET /project_code/repository/branches" do | ||
432 | + subject { branches_project_repository_path(project) } | ||
433 | + | ||
434 | + before do | ||
435 | + # Speed increase | ||
436 | + Project.any_instance.stub(:branches).and_return([]) | ||
437 | + end | ||
438 | + | ||
439 | + it { should be_allowed_for master } | ||
440 | + it { should be_allowed_for reporter } | ||
441 | + it { should be_allowed_for :admin } | ||
442 | + it { should be_allowed_for guest } | ||
443 | + it { should be_allowed_for :user } | ||
444 | + it { should be_denied_for :visitor } | ||
445 | + end | ||
446 | + | ||
447 | + describe "GET /project_code/repository/tags" do | ||
448 | + subject { tags_project_repository_path(project) } | ||
449 | + | ||
450 | + before do | ||
451 | + # Speed increase | ||
452 | + Project.any_instance.stub(:tags).and_return([]) | ||
453 | + end | ||
454 | + | ||
455 | + it { should be_allowed_for master } | ||
456 | + it { should be_allowed_for reporter } | ||
457 | + it { should be_allowed_for :admin } | ||
458 | + it { should be_allowed_for guest } | ||
459 | + it { should be_allowed_for :user } | ||
460 | + it { should be_denied_for :visitor } | ||
461 | + end | ||
462 | + | ||
463 | + describe "GET /project_code/hooks" do | ||
464 | + subject { project_hooks_path(project) } | ||
465 | + | ||
466 | + it { should be_allowed_for master } | ||
467 | + it { should be_allowed_for reporter } | ||
468 | + it { should be_allowed_for :admin } | ||
469 | + it { should be_allowed_for guest } | ||
470 | + it { should be_allowed_for :user } | ||
471 | + it { should be_denied_for :visitor } | ||
472 | + end | ||
473 | + end | ||
232 | end | 474 | end |