Commit f1fd47875c19bf4bd9b5bbd2975f99209f1c282e

Authored by Dmitriy Zaporozhets
2 parents a3c80673 e8292e73

Merge branch 'epic/public_projects' of /home/git/repositories/gitlab/gitlabhq

Showing 38 changed files with 871 additions and 674 deletions   Show diff stats
  1 +v 6.2.0
  2 + - Public projects are visible from the outside
  3 +
1 v 6.1.0 4 v 6.1.0
2 - Project specific IDs for issues, mr, milestones 5 - Project specific IDs for issues, mr, milestones
3 Above items will get a new id and for example all bookmarked issue urls will change. 6 Above items will get a new id and for example all bookmarked issue urls will change.
1 -6.1.0 1 +6.2.0.pre
app/assets/images/login-logo.png

9.97 KB

app/assets/stylesheets/common.scss
@@ -382,3 +382,8 @@ table { @@ -382,3 +382,8 @@ table {
382 width: 50px; 382 width: 50px;
383 min-height: 100px; 383 min-height: 100px;
384 } 384 }
  385 +
  386 +.navbar-gitlab .navbar-inner .nav > li .btn-sign-in {
  387 + @extend .btn-new;
  388 + padding: 5px 15px;
  389 +}
app/assets/stylesheets/sections/login.scss
1 /* Login Page */ 1 /* Login Page */
2 body.login-page{ 2 body.login-page{
3 - background: #474D57;  
4 - .container .content { padding-top: 4%; } 3 + .container > .content {
  4 + padding-top: 20px;
  5 + }
5 } 6 }
6 7
7 .login-box{ 8 .login-box{
app/assets/stylesheets/sections/projects.scss
@@ -79,21 +79,6 @@ ul.nav.nav-projects-tabs { @@ -79,21 +79,6 @@ ul.nav.nav-projects-tabs {
79 margin: 0px; 79 margin: 0px;
80 } 80 }
81 81
82 -.public-projects {  
83 - li {  
84 - .project-title {  
85 - font-size: 14px;  
86 - line-height: 2;  
87 - font-weight: normal;  
88 - }  
89 -  
90 - .description {  
91 - margin-left: 15px;  
92 - color: #aaa;  
93 - }  
94 - }  
95 -}  
96 -  
97 .my-projects { 82 .my-projects {
98 li { 83 li {
99 .project-title { 84 .project-title {
@@ -110,7 +95,6 @@ ul.nav.nav-projects-tabs { @@ -110,7 +95,6 @@ ul.nav.nav-projects-tabs {
110 } 95 }
111 } 96 }
112 97
113 -  
114 .public-clone { 98 .public-clone {
115 background: #333; 99 background: #333;
116 color: #f5f5f5; 100 color: #f5f5f5;
@@ -123,3 +107,11 @@ ul.nav.nav-projects-tabs { @@ -123,3 +107,11 @@ ul.nav.nav-projects-tabs {
123 position: relative; 107 position: relative;
124 top: -5px; 108 top: -5px;
125 } 109 }
  110 +
  111 +.public-projects .repo-info {
  112 + color: #777;
  113 +
  114 + a {
  115 + color: #777;
  116 + }
  117 +}
app/controllers/profiles_controller.rb
@@ -33,8 +33,8 @@ class ProfilesController < ApplicationController @@ -33,8 +33,8 @@ class ProfilesController < ApplicationController
33 end 33 end
34 34
35 def update_password 35 def update_password
36 - params[:user].select! do |key, value|  
37 - %w(current_password password password_confirmation).include?(key.to_s) 36 + password_attributes = params[:user].select do |key, value|
  37 + %w(password password_confirmation).include?(key.to_s)
38 end 38 end
39 39
40 unless @user.valid_password?(params[:user][:current_password]) 40 unless @user.valid_password?(params[:user][:current_password])
@@ -42,7 +42,7 @@ class ProfilesController < ApplicationController @@ -42,7 +42,7 @@ class ProfilesController < ApplicationController
42 return 42 return
43 end 43 end
44 44
45 - if @user.update_attributes(params[:user]) 45 + if @user.update_attributes(password_attributes)
46 flash[:notice] = "Password was successfully updated. Please login with it" 46 flash[:notice] = "Password was successfully updated. Please login with it"
47 redirect_to new_user_session_path 47 redirect_to new_user_session_path
48 else 48 else
app/controllers/projects/application_controller.rb
1 class Projects::ApplicationController < ApplicationController 1 class Projects::ApplicationController < ApplicationController
2 before_filter :project 2 before_filter :project
3 before_filter :repository 3 before_filter :repository
4 - layout 'projects' 4 + layout :determine_layout
  5 +
  6 + def authenticate_user!
  7 + # Restrict access to Projects area only
  8 + # for non-signed users
  9 + if !current_user
  10 + id = params[:project_id] || params[:id]
  11 + @project = Project.find_with_namespace(id)
  12 +
  13 + return if @project && @project.public
  14 + end
  15 +
  16 + super
  17 + end
  18 +
  19 + def determine_layout
  20 + if current_user
  21 + 'projects'
  22 + else
  23 + 'public_projects'
  24 + end
  25 + end
5 end 26 end
app/controllers/projects/hooks_controller.rb
1 class Projects::HooksController < Projects::ApplicationController 1 class Projects::HooksController < Projects::ApplicationController
2 # Authorize 2 # Authorize
3 - before_filter :authorize_read_project!  
4 - before_filter :authorize_admin_project!, only: [:new, :create, :destroy] 3 + before_filter :authorize_admin_project!
5 4
6 respond_to :html 5 respond_to :html
7 6
app/controllers/projects/snippets_controller.rb
@@ -14,8 +14,6 @@ class Projects::SnippetsController &lt; Projects::ApplicationController @@ -14,8 +14,6 @@ class Projects::SnippetsController &lt; Projects::ApplicationController
14 # Allow destroy snippet 14 # Allow destroy snippet
15 before_filter :authorize_admin_project_snippet!, only: [:destroy] 15 before_filter :authorize_admin_project_snippet!, only: [:destroy]
16 16
17 - layout 'projects'  
18 -  
19 respond_to :html 17 respond_to :html
20 18
21 def index 19 def index
app/controllers/projects/team_members_controller.rb
1 class Projects::TeamMembersController < Projects::ApplicationController 1 class Projects::TeamMembersController < Projects::ApplicationController
2 # Authorize 2 # Authorize
3 - before_filter :authorize_read_project!  
4 - before_filter :authorize_admin_project!, except: [:index, :show] 3 + before_filter :authorize_admin_project!
5 4
6 layout "project_settings" 5 layout "project_settings"
7 6
app/controllers/projects_controller.rb
1 -class ProjectsController < Projects::ApplicationController  
2 - skip_before_filter :project, only: [:new, :create]  
3 - skip_before_filter :repository, only: [:new, :create] 1 +class ProjectsController < ApplicationController
  2 + skip_before_filter :authenticate_user!, only: [:show]
  3 + before_filter :project, except: [:new, :create]
  4 + before_filter :repository, except: [:new, :create]
4 5
5 # Authorize 6 # Authorize
6 before_filter :authorize_read_project!, except: [:index, :new, :create] 7 before_filter :authorize_read_project!, except: [:index, :new, :create]
@@ -54,8 +55,9 @@ class ProjectsController &lt; Projects::ApplicationController @@ -54,8 +55,9 @@ class ProjectsController &lt; Projects::ApplicationController
54 end 55 end
55 56
56 def show 57 def show
57 - limit = (params[:limit] || 20).to_i 58 + return authenticate_user! unless @project.public || current_user
58 59
  60 + limit = (params[:limit] || 20).to_i
59 @events = @project.events.recent 61 @events = @project.events.recent
60 @events = event_filter.apply_filter(@events) 62 @events = event_filter.apply_filter(@events)
61 @events = @events.limit(limit).offset(params[:offset] || 0) 63 @events = @events.limit(limit).offset(params[:offset] || 0)
@@ -67,10 +69,12 @@ class ProjectsController &lt; Projects::ApplicationController @@ -67,10 +69,12 @@ class ProjectsController &lt; Projects::ApplicationController
67 respond_to do |format| 69 respond_to do |format|
68 format.html do 70 format.html do
69 if @project.empty_repo? 71 if @project.empty_repo?
70 - render "projects/empty" 72 + render "projects/empty", layout: user_layout
71 else 73 else
72 - @last_push = current_user.recent_push(@project.id)  
73 - render :show 74 + if current_user
  75 + @last_push = current_user.recent_push(@project.id)
  76 + end
  77 + render :show, layout: user_layout
74 end 78 end
75 end 79 end
76 format.js 80 format.js
@@ -121,4 +125,8 @@ class ProjectsController &lt; Projects::ApplicationController @@ -121,4 +125,8 @@ class ProjectsController &lt; Projects::ApplicationController
121 def set_title 125 def set_title
122 @title = 'New Project' 126 @title = 'New Project'
123 end 127 end
  128 +
  129 + def user_layout
  130 + current_user ? "projects" : "public_projects"
  131 + end
124 end 132 end
app/controllers/public/projects_controller.rb
@@ -10,17 +10,4 @@ class Public::ProjectsController &lt; ApplicationController @@ -10,17 +10,4 @@ class Public::ProjectsController &lt; ApplicationController
10 @projects = @projects.search(params[:search]) if params[:search].present? 10 @projects = @projects.search(params[:search]) if params[:search].present?
11 @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20) 11 @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
12 end 12 end
13 -  
14 - def show  
15 - @project = Project.public_only.find_with_namespace(params[:id])  
16 - render_404 and return unless @project  
17 -  
18 - @repository = @project.repository  
19 - unless @project.empty_repo?  
20 - @recent_tags = @repository.tags.first(10)  
21 -  
22 - @commit = @repository.commit(params[:ref])  
23 - @tree = Tree.new(@repository, @commit.id)  
24 - end  
25 - end  
26 end 13 end
app/helpers/application_helper.rb
@@ -90,6 +90,8 @@ module ApplicationHelper @@ -90,6 +90,8 @@ module ApplicationHelper
90 end 90 end
91 91
92 def search_autocomplete_source 92 def search_autocomplete_source
  93 + return unless current_user
  94 +
93 projects = current_user.authorized_projects.map { |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } } 95 projects = current_user.authorized_projects.map { |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } }
94 groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } } 96 groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } }
95 97
app/helpers/projects_helper.rb
@@ -103,4 +103,20 @@ module ProjectsHelper @@ -103,4 +103,20 @@ module ProjectsHelper
103 103
104 nav_tabs.flatten 104 nav_tabs.flatten
105 end 105 end
  106 +
  107 + def git_user_name
  108 + if current_user
  109 + current_user.name
  110 + else
  111 + "Your name"
  112 + end
  113 + end
  114 +
  115 + def git_user_email
  116 + if current_user
  117 + current_user.email
  118 + else
  119 + "your@email.com"
  120 + end
  121 + end
106 end 122 end
app/models/ability.rb
1 class Ability 1 class Ability
2 class << self 2 class << self
3 def allowed(user, subject) 3 def allowed(user, subject)
  4 + return not_auth_abilities(user, subject) if user.nil?
4 return [] unless user.kind_of?(User) 5 return [] unless user.kind_of?(User)
5 return [] if user.blocked? 6 return [] if user.blocked?
6 7
@@ -17,6 +18,34 @@ class Ability @@ -17,6 +18,34 @@ class Ability
17 end.concat(global_abilities(user)) 18 end.concat(global_abilities(user))
18 end 19 end
19 20
  21 + # List of possible abilities
  22 + # for non-authenticated user
  23 + def not_auth_abilities(user, subject)
  24 + project = if subject.kind_of?(Project)
  25 + subject
  26 + elsif subject.respond_to?(:project)
  27 + subject.project
  28 + else
  29 + nil
  30 + end
  31 +
  32 + if project && project.public
  33 + [
  34 + :read_project,
  35 + :read_wiki,
  36 + :read_issue,
  37 + :read_milestone,
  38 + :read_project_snippet,
  39 + :read_team_member,
  40 + :read_merge_request,
  41 + :read_note,
  42 + :download_code
  43 + ]
  44 + else
  45 + []
  46 + end
  47 + end
  48 +
20 def global_abilities(user) 49 def global_abilities(user)
21 rules = [] 50 rules = []
22 rules << :create_group if user.can_create_group 51 rules << :create_group if user.can_create_group
@@ -58,19 +87,9 @@ class Ability @@ -58,19 +87,9 @@ class Ability
58 end 87 end
59 88
60 def public_project_rules 89 def public_project_rules
61 - [ 90 + project_guest_rules + [
62 :download_code, 91 :download_code,
63 :fork_project, 92 :fork_project,
64 - :read_project,  
65 - :read_wiki,  
66 - :read_issue,  
67 - :read_milestone,  
68 - :read_project_snippet,  
69 - :read_team_member,  
70 - :read_merge_request,  
71 - :read_note,  
72 - :write_issue,  
73 - :write_note  
74 ] 93 ]
75 end 94 end
76 95
@@ -135,7 +154,7 @@ class Ability @@ -135,7 +154,7 @@ class Ability
135 def group_abilities user, group 154 def group_abilities user, group
136 rules = [] 155 rules = []
137 156
138 - if group.users.include?(user) 157 + if group.users.include?(user) || user.admin?
139 rules << :read_group 158 rules << :read_group
140 end 159 end
141 160
app/models/group.rb
@@ -32,6 +32,10 @@ class Group &lt; Namespace @@ -32,6 +32,10 @@ class Group &lt; Namespace
32 end 32 end
33 end 33 end
34 34
  35 + def add_user(user, group_access)
  36 + self.users_groups.create(user_id: user.id, group_access: group_access)
  37 + end
  38 +
35 def change_owner(user) 39 def change_owner(user)
36 self.owner = user 40 self.owner = user
37 membership = users_groups.where(user_id: user.id).first 41 membership = users_groups.where(user_id: user.id).first
app/views/layouts/_public_head_panel.html.haml 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +%header.navbar.navbar-static-top.navbar-gitlab
  2 + .navbar-inner
  3 + .container
  4 + %div.app_logo
  5 + %span.separator
  6 + = link_to public_root_path, class: "home" do
  7 + %h1 GITLAB
  8 + %span.separator
  9 + %h1.project_name
  10 + - if @project
  11 + = project_title(@project)
  12 + - else
  13 + Public Projects
  14 +
  15 + %ul.nav
  16 + %li
  17 + %a
  18 + %div.hide.turbolink-spinner
  19 + %i.icon-refresh.icon-spin
  20 + Loading...
  21 + %li
  22 + = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in'
app/views/layouts/devise.html.haml
@@ -6,5 +6,10 @@ @@ -6,5 +6,10 @@
6 .container 6 .container
7 .content 7 .content
8 %center 8 %center
9 - = image_tag image_path "login-logo.png" 9 + %h1 GitLab
  10 + %p.light
  11 + GitLab is open source software to collaborate on code.
  12 + %br
  13 + #{link_to "Sign in", new_user_session_path} or browse for #{link_to "public projects", public_projects_path}.
  14 + %hr
10 = yield 15 = yield
app/views/layouts/public.html.haml
1 !!! 5 1 !!! 5
2 %html{ lang: "en"} 2 %html{ lang: "en"}
3 = render "layouts/head", title: "Public Projects" 3 = render "layouts/head", title: "Public Projects"
4 - %body{class: "#{app_theme} application", :'data-page' => body_data_page} 4 + %body{class: "ui_mars application", :'data-page' => body_data_page}
5 - if current_user 5 - if current_user
6 = render "layouts/head_panel", title: "Public Projects" 6 = render "layouts/head_panel", title: "Public Projects"
7 - else 7 - else
8 - %header.navbar.navbar-static-top.navbar-gitlab  
9 - .navbar-inner  
10 - .container  
11 - %div.app_logo  
12 - %span.separator  
13 - = link_to public_root_path, class: "home" do  
14 - %h1 GITLAB  
15 - %span.separator  
16 - %h1.project_name Public Projects  
17 - %ul.nav  
18 - %li  
19 - %a  
20 - %div.hide.turbolink-spinner  
21 - %i.icon-refresh.icon-spin  
22 - Loading...  
23 - %li  
24 - = link_to "Sign in", new_session_path(:user) 8 + = render "layouts/public_head_panel"
25 9
26 .container.navless-container 10 .container.navless-container
27 - .content  
28 - = yield 11 + .content= yield
app/views/layouts/public_projects.html.haml 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +!!! 5
  2 +%html{ lang: "en"}
  3 + = render "layouts/head", title: @project.name_with_namespace
  4 + %body{class: "ui_mars application", :'data-page' => body_data_page}
  5 + = render "layouts/public_head_panel"
  6 + %nav.main-nav
  7 + .container= render 'layouts/nav/project'
  8 + .container
  9 + .content= yield
app/views/projects/_clone_panel.html.haml
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 .span3.pull-right 5 .span3.pull-right
6 .pull-right 6 .pull-right
7 - unless @project.empty_repo? 7 - unless @project.empty_repo?
8 - - if can?(current_user, :fork_project, @project) && @project.namespace != current_user.namespace 8 + - if current_user && can?(current_user, :fork_project, @project) && @project.namespace != current_user.namespace
9 - if current_user.already_forked?(@project) 9 - if current_user.already_forked?(@project)
10 = link_to project_path(current_user.fork_of(@project)), class: 'btn grouped disabled' do 10 = link_to project_path(current_user.fork_of(@project)), class: 'btn grouped disabled' do
11 %i.icon-code-fork 11 %i.icon-code-fork
@@ -19,37 +19,38 @@ @@ -19,37 +19,38 @@
19 %i.icon-download-alt 19 %i.icon-download-alt
20 %span.only-wide Download 20 %span.only-wide Download
21 21
22 - .dropdown.pull-right  
23 - %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}  
24 - %i.icon-plus-sign-alt  
25 - %span.only-wide New  
26 - %b.caret  
27 - %ul.dropdown-menu  
28 - - if @project.issues_enabled && can?(current_user, :write_issue, @project)  
29 - %li  
30 - = link_to url_for_new_issue, title: "New Issue" do  
31 - Issue  
32 - - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project)  
33 - %li  
34 - = link_to new_project_merge_request_path(@project), title: "New Merge Request" do  
35 - Merge Request  
36 - - if @project.snippets_enabled && can?(current_user, :write_snippet, @project)  
37 - %li  
38 - = link_to new_project_snippet_path(@project), title: "New Snippet" do  
39 - Snippet  
40 - - if can? current_user, :push_code, @project  
41 - %li.divider  
42 - %li  
43 - = link_to new_project_branch_path(@project) do  
44 - %i.icon-code-fork  
45 - Git branch  
46 - %li  
47 - = link_to new_project_tag_path(@project) do  
48 - %i.icon-tag  
49 - Git tag 22 + - if current_user
  23 + .dropdown.pull-right
  24 + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
  25 + %i.icon-plus-sign-alt
  26 + %span.only-wide New
  27 + %b.caret
  28 + %ul.dropdown-menu
  29 + - if @project.issues_enabled && can?(current_user, :write_issue, @project)
  30 + %li
  31 + = link_to url_for_new_issue, title: "New Issue" do
  32 + Issue
  33 + - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project)
  34 + %li
  35 + = link_to new_project_merge_request_path(@project), title: "New Merge Request" do
  36 + Merge Request
  37 + - if @project.snippets_enabled && can?(current_user, :write_snippet, @project)
  38 + %li
  39 + = link_to new_project_snippet_path(@project), title: "New Snippet" do
  40 + Snippet
  41 + - if can? current_user, :push_code, @project
  42 + %li.divider
  43 + %li
  44 + = link_to new_project_branch_path(@project) do
  45 + %i.icon-code-fork
  46 + Git branch
  47 + %li
  48 + = link_to new_project_tag_path(@project) do
  49 + %i.icon-tag
  50 + Git tag
50 51
51 - - if can?(current_user, :admin_team_member, @project)  
52 - %li.divider  
53 - %li  
54 - = link_to new_project_team_member_path(@project), title: "New project member" do  
55 - Project member 52 + - if can?(current_user, :admin_team_member, @project)
  53 + %li.divider
  54 + %li
  55 + = link_to new_project_team_member_path(@project), title: "New project member" do
  56 + Project member
app/views/projects/commits/_head.html.haml
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 Stats 21 Stats
22 22
23 23
24 - - if current_controller?(:commits) && current_user.private_token 24 + - if current_user && current_controller?(:commits) && current_user.private_token
25 %li.pull-right 25 %li.pull-right
26 = link_to project_commits_path(@project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed" do 26 = link_to project_commits_path(@project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed" do
27 %i.icon-rss 27 %i.icon-rss
app/views/projects/empty.html.haml
@@ -16,8 +16,8 @@ @@ -16,8 +16,8 @@
16 %legend Git global setup: 16 %legend Git global setup:
17 %pre.dark 17 %pre.dark
18 :preserve 18 :preserve
19 - git config --global user.name "#{current_user.name}"  
20 - git config --global user.email "#{current_user.email}" 19 + git config --global user.name "#{git_user_name}"
  20 + git config --global user.email "#{git_user_email}"
21 21
22 %fieldset 22 %fieldset
23 %legend Create Repository 23 %legend Create Repository
app/views/projects/issues/_head.html.haml
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
5 = link_to 'Milestones', project_milestones_path(@project), class: "tab" 5 = link_to 'Milestones', project_milestones_path(@project), class: "tab"
6 = nav_link(controller: :labels) do 6 = nav_link(controller: :labels) do
7 = link_to 'Labels', project_labels_path(@project), class: "tab" 7 = link_to 'Labels', project_labels_path(@project), class: "tab"
8 - %li.pull-right  
9 - = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do  
10 - %i.icon-rss 8 + - if current_user
  9 + %li.pull-right
  10 + = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do
  11 + %i.icon-rss
app/views/projects/notes/_note.html.haml
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 %i.icon-link 5 %i.icon-link
6 Link here 6 Link here
7 &nbsp; 7 &nbsp;
8 - - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) 8 + - if(note.author_id == current_user.try(:id)) || can?(current_user, :admin_note, @project)
9 = link_to "#", title: "Edit comment", class: "js-note-edit" do 9 = link_to "#", title: "Edit comment", class: "js-note-edit" do
10 %i.icon-edit 10 %i.icon-edit
11 Edit 11 Edit
app/views/public/projects/_tree.html.haml
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -- if tree.readme  
2 - = render "projects/tree/readme", readme: tree.readme  
3 -- else  
4 - .alert  
5 - %h3.nothing_here_message This project does not have README file  
app/views/public/projects/index.html.haml
@@ -2,29 +2,40 @@ @@ -2,29 +2,40 @@
2 .span6 2 .span6
3 %h3.page-title 3 %h3.page-title
4 Projects (#{@projects.total_count}) 4 Projects (#{@projects.total_count})
5 - %small with read-only access 5 + .light
  6 + You can browse public projects in read-only mode until signed in.
  7 +
6 .span6 8 .span6
7 .pull-right 9 .pull-right
8 = form_tag public_projects_path, method: :get, class: 'form-inline' do |f| 10 = form_tag public_projects_path, method: :get, class: 'form-inline' do |f|
9 .search-holder 11 .search-holder
10 - .controls  
11 - = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "span3 search-text-input", id: "projects_search"  
12 - = submit_tag 'Search', class: "btn btn-primary wide"  
13 - 12 + = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "span3 search-text-input", id: "projects_search"
  13 + = submit_tag 'Search', class: "btn btn-primary wide"
  14 +%hr
14 .public-projects 15 .public-projects
15 - %ul.bordered-list 16 + %ul.bordered-list.top-list
16 - @projects.each do |project| 17 - @projects.each do |project|
17 %li 18 %li
18 - .project-title  
19 - %i.icon-share.cgray  
20 - = link_to public_project_path(project) do  
21 - %strong= project.name_with_namespace 19 + %h4
  20 + = link_to project_path(project) do
  21 + = project.name_with_namespace
22 .pull-right 22 .pull-right
23 %pre.public-clone git clone #{project.http_url_to_repo} 23 %pre.public-clone git clone #{project.http_url_to_repo}
24 24
25 - if project.description.present? 25 - if project.description.present?
26 - %div.description 26 + %p
27 = project.description 27 = project.description
  28 +
  29 + .repo-info
  30 + - unless project.empty_repo?
  31 + = link_to pluralize(project.repository.round_commit_count, 'commit'), project_commits_path(project, project.default_branch)
  32 + &middot;
  33 + = link_to pluralize(project.repository.branch_names.count, 'branch'), project_branches_path(project)
  34 + &middot;
  35 + = link_to pluralize(project.repository.tag_names.count, 'tag'), project_tags_path(project)
  36 + - else
  37 + %i.icon-warning-sign
  38 + Empty repository
28 - unless @projects.present? 39 - unless @projects.present?
29 %h3.nothing_here_message No public projects 40 %h3.nothing_here_message No public projects
30 41
app/views/public/projects/show.html.haml
@@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
1 -%h3.page-title  
2 - = @project.name_with_namespace  
3 - .pull-right  
4 - %pre.public-clone git clone #{@project.http_url_to_repo}  
5 - .pull-right  
6 - - if current_user  
7 - = link_to 'Browse project', @project, class: 'btn btn-create append-right-10'  
8 -  
9 -  
10 -%div  
11 - = link_to public_root_path do  
12 - &larr; To projects list  
13 - .pull-right  
14 - %span.light= @project.description  
15 -  
16 -%br  
17 -.row  
18 - - unless @project.empty_repo?  
19 - .span9  
20 - = render 'tree', tree: @tree  
21 - .span3  
22 - %h5 Repository:  
23 - %div  
24 - %p  
25 - %span.light Bare size is  
26 - #{@project.repository.size} MB  
27 -  
28 - %p  
29 - = pluralize(@repository.round_commit_count, 'commit')  
30 - %p  
31 - = pluralize(@repository.branch_names.count, 'branch')  
32 - %p  
33 - = pluralize(@repository.tag_names.count, 'tag')  
34 -  
35 - - if @recent_tags.present?  
36 - %hr  
37 - %h5 Most Recent Tags:  
38 - %ul.unstyled  
39 - - @recent_tags.each do |tag|  
40 - %li  
41 - %p  
42 - %i.icon-tag  
43 - %strong= tag.name  
44 - %small.light.pull-right  
45 - %i.icon-calendar  
46 - = time_ago_in_words(tag.commit.committed_date)  
47 - ago  
48 - - else  
49 - = 'Empty Repository'  
config/routes.rb
@@ -55,8 +55,6 @@ Gitlab::Application.routes.draw do @@ -55,8 +55,6 @@ Gitlab::Application.routes.draw do
55 # 55 #
56 namespace :public do 56 namespace :public do
57 resources :projects, only: [:index] 57 resources :projects, only: [:index]
58 - resources :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }, only: [:show]  
59 -  
60 root to: "projects#index" 58 root to: "projects#index"
61 end 59 end
62 60
features/public/public_projects.feature
@@ -9,11 +9,10 @@ Feature: Public Projects Feature @@ -9,11 +9,10 @@ Feature: Public Projects Feature
9 And I should not see project "Enterprise" 9 And I should not see project "Enterprise"
10 10
11 Scenario: I visit public project page 11 Scenario: I visit public project page
12 - When I visit public page for "Community" project  
13 - Then I should see public project details  
14 - And I should see project readme 12 + When I visit project "Community" page
  13 + Then I should see project "Community" home page
15 14
16 Scenario: I visit an empty public project page 15 Scenario: I visit an empty public project page
17 Given public empty project "Empty Public Project" 16 Given public empty project "Empty Public Project"
18 - When I visit empty public project page  
19 - Then I should see empty public project details  
20 \ No newline at end of file 17 \ No newline at end of file
  18 + When I visit empty project page
  19 + Then I should see empty public project details
features/steps/public/projects_feature.rb
@@ -11,7 +11,6 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps @@ -11,7 +11,6 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps
11 11
12 step 'I should see project "Empty Public Project"' do 12 step 'I should see project "Empty Public Project"' do
13 page.should have_content "Empty Public Project" 13 page.should have_content "Empty Public Project"
14 - puts page.save_page('foo.html')  
15 end 14 end
16 15
17 step 'I should see public project details' do 16 step 'I should see public project details' do
@@ -24,26 +23,35 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps @@ -24,26 +23,35 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps
24 end 23 end
25 24
26 step 'public project "Community"' do 25 step 'public project "Community"' do
27 - create :project_with_code, name: 'Community', public: true 26 + create :project_with_code, name: 'Community', public: true, default_branch: 'master'
28 end 27 end
29 28
30 step 'public empty project "Empty Public Project"' do 29 step 'public empty project "Empty Public Project"' do
31 create :project, name: 'Empty Public Project', public: true 30 create :project, name: 'Empty Public Project', public: true
32 end 31 end
33 32
34 - step 'I visit empty public project page' do 33 + step 'I visit empty project page' do
35 project = Project.find_by_name('Empty Public Project') 34 project = Project.find_by_name('Empty Public Project')
36 - visit public_project_path(project) 35 + visit project_path(project)
  36 + end
  37 +
  38 + step 'I visit project "Community" page' do
  39 + project = Project.find_by_name('Community')
  40 + visit project_path(project)
