Commit 4c44c5ef authored by Stephen Lottermoser's avatar Stephen Lottermoser Committed by Stephen Lottermoser

Internally public projects

Public projects listed in the public section will be linked to the
actual project's page. Public projects now give any user Guest
permissions to the project, allowing them to download the code, read
and create issues, and view anything else in the project's pages.

Ample access tests have been added to the project_access_spec to
verify correct permissions and behavior on public projects.
- Visitors to the site who are not logged in still cannot view the
  project's pages.
- Logged-in users visiting a public project where they are not a team
  member can create issues, but not snippets. They can view the projects
  code, issues, merge requests, etc, just as if they were a Guest member
  of the project.
- Since this is a public project, the user is also granted :download_code
  permissions, a permission normally reserved for Reporters, since they
  can clone the repo anyways and browse commits and branches locally.
parent 4f5aae1d
......@@ -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!
......
......@@ -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
......
......@@ -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
......
......@@ -9,7 +9,7 @@
%li.clearfix
%h5
%i.icon-share
= project.name_with_namespace
= link_to_project project
.pull-right
%pre.dark.tiny git clone #{project.http_url_to_repo}
%p.description
......
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
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
......@@ -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
......
......@@ -229,4 +229,246 @@ describe "Application access" do
it { should be_denied_for :visitor }
end
end
describe "PublicProject" do
let(:project) { create(:project) }
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_denied_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_denied_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_denied_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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment