diff options
-rw-r--r-- | app/controllers/application_controller.rb | 2 | ||||
-rw-r--r-- | app/models/ability.rb | 2 | ||||
-rw-r--r-- | app/views/projects/_form.html.haml | 4 | ||||
-rw-r--r-- | app/views/public/projects/index.html.haml | 5 | ||||
-rw-r--r-- | features/project/public_projects.feature | 8 | ||||
-rw-r--r-- | features/steps/project/public_projects.rb | 9 | ||||
-rw-r--r-- | features/steps/shared/paths.rb | 8 | ||||
-rw-r--r-- | spec/features/security/project_access_spec.rb | 242 |
8 files changed, 276 insertions, 4 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 22fe5abacb3..a6a887fa939 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -88,7 +88,7 @@ class ApplicationController < ActionController::Base end def authorize_code_access! - return access_denied! unless can?(current_user, :download_code, project) + return access_denied! unless can?(current_user, :download_code, project) or project.public? end def authorize_create_team! diff --git a/app/models/ability.rb b/app/models/ability.rb index eb7f89dcfc1..cad5a832978 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -37,7 +37,7 @@ class Ability elsif team.reporters.include?(user) rules << project_report_rules - elsif team.guests.include?(user) + elsif team.guests.include?(user) or project.public? rules << project_guest_rules end diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index 4d635e3dc68..0e1fd238005 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -48,7 +48,7 @@ Public mode: .control-group = f.label :public, class: 'control-label' do - %span Public clone access + %span Public access .controls = f.check_box :public %span.descr @@ -56,6 +56,8 @@ %em without any authentication. It will also be listed on the #{link_to "public access directory", public_root_path}. + %em Any + user will have #{link_to "Guest", help_permissions_path} permissions on the repository. %fieldset.features %legend diff --git a/app/views/public/projects/index.html.haml b/app/views/public/projects/index.html.haml index 3d0d793b2d2..c31fcfd15de 100644 --- a/app/views/public/projects/index.html.haml +++ b/app/views/public/projects/index.html.haml @@ -9,7 +9,10 @@ %li.clearfix %h5 %i.icon-share - = project.name_with_namespace + - if current_user + = link_to_project project + - else + = project.name_with_namespace .pull-right %pre.dark.tiny git clone #{project.http_url_to_repo} %p.description diff --git a/features/project/public_projects.feature b/features/project/public_projects.feature new file mode 100644 index 00000000000..c5a9da14c54 --- /dev/null +++ b/features/project/public_projects.feature @@ -0,0 +1,8 @@ +Feature: Public Projects + Background: + Given I sign in as a user + + Scenario: I should see the list of public projects + When I visit the public projects area + Then I should see the list of public projects + diff --git a/features/steps/project/public_projects.rb b/features/steps/project/public_projects.rb new file mode 100644 index 00000000000..7063e7d56ae --- /dev/null +++ b/features/steps/project/public_projects.rb @@ -0,0 +1,9 @@ +class PublicProjects < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Then 'I should see the list of public projects' do + page.should have_content "Public Projects" + end +end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 27ca65b22dd..38730cc2cd6 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -263,6 +263,14 @@ module SharedPaths visit project_wiki_path(@project, :home) end + # ---------------------------------------- + # Public Projects + # ---------------------------------------- + + Given 'I visit the public projects area' do + visit public_root_path + end + def root_ref @project.repository.root_ref end diff --git a/spec/features/security/project_access_spec.rb b/spec/features/security/project_access_spec.rb index cfbb8f135ab..8c65af061e0 100644 --- a/spec/features/security/project_access_spec.rb +++ b/spec/features/security/project_access_spec.rb @@ -229,4 +229,246 @@ describe "Application access" do it { should be_denied_for :visitor } end end + + + describe "PublicProject" do + let(:project) { create(:project_with_code) } + + let(:master) { create(:user) } + let(:guest) { create(:user) } + let(:reporter) { create(:user) } + + let(:admin) { create(:user) } + + before do + # public project + project.public = true + project.save! + + # full access + project.team << [master, :master] + + # readonly + project.team << [reporter, :reporter] + + end + + describe "Project should be public" do + subject { project } + + its(:public?) { should be_true } + end + + describe "GET /project_code" do + subject { project_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/tree/master" do + subject { project_tree_path(project, project.repository.root_ref) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/commits/master" do + subject { project_commits_path(project, project.repository.root_ref, limit: 1) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/commit/:sha" do + subject { project_commit_path(project, project.repository.commit) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/compare" do + subject { project_compare_index_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/team" do + subject { project_team_index_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/wall" do + subject { project_wall_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/blob" do + before do + commit = project.repository.commit + path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name + @blob_path = project_blob_path(project, File.join(commit.id, path)) + end + + it { @blob_path.should be_allowed_for master } + it { @blob_path.should be_allowed_for reporter } + it { @blob_path.should be_allowed_for :admin } + it { @blob_path.should be_allowed_for guest } + it { @blob_path.should be_allowed_for :user } + it { @blob_path.should be_denied_for :visitor } + end + + describe "GET /project_code/edit" do + subject { edit_project_path(project) } + + it { should be_allowed_for master } + it { should be_denied_for reporter } + it { should be_allowed_for :admin } + it { should be_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/deploy_keys" do + subject { project_deploy_keys_path(project) } + + it { should be_allowed_for master } + it { should be_denied_for reporter } + it { should be_allowed_for :admin } + it { should be_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/issues" do + subject { project_issues_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/snippets" do + subject { project_snippets_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/snippets/new" do + subject { new_project_snippet_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/merge_requests" do + subject { project_merge_requests_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/repository" do + subject { project_repository_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/repository/branches" do + subject { branches_project_repository_path(project) } + + before do + # Speed increase + Project.any_instance.stub(:branches).and_return([]) + end + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/repository/tags" do + subject { tags_project_repository_path(project) } + + before do + # Speed increase + Project.any_instance.stub(:tags).and_return([]) + end + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /project_code/hooks" do + subject { project_hooks_path(project) } + + it { should be_allowed_for master } + it { should be_allowed_for reporter } + it { should be_allowed_for :admin } + it { should be_allowed_for guest } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + end end |