37 end 41 end
38 42
39 step 'I should see empty public project details' do 43 step 'I should see empty public project details' do
40 - page.should have_content 'Empty Repository' 44 + page.should have_content 'Git global setup'
41 end 45 end
42 46
43 step 'private project "Enterprise"' do 47 step 'private project "Enterprise"' do
44 create :project, name: 'Enterprise' 48 create :project, name: 'Enterprise'
45 end 49 end
46 50
  51 + step 'I should see project "Community" home page' do
  52 + page.should have_content 'Repo size is'
  53 + end
  54 +
47 private 55 private
48 56
49 def project 57 def project
spec/features/security/dashboard_access_spec.rb 0 → 100644
@@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
  1 +require 'spec_helper'
  2 +
  3 +describe "Dashboard access" do
  4 + describe "GET /dashboard" do
  5 + subject { dashboard_path }
  6 +
  7 + it { should be_allowed_for :admin }
  8 + it { should be_allowed_for :user }
  9 + it { should be_denied_for :visitor }
  10 + end
  11 +
  12 + describe "GET /dashboard/issues" do
  13 + subject { issues_dashboard_path }
  14 +
  15 + it { should be_allowed_for :admin }
  16 + it { should be_allowed_for :user }
  17 + it { should be_denied_for :visitor }
  18 + end
  19 +
  20 + describe "GET /dashboard/merge_requests" do
  21 + subject { merge_requests_dashboard_path }
  22 +
  23 + it { should be_allowed_for :admin }
  24 + it { should be_allowed_for :user }
  25 + it { should be_denied_for :visitor }
  26 + end
  27 +
  28 + describe "GET /dashboard/projects" do
  29 + subject { projects_dashboard_path }
  30 +
  31 + it { should be_allowed_for :admin }
  32 + it { should be_allowed_for :user }
  33 + it { should be_denied_for :visitor }
  34 + end
  35 +
  36 + describe "GET /help" do
  37 + subject { help_path }
  38 +
  39 + it { should be_allowed_for :admin }
  40 + it { should be_allowed_for :user }
  41 + it { should be_denied_for :visitor }
  42 + end
  43 +
  44 + describe "GET /projects/new" do
  45 + it { new_project_path.should be_allowed_for :admin }
  46 + it { new_project_path.should be_allowed_for :user }
  47 + it { new_project_path.should be_denied_for :visitor }
  48 + end
  49 +
  50 + describe "GET /groups/new" do
  51 + it { new_group_path.should be_allowed_for :admin }
  52 + it { new_group_path.should be_allowed_for :user }
  53 + it { new_group_path.should be_denied_for :visitor }
  54 + end
  55 +end
