Commit 2fc236177f70244101b285bde8ee6a77f779c0ce

Authored by Dmitriy Zaporozhets
2 parents f40d4e66 8589f0f4

Merge pull request #3801 from holdtotherod/feature/internally-public-projects

Internally public projects
app/controllers/application_controller.rb
... ... @@ -88,7 +88,7 @@ class ApplicationController < ActionController::Base
88 88 end
89 89  
90 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 92 end
93 93  
94 94 def authorize_create_team!
... ...
app/models/ability.rb
... ... @@ -37,7 +37,7 @@ class Ability
37 37 elsif team.reporters.include?(user)
38 38 rules << project_report_rules
39 39  
40   - elsif team.guests.include?(user)
  40 + elsif team.guests.include?(user) or project.public?
41 41 rules << project_guest_rules
42 42 end
43 43  
... ...
app/views/projects/_form.html.haml
... ... @@ -48,7 +48,7 @@
48 48 Public mode:
49 49 .control-group
50 50 = f.label :public, class: 'control-label' do
51   - %span Public clone access
  51 + %span Public access
52 52 .controls
53 53 = f.check_box :public
54 54 %span.descr
... ... @@ -56,6 +56,8 @@
56 56 %em without any
57 57 authentication.
58 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 62 %fieldset.features
61 63 %legend
... ...
app/views/public/projects/index.html.haml
... ... @@ -9,7 +9,10 @@
9 9 %li.clearfix
10 10 %h5
11 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 16 .pull-right
14 17 %pre.dark.tiny git clone #{project.http_url_to_repo}
15 18 %p.description
... ...
features/project/public_projects.feature 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +Feature: Public Projects
  2 + Background:
  3 + Given I sign in as a user
  4 +
  5 + Scenario: I should see the list of public projects
  6 + When I visit the public projects area
  7 + Then I should see the list of public projects
  8 +
... ...
features/steps/project/public_projects.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class PublicProjects < Spinach::FeatureSteps
  2 + include SharedAuthentication
  3 + include SharedProject
  4 + include SharedPaths
  5 +
  6 + Then 'I should see the list of public projects' do
  7 + page.should have_content "Public Projects"
  8 + end
  9 +end
... ...
features/steps/shared/paths.rb
... ... @@ -263,6 +263,14 @@ module SharedPaths
263 263 visit project_wiki_path(@project, :home)
264 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 274 def root_ref
267 275 @project.repository.root_ref
268 276 end
... ...
spec/features/security/project_access_spec.rb
... ... @@ -229,4 +229,246 @@ describe &quot;Application access&quot; do
229 229 it { should be_denied_for :visitor }
230 230 end
231 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 474 end
... ...