summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/models/ability.rb2
-rw-r--r--app/views/projects/_form.html.haml4
-rw-r--r--app/views/public/projects/index.html.haml5
-rw-r--r--features/project/public_projects.feature8
-rw-r--r--features/steps/project/public_projects.rb9
-rw-r--r--features/steps/shared/paths.rb8
-rw-r--r--spec/features/security/project_access_spec.rb242
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