spec/features/security/group_access_spec.rb 0 → 100644
@@ -0,0 +1,83 @@ @@ -0,0 +1,83 @@
  1 +require 'spec_helper'
  2 +
  3 +describe "Group access" do
  4 + describe "GET /projects/new" do
  5 + it { new_group_path.should be_allowed_for :admin }
  6 + it { new_group_path.should be_allowed_for :user }
  7 + it { new_group_path.should be_denied_for :visitor }
  8 + end
  9 +
  10 + describe "Group" do
  11 + let(:group) { create(:group) }
  12 +
  13 + let(:master) { create(:user) }
  14 + let(:reporter) { create(:user) }
  15 + let(:guest) { create(:user) }
  16 +
  17 + before do
  18 + group.add_user(master, Gitlab::Access::MASTER)
  19 + group.add_user(reporter, Gitlab::Access::REPORTER)
  20 + group.add_user(guest, Gitlab::Access::GUEST)
  21 + end
  22 +
  23 + describe "GET /groups/:path" do
  24 + subject { group_path(group) }
  25 +
  26 + it { should be_allowed_for group.owner }
  27 + it { should be_allowed_for master }
  28 + it { should be_allowed_for reporter }
  29 + it { should be_allowed_for :admin }
  30 + it { should be_allowed_for guest }
  31 + it { should be_denied_for :user }
  32 + it { should be_denied_for :visitor }
  33 + end
  34 +
  35 + describe "GET /groups/:path/issues" do
  36 + subject { issues_group_path(group) }
  37 +
  38 + it { should be_allowed_for group.owner }
  39 + it { should be_allowed_for master }
  40 + it { should be_allowed_for reporter }
  41 + it { should be_allowed_for :admin }
  42 + it { should be_allowed_for guest }
  43 + it { should be_denied_for :user }
  44 + it { should be_denied_for :visitor }
  45 + end
  46 +
  47 + describe "GET /groups/:path/merge_requests" do
  48 + subject { merge_requests_group_path(group) }
  49 +
  50 + it { should be_allowed_for group.owner }
  51 + it { should be_allowed_for master }
  52 + it { should be_allowed_for reporter }
  53 + it { should be_allowed_for :admin }
  54 + it { should be_allowed_for guest }
  55 + it { should be_denied_for :user }
  56 + it { should be_denied_for :visitor }
  57 + end
  58 +
  59 + describe "GET /groups/:path/members" do
  60 + subject { members_group_path(group) }
  61 +
  62 + it { should be_allowed_for group.owner }
  63 + it { should be_allowed_for master }
  64 + it { should be_allowed_for reporter }
  65 + it { should be_allowed_for :admin }
  66 + it { should be_allowed_for guest }
  67 + it { should be_denied_for :user }
  68 + it { should be_denied_for :visitor }
  69 + end
  70 +
  71 + describe "GET /groups/:path/edit" do
  72 + subject { edit_group_path(group) }
  73 +
  74 + it { should be_allowed_for group.owner }
  75 + it { should be_denied_for master }
  76 + it { should be_denied_for reporter }
  77 + it { should be_allowed_for :admin }
  78 + it { should be_denied_for guest }
  79 + it { should be_denied_for :user }
  80 + it { should be_denied_for :visitor }
  81 + end
  82 + end
  83 +end
spec/features/security/profile_access_spec.rb
@@ -45,5 +45,32 @@ describe &quot;Users Security&quot; do @@ -45,5 +45,32 @@ describe &quot;Users Security&quot; do
45 it { should be_allowed_for :user } 45 it { should be_allowed_for :user }
46 it { should be_denied_for :visitor } 46 it { should be_denied_for :visitor }
47 end 47 end
  48 +
  49 + describe "GET /profile/history" do
  50 + subject { history_profile_path }
  51 +
  52 + it { should be_allowed_for @u1 }
  53 + it { should be_allowed_for :admin }
  54 + it { should be_allowed_for :user }
  55 + it { should be_denied_for :visitor }
  56 + end
  57 +
  58 + describe "GET /profile/notifications" do
  59 + subject { profile_notifications_path }
  60 +
  61 + it { should be_allowed_for @u1 }
  62 + it { should be_allowed_for :admin }
  63 + it { should be_allowed_for :user }
  64 + it { should be_denied_for :visitor }
  65 + end
  66 +
  67 + describe "GET /profile/groups" do
  68 + subject { profile_groups_path }
  69 +
  70 + it { should be_allowed_for @u1 }
  71 + it { should be_allowed_for :admin }
  72 + it { should be_allowed_for :user }
  73 + it { should be_denied_for :visitor }
  74 + end
48 end 75 end
49 end 76 end
spec/features/security/project/private_access_spec.rb 0 → 100644
@@ -0,0 +1,218 @@ @@ -0,0 +1,218 @@
  1 +require 'spec_helper'
  2 +
  3 +describe "Private Project Access" do
  4 + let(:project) { create(:project_with_code) }
  5 +
  6 + let(:master) { create(:user) }
  7 + let(:guest) { create(:user) }
  8 + let(:reporter) { create(:user) }
  9 +
  10 + before do
  11 + # full access
  12 + project.team << [master, :master]
  13 +
  14 + # readonly
  15 + project.team << [reporter, :reporter]
  16 + end
  17 +
  18 + describe "GET /:project_path" do
  19 + subject { project_path(project) }
  20 +
  21 + it { should be_allowed_for master }
  22 + it { should be_allowed_for reporter }
  23 + it { should be_allowed_for :admin }
  24 + it { should be_denied_for guest }
  25 + it { should be_denied_for :user }
  26 + it { should be_denied_for :visitor }
  27 + end
  28 +
  29 + describe "GET /:project_path/tree/master" do
  30 + subject { project_tree_path(project, project.repository.root_ref) }
  31 +
  32 + it { should be_allowed_for master }
  33 + it { should be_allowed_for reporter }
  34 + it { should be_allowed_for :admin }
  35 + it { should be_denied_for guest }
  36 + it { should be_denied_for :user }
  37 + it { should be_denied_for :visitor }
  38 + end
  39 +
  40 + describe "GET /:project_path/commits/master" do
  41 + subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
  42 +
  43 + it { should be_allowed_for master }
  44 + it { should be_allowed_for reporter }
  45 + it { should be_allowed_for :admin }
  46 + it { should be_denied_for guest }
  47 + it { should be_denied_for :user }
  48 + it { should be_denied_for :visitor }
  49 + end
  50 +
  51 + describe "GET /:project_path/commit/:sha" do
  52 + subject { project_commit_path(project, project.repository.commit) }
  53 +
  54 + it { should be_allowed_for master }
  55 + it { should be_allowed_for reporter }
  56 + it { should be_allowed_for :admin }
  57 + it { should be_denied_for guest }
  58 + it { should be_denied_for :user }
  59 + it { should be_denied_for :visitor }
  60 + end
  61 +
  62 + describe "GET /:project_path/compare" do
  63 + subject { project_compare_index_path(project) }
  64 +
  65 + it { should be_allowed_for master }
  66 + it { should be_allowed_for reporter }
  67 + it { should be_allowed_for :admin }
  68 + it { should be_denied_for guest }
  69 + it { should be_denied_for :user }
  70 + it { should be_denied_for :visitor }
  71 + end
  72 +
  73 + describe "GET /:project_path/team" do
  74 + subject { project_team_index_path(project) }
  75 +
  76 + it { should be_allowed_for master }
  77 + it { should be_denied_for reporter }
  78 + it { should be_allowed_for :admin }
  79 + it { should be_denied_for guest }
  80 + it { should be_denied_for :user }
  81 + it { should be_denied_for :visitor }
  82 + end
  83 +
  84 + describe "GET /:project_path/wall" do
  85 + subject { project_wall_path(project) }
  86 +
  87 + it { should be_allowed_for master }
  88 + it { should be_allowed_for reporter }
  89 + it { should be_allowed_for :admin }
  90 + it { should be_denied_for guest }
  91 + it { should be_denied_for :user }
  92 + it { should be_denied_for :visitor }
  93 + end
  94 +
  95 + describe "GET /:project_path/blob" do
  96 + before do
  97 + commit = project.repository.commit
  98 + path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob) }.first.name
  99 + @blob_path = project_blob_path(project, File.join(commit.id, path))
  100 + end
  101 +
  102 + it { @blob_path.should be_allowed_for master }
  103 + it { @blob_path.should be_allowed_for reporter }
  104 + it { @blob_path.should be_allowed_for :admin }
  105 + it { @blob_path.should be_denied_for guest }
  106 + it { @blob_path.should be_denied_for :user }
  107 + it { @blob_path.should be_denied_for :visitor }
  108 + end
  109 +
  110 + describe "GET /:project_path/edit" do
  111 + subject { edit_project_path(project) }
  112 +
  113 + it { should be_allowed_for master }
  114 + it { should be_denied_for reporter }
  115 + it { should be_allowed_for :admin }
  116 + it { should be_denied_for guest }
  117 + it { should be_denied_for :user }
  118 + it { should be_denied_for :visitor }
  119 + end
  120 +
  121 + describe "GET /:project_path/deploy_keys" do
  122 + subject { project_deploy_keys_path(project) }
  123 +
  124 + it { should be_allowed_for master }
  125 + it { should be_denied_for reporter }
  126 + it { should be_allowed_for :admin }
  127 + it { should be_denied_for guest }
  128 + it { should be_denied_for :user }
  129 + it { should be_denied_for :visitor }
  130 + end
  131 +
  132 + describe "GET /:project_path/issues" do
  133 + subject { project_issues_path(project) }
  134 +
  135 + it { should be_allowed_for master }
  136 + it { should be_allowed_for reporter }
  137 + it { should be_allowed_for :admin }
  138 + it { should be_denied_for guest }
  139 + it { should be_denied_for :user }
  140 + it { should be_denied_for :visitor }
  141 + end
  142 +
  143 + describe "GET /:project_path/snippets" do
  144 + subject { project_snippets_path(project) }
  145 +
  146 + it { should be_allowed_for master }
  147 + it { should be_allowed_for reporter }
  148 + it { should be_allowed_for :admin }
  149 + it { should be_denied_for guest }
  150 + it { should be_denied_for :user }
  151 + it { should be_denied_for :visitor }
  152 + end
  153 +
  154 + describe "GET /:project_path/merge_requests" do
  155 + subject { project_merge_requests_path(project) }
  156 +
  157 + it { should be_allowed_for master }
  158 + it { should be_allowed_for reporter }
  159 + it { should be_allowed_for :admin }
  160 + it { should be_denied_for guest }
  161 + it { should be_denied_for :user }
  162 + it { should be_denied_for :visitor }
  163 + end
  164 +
  165 + describe "GET /:project_path/branches/recent" do
  166 + subject { recent_project_branches_path(project) }
  167 +
  168 + it { should be_allowed_for master }
  169 + it { should be_allowed_for reporter }
  170 + it { should be_allowed_for :admin }
  171 + it { should be_denied_for guest }
  172 + it { should be_denied_for :user }
  173 + it { should be_denied_for :visitor }
  174 + end
  175 +
  176 + describe "GET /:project_path/branches" do
  177 + subject { project_branches_path(project) }
  178 +
  179 + before do
  180 + # Speed increase
  181 + Project.any_instance.stub(:branches).and_return([])
  182 + end
  183 +
  184 + it { should be_allowed_for master }
  185 + it { should be_allowed_for reporter }
  186 + it { should be_allowed_for :admin }
  187 + it { should be_denied_for guest }
  188 + it { should be_denied_for :user }
  189 + it { should be_denied_for :visitor }
  190 + end
  191 +
  192 + describe "GET /:project_path/tags" do
  193 + subject { project_tags_path(project) }
  194 +
  195 + before do
  196 + # Speed increase
  197 + Project.any_instance.stub(:tags).and_return([])
  198 + end
  199 +
  200 + it { should be_allowed_for master }
  201 + it { should be_allowed_for reporter }
  202 + it { should be_allowed_for :admin }
  203 + it { should be_denied_for guest }
  204 + it { should be_denied_for :user }
  205 + it { should be_denied_for :visitor }
  206 + end
  207 +
  208 + describe "GET /:project_path/hooks" do
  209 + subject { project_hooks_path(project) }
  210 +
  211 + it { should be_allowed_for master }
  212 + it { should be_denied_for reporter }
  213 + it { should be_allowed_for :admin }
  214 + it { should be_denied_for guest }
  215 + it { should be_denied_for :user }
  216 + it { should be_denied_for :visitor }
  217 + end
  218 +end
spec/features/security/project/public_access_spec.rb 0 → 100644
@@ -0,0 +1,251 @@ @@ -0,0 +1,251 @@
  1 +require 'spec_helper'
  2 +
  3 +describe "Public Project Access" do
  4 + let(:project) { create(:project_with_code) }
  5 +
  6 + let(:master) { create(:user) }
  7 + let(:guest) { create(:user) }
  8 + let(:reporter) { create(:user) }
  9 +
  10 + before do
  11 + # public project
  12 + project.public = true
  13 + project.save!
  14 +
  15 + # full access
  16 + project.team << [master, :master]
  17 +
  18 + # readonly
  19 + project.team << [reporter, :reporter]
  20 +
  21 + end
  22 +
  23 + describe "Project should be public" do
  24 + subject { project }
  25 +
  26 + its(:public?) { should be_true }
  27 + end
  28 +
  29 + describe "GET /:project_path" do
  30 + subject { project_path(project) }
  31 +
  32 + it { should be_allowed_for master }
  33 + it { should be_allowed_for reporter }
  34 + it { should be_allowed_for :admin }
  35 + it { should be_allowed_for guest }
  36 + it { should be_allowed_for :user }
  37 + it { should be_allowed_for :visitor }
  38 + end
  39 +
  40 + describe "GET /:project_path/tree/master" do
  41 + subject { project_tree_path(project, project.repository.root_ref) }
  42 +
  43 + it { should be_allowed_for master }
  44 + it { should be_allowed_for reporter }
  45 + it { should be_allowed_for :admin }
  46 + it { should be_allowed_for guest }
  47 + it { should be_allowed_for :user }
  48 + it { should be_allowed_for :visitor }
  49 + end
  50 +
  51 + describe "GET /:project_path/commits/master" do
  52 + subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
  53 +
  54 + it { should be_allowed_for master }
  55 + it { should be_allowed_for reporter }
  56 + it { should be_allowed_for :admin }
  57 + it { should be_allowed_for guest }
  58 + it { should be_allowed_for :user }
  59 + it { should be_allowed_for :visitor }
  60 + end
  61 +
  62 + describe "GET /:project_path/commit/:sha" do
  63 + subject { project_commit_path(project, project.repository.commit) }
  64 +
  65 + it { should be_allowed_for master }
  66 + it { should be_allowed_for reporter }
  67 + it { should be_allowed_for :admin }
  68 + it { should be_allowed_for guest }
  69 + it { should be_allowed_for :user }
  70 + it { should be_allowed_for :visitor }
  71 + end
  72 +
  73 + describe "GET /:project_path/compare" do
  74 + subject { project_compare_index_path(project) }
  75 +
  76 + it { should be_allowed_for master }
  77 + it { should be_allowed_for reporter }
  78 + it { should be_allowed_for :admin }
  79 + it { should be_allowed_for guest }
  80 + it { should be_allowed_for :user }
  81 + it { should be_allowed_for :visitor }
  82 + end
  83 +
  84 + describe "GET /:project_path/team" do
  85 + subject { project_team_index_path(project) }
  86 +
  87 + it { should be_allowed_for master }
  88 + it { should be_denied_for reporter }
  89 + it { should be_allowed_for :admin }
  90 + it { should be_denied_for guest }
  91 + it { should be_denied_for :user }
  92 + it { should be_denied_for :visitor }
  93 + end
  94 +
  95 + describe "GET /:project_path/wall" do
  96 + subject { project_wall_path(project) }
  97 +
  98 + it { should be_allowed_for master }
  99 + it { should be_allowed_for reporter }
  100 + it { should be_allowed_for :admin }
  101 + it { should be_allowed_for guest }
  102 + it { should be_allowed_for :user }
  103 + it { should be_allowed_for :visitor }
  104 + end
  105 +
  106 + describe "GET /:project_path/blob" do
  107 + before do
  108 + commit = project.repository.commit
  109 + path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob) }.first.name
  110 + @blob_path = project_blob_path(project, File.join(commit.id, path))
  111 + end
  112 +
  113 + it { @blob_path.should be_allowed_for master }
  114 + it { @blob_path.should be_allowed_for reporter }
  115 + it { @blob_path.should be_allowed_for :admin }
  116 + it { @blob_path.should be_allowed_for guest }
  117 + it { @blob_path.should be_allowed_for :user }
  118 + it { @blob_path.should be_allowed_for :visitor }
  119 + end
  120 +
  121 + describe "GET /:project_path/edit" do
  122 + subject { edit_project_path(project) }
  123 +
  124 + it { should be_allowed_for master }
  125 + it { should be_denied_for reporter }
  126 + it { should be_allowed_for :admin }
  127 + it { should be_denied_for guest }
  128 + it { should be_denied_for :user }
  129 + it { should be_denied_for :visitor }
  130 + end
  131 +
  132 + describe "GET /:project_path/deploy_keys" do
  133 + subject { project_deploy_keys_path(project) }
  134 +
  135 + it { should be_allowed_for master }
  136 + it { should be_denied_for reporter }
  137 + it { should be_allowed_for :admin }
  138 + it { should be_denied_for guest }
  139 + it { should be_denied_for :user }
  140 + it { should be_denied_for :visitor }
  141 + end
  142 +
  143 + describe "GET /:project_path/issues" do
  144 + subject { project_issues_path(project) }
  145 +
  146 + it { should be_allowed_for master }
  147 + it { should be_allowed_for reporter }
  148 + it { should be_allowed_for :admin }
  149 + it { should be_allowed_for guest }
  150 + it { should be_allowed_for :user }
  151 + it { should be_allowed_for :visitor }
  152 + end
  153 +
  154 + describe "GET /:project_path/snippets" do
  155 + subject { project_snippets_path(project) }
  156 +
  157 + it { should be_allowed_for master }
  158 + it { should be_allowed_for reporter }
  159 + it { should be_allowed_for :admin }
  160 + it { should be_allowed_for guest }
  161 + it { should be_allowed_for :user }
  162 + it { should be_allowed_for :visitor }
  163 + end
  164 +
  165 + describe "GET /:project_path/snippets/new" do
  166 + subject { new_project_snippet_path(project) }
  167 +
  168 + it { should be_allowed_for master }
  169 + it { should be_allowed_for reporter }
  170 + it { should be_allowed_for :admin }
  171 + it { should be_denied_for guest }
  172 + it { should be_denied_for :user }
  173 + it { should be_denied_for :visitor }
  174 + end
  175 +
  176 + describe "GET /:project_path/merge_requests" do
  177 + subject { project_merge_requests_path(project) }
  178 +
  179 + it { should be_allowed_for master }
  180 + it { should be_allowed_for reporter }
  181 + it { should be_allowed_for :admin }
  182 + it { should be_allowed_for guest }
  183 + it { should be_allowed_for :user }
  184 + it { should be_allowed_for :visitor }
  185 + end
  186 +
  187 + describe "GET /:project_path/merge_requests/new" do
  188 + subject { new_project_merge_request_path(project) }
  189 +
  190 + it { should be_allowed_for master }
  191 + it { should be_denied_for reporter }
  192 + it { should be_allowed_for :admin }
  193 + it { should be_denied_for guest }
  194 + it { should be_denied_for :user }
  195 + it { should be_denied_for :visitor }
  196 + end
  197 +
  198 + describe "GET /:project_path/branches/recent" do
  199 + subject { recent_project_branches_path(project) }
  200 +
  201 + it { should be_allowed_for master }
  202 + it { should be_allowed_for reporter }
  203 + it { should be_allowed_for :admin }
  204 + it { should be_allowed_for guest }
  205 + it { should be_allowed_for :user }
  206 + it { should be_allowed_for :visitor }
  207 + end
  208 +
  209 + describe "GET /:project_path/branches" do
  210 + subject { project_branches_path(project) }
  211 +
  212 + before do
  213 + # Speed increase
  214 + Project.any_instance.stub(:branches).and_return([])
  215 + end
  216 +
  217 + it { should be_allowed_for master }
  218 + it { should be_allowed_for reporter }
  219 + it { should be_allowed_for :admin }
  220 + it { should be_allowed_for guest }
  221 + it { should be_allowed_for :user }
  222 + it { should be_allowed_for :visitor }
  223 + end
  224 +
  225 + describe "GET /:project_path/tags" do
  226 + subject { project_tags_path(project) }
  227 +
  228 + before do
  229 + # Speed increase
  230 + Project.any_instance.stub(:tags).and_return([])
  231 + end
  232 +
  233 + it { should be_allowed_for master }
  234 + it { should be_allowed_for reporter }
  235 + it { should be_allowed_for :admin }
  236 + it { should be_allowed_for guest }
  237 + it { should be_allowed_for :user }
  238 + it { should be_allowed_for :visitor }
  239 + end
  240 +
  241 + describe "GET /:project_path/hooks" do
  242 + subject { project_hooks_path(project) }
  243 +
  244 + it { should be_allowed_for master }
  245 + it { should be_denied_for reporter }
  246 + it { should be_allowed_for :admin }
  247 + it { should be_denied_for guest }
  248 + it { should be_denied_for :user }
  249 + it { should be_denied_for :visitor }
  250 + end
  251 +end
spec/features/security/project_access_spec.rb
@@ -1,474 +0,0 @@ @@ -1,474 +0,0 @@
1 -require 'spec_helper'  
2 -  
3 -describe "Application access" do  
4 - describe "GET /" do  
5 - it { root_path.should be_allowed_for :admin }  
6 - it { root_path.should be_allowed_for :user }  
7 - it { root_path.should be_denied_for :visitor }  
8 - end  
9 -  
10 - describe "GET /projects/new" do  
11 - it { new_project_path.should be_allowed_for :admin }  
12 - it { new_project_path.should be_allowed_for :user }  
13 - it { new_project_path.should be_denied_for :visitor }  
14 - end  
15 -  
16 - describe "Project" do  
17 - let(:project) { create(:project_with_code) }  
18 -  
19 - let(:master) { create(:user) }  
20 - let(:guest) { create(:user) }  
21 - let(:reporter) { create(:user) }  
22 -  
23 - before do  
24 - # full access  
25 - project.team << [master, :master]  
26 -  
27 - # readonly  
28 - project.team << [reporter, :reporter]  
29 - end  
30 -  
31 - describe "GET /project_code" do  
32 - subject { project_path(project) }  
33 -  
34 - it { should be_allowed_for master }  
35 - it { should be_allowed_for reporter }  
36 - it { should be_allowed_for :admin }  
37 - it { should be_denied_for guest }  
38 - it { should be_denied_for :user }  
39 - it { should be_denied_for :visitor }  
40 - end  
41 -  
42 - describe "GET /project_code/tree/master" do  
43 - subject { project_tree_path(project, project.repository.root_ref) }  
44 -  
45 - it { should be_allowed_for master }  
46 - it { should be_allowed_for reporter }  
47 - it { should be_allowed_for :admin }  
48 - it { should be_denied_for guest }  
49 - it { should be_denied_for :user }  
50 - it { should be_denied_for :visitor }  
51 - end  
52 -  
53 - describe "GET /project_code/commits/master" do  
54 - subject { project_commits_path(project, project.repository.root_ref, limit: 1) }  
55 -  
56 - it { should be_allowed_for master }  
57 - it { should be_allowed_for reporter }  
58 - it { should be_allowed_for :admin }  
59 - it { should be_denied_for guest }  
60 - it { should be_denied_for :user }  
61 - it { should be_denied_for :visitor }  
62 - end  
63 -  
64 - describe "GET /project_code/commit/:sha" do  
65 - subject { project_commit_path(project, project.repository.commit) }  
66 -  
67 - it { should be_allowed_for master }  
68 - it { should be_allowed_for reporter }  
69 - it { should be_allowed_for :admin }  
70 - it { should be_denied_for guest }  
71 - it { should be_denied_for :user }  
72 - it { should be_denied_for :visitor }  
73 - end  
74 -  
75 - describe "GET /project_code/compare" do  
76 - subject { project_compare_index_path(project) }  
77 -  
78 - it { should be_allowed_for master }  
79 - it { should be_allowed_for reporter }  
80 - it { should be_allowed_for :admin }  
81 - it { should be_denied_for guest }  
82 - it { should be_denied_for :user }  
83 - it { should be_denied_for :visitor }  
84 - end  
85 -  
86 - describe "GET /project_code/team" do  
87 - subject { project_team_index_path(project) }  
88 -  
89 - it { should be_allowed_for master }  
90 - it { should be_allowed_for reporter }  
91 - it { should be_allowed_for :admin }  
92 - it { should be_denied_for guest }  
93 - it { should be_denied_for :user }  
94 - it { should be_denied_for :visitor }  
95 - end  
96 -  
97 - describe "GET /project_code/wall" do  
98 - subject { project_wall_path(project) }  
99 -  
100 - it { should be_allowed_for master }  
101 - it { should be_allowed_for reporter }  
102 - it { should be_allowed_for :admin }  
103 - it { should be_denied_for guest }  
104 - it { should be_denied_for :user }  
105 - it { should be_denied_for :visitor }  
106 - end  
107 -  
108 - describe "GET /project_code/blob" do  
109 - before do  
110 - commit = project.repository.commit  
111 - path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob) }.first.name  
112 - @blob_path = project_blob_path(project, File.join(commit.id, path))  
113 - end  
114 -  
115 - it { @blob_path.should be_allowed_for master }  
116 - it { @blob_path.should be_allowed_for reporter }  
117 - it { @blob_path.should be_allowed_for :admin }  
118 - it { @blob_path.should be_denied_for guest }  
119 - it { @blob_path.should be_denied_for :user }  
120 - it { @blob_path.should be_denied_for :visitor }  
121 - end  
122 -  
123 - describe "GET /project_code/edit" do  
124 - subject { edit_project_path(project) }  
125 -  
126 - it { should be_allowed_for master }  
127 - it { should be_denied_for reporter }  
128 - it { should be_allowed_for :admin }  
129 - it { should be_denied_for guest }  
130 - it { should be_denied_for :user }  
131 - it { should be_denied_for :visitor }  
132 - end  
133 -  
134 - describe "GET /project_code/deploy_keys" do  
135 - subject { project_deploy_keys_path(project) }  
136 -  
137 - it { should be_allowed_for master }  
138 - it { should be_denied_for reporter }  
139 - it { should be_allowed_for :admin }  
140 - it { should be_denied_for guest }  
141 - it { should be_denied_for :user }  
142 - it { should be_denied_for :visitor }  
143 - end  
144 -  
145 - describe "GET /project_code/issues" do  
146 - subject { project_issues_path(project) }  
147 -  
148 - it { should be_allowed_for master }  
149 - it { should be_allowed_for reporter }  
150 - it { should be_allowed_for :admin }  
151 - it { should be_denied_for guest }  
152 - it { should be_denied_for :user }  
153 - it { should be_denied_for :visitor }  
154 - end  
155 -  
156 - describe "GET /project_code/snippets" do  
157 - subject { project_snippets_path(project) }  
158 -  
159 - it { should be_allowed_for master }  
160 - it { should be_allowed_for reporter }  
161 - it { should be_allowed_for :admin }  
162 - it { should be_denied_for guest }  
163 - it { should be_denied_for :user }  
164 - it { should be_denied_for :visitor }  
165 - end  
166 -  
167 - describe "GET /project_code/merge_requests" do  
168 - subject { project_merge_requests_path(project) }  
169 -  
170 - it { should be_allowed_for master }  
171 - it { should be_allowed_for reporter }  
172 - it { should be_allowed_for :admin }  
173 - it { should be_denied_for guest }  
174 - it { should be_denied_for :user }  
175 - it { should be_denied_for :visitor }  
176 - end  
177 -  
178 - describe "GET /project_code/branches/recent" do  
179 - subject { recent_project_branches_path(project) }  
180 -  
181 - it { should be_allowed_for master }  
182 - it { should be_allowed_for reporter }  
183 - it { should be_allowed_for :admin }  
184 - it { should be_denied_for guest }  
185 - it { should be_denied_for :user }  
186 - it { should be_denied_for :visitor }  
187 - end  
188 -  
189 - describe "GET /project_code/branches" do  
190 - subject { project_branches_path(project) }  
191 -  
192 - before do  
193 - # Speed increase  
194 - Project.any_instance.stub(:branches).and_return([])  
195 - end  
196 -  
197 - it { should be_allowed_for master }  
198 - it { should be_allowed_for reporter }  
199 - it { should be_allowed_for :admin }  
200 - it { should be_denied_for guest }  
201 - it { should be_denied_for :user }  
202 - it { should be_denied_for :visitor }  
203 - end  
204 -  
205 - describe "GET /project_code/tags" do  
206 - subject { project_tags_path(project) }  
207 -  
208 - before do  
209 - # Speed increase  
210 - Project.any_instance.stub(:tags).and_return([])  
211 - end  
212 -  
213 - it { should be_allowed_for master }  
214 - it { should be_allowed_for reporter }  
215 - it { should be_allowed_for :admin }  
216 - it { should be_denied_for guest }  
217 - it { should be_denied_for :user }  
218 - it { should be_denied_for :visitor }  
219 - end  
220 -  
221 - describe "GET /project_code/hooks" do  
222 - subject { project_hooks_path(project) }  
223 -  
224 - it { should be_allowed_for master }  
225 - it { should be_allowed_for reporter }  
226 - it { should be_allowed_for :admin }  
227 - it { should be_denied_for guest }  
228 - it { should be_denied_for :user }  
229 - it { should be_denied_for :visitor }  
230 - 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/branches/recent" do  
421 - subject { recent_project_branches_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/branches" do  
432 - subject { project_branches_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/tags" do  
448 - subject { project_tags_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  
474 -end