From e894e3eea505ebd675b90c3c53382fd8f273ced8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 24 Sep 2013 12:27:25 +0300 Subject: [PATCH 01/15] Restyle sign-in page. Mention public projects --- app/assets/images/login-logo.png | Bin 10209 -> 0 bytes app/assets/stylesheets/sections/login.scss | 5 +++-- app/views/layouts/devise.html.haml | 7 ++++++- 3 files changed, 9 insertions(+), 3 deletions(-) delete mode 100644 app/assets/images/login-logo.png diff --git a/app/assets/images/login-logo.png b/app/assets/images/login-logo.png deleted file mode 100644 index a61c41303c4d6a13cfd9cbd762bff96820233299..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10209 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 Js1!2^`X7e*-9rEX diff --git a/app/assets/stylesheets/sections/login.scss b/app/assets/stylesheets/sections/login.scss index 8d9fd037bc..33bef59c08 100644 --- a/app/assets/stylesheets/sections/login.scss +++ b/app/assets/stylesheets/sections/login.scss @@ -1,7 +1,8 @@ /* Login Page */ body.login-page{ - background: #474D57; - .container .content { padding-top: 4%; } + .container > .content { + padding-top: 20px; + } } .login-box{ diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index 0fa3621173..c4729836fa 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -6,5 +6,10 @@ .container .content %center - = image_tag image_path "login-logo.png" + %h1 GitLab + %p.light + GitLab is open source software to collaborate on code. + %br + #{link_to "Sign in", new_user_session_path} or browse for #{link_to "public projects", public_projects_path}. + %hr = yield From 66998f6d46ee778e6bde749e41f1d712b184a771 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 24 Sep 2013 15:58:39 +0300 Subject: [PATCH 02/15] Allow non authenticated user access to public projects --- app/assets/stylesheets/common.scss | 5 +++ .../projects/application_controller.rb | 23 +++++++++++++- app/controllers/projects_controller.rb | 9 ++++-- app/helpers/application_helper.rb | 2 ++ app/models/ability.rb | 31 ++++++++++++------- app/views/layouts/public.html.haml | 23 ++++++++++---- app/views/projects/_clone_panel.html.haml | 2 +- app/views/projects/commits/_head.html.haml | 2 +- app/views/projects/issues/_head.html.haml | 7 +++-- 9 files changed, 79 insertions(+), 25 deletions(-) diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 6d80b22b3a..1572227ec3 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -382,3 +382,8 @@ table { width: 50px; min-height: 100px; } + +.navbar-gitlab .navbar-inner .nav > li .btn-sign-in { + @extend .btn-new; + padding: 5px 15px; +} diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 1f2a75175c..d525bd4a70 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -1,5 +1,26 @@ class Projects::ApplicationController < ApplicationController before_filter :project before_filter :repository - layout 'projects' + layout :determine_layout + + def authenticate_user! + # Restrict access to Projects area only + # for non-signed users + if !current_user + id = params[:project_id] || params[:id] + @project = Project.find_with_namespace(id) + + return if @project && @project.public + end + + super + end + + def determine_layout + if current_user + 'projects' + else + 'public' + end + end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 23b54ec44a..9ba2a758b8 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,4 +1,5 @@ class ProjectsController < Projects::ApplicationController + skip_before_filter :authenticate_user!, only: [:show] skip_before_filter :project, only: [:new, :create] skip_before_filter :repository, only: [:new, :create] @@ -54,6 +55,8 @@ class ProjectsController < Projects::ApplicationController end def show + return authenticate_user! unless @project.public + limit = (params[:limit] || 20).to_i @events = @project.events.recent @@ -69,8 +72,10 @@ class ProjectsController < Projects::ApplicationController if @project.empty_repo? render "projects/empty" else - @last_push = current_user.recent_push(@project.id) - render :show + if current_user + @last_push = current_user.recent_push(@project.id) + end + render :show, layout: current_user ? "project" : "public" end end format.js diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 4209b081bf..7e5c10fee0 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -90,6 +90,8 @@ module ApplicationHelper end def search_autocomplete_source + return unless current_user + projects = current_user.authorized_projects.map { |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } } groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } } diff --git a/app/models/ability.rb b/app/models/ability.rb index 8335829f91..7f044b220a 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -1,6 +1,7 @@ class Ability class << self def allowed(user, subject) + return not_auth_abilities(user, subject) if user.nil? return [] unless user.kind_of?(User) return [] if user.blocked? @@ -17,6 +18,24 @@ class Ability end.concat(global_abilities(user)) end + # List of possible abilities + # for non-authenticated user + def not_auth_abilities(user, subject) + project = if subject.kind_of?(Project) + subject + elsif subject.respond_to?(:project) + subject.project + else + nil + end + + if project && project.public + public_project_rules + else + [] + end + end + def global_abilities(user) rules = [] rules << :create_group if user.can_create_group @@ -58,19 +77,9 @@ class Ability end def public_project_rules - [ + project_guest_rules + [ :download_code, :fork_project, - :read_project, - :read_wiki, - :read_issue, - :read_milestone, - :read_project_snippet, - :read_team_member, - :read_merge_request, - :read_note, - :write_issue, - :write_note ] end diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml index 7dce0cbeae..c1fe5fcae7 100644 --- a/app/views/layouts/public.html.haml +++ b/app/views/layouts/public.html.haml @@ -1,7 +1,7 @@ !!! 5 %html{ lang: "en"} = render "layouts/head", title: "Public Projects" - %body{class: "#{app_theme} application", :'data-page' => body_data_page} + %body{class: "ui_mars application", :'data-page' => body_data_page} - if current_user = render "layouts/head_panel", title: "Public Projects" - else @@ -13,7 +13,12 @@ = link_to public_root_path, class: "home" do %h1 GITLAB %span.separator - %h1.project_name Public Projects + %h1.project_name + - if @project + = project_title(@project) + - else + Public Projects + %ul.nav %li %a @@ -21,8 +26,14 @@ %i.icon-refresh.icon-spin Loading... %li - = link_to "Sign in", new_session_path(:user) + = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in' - .container.navless-container - .content - = yield + - if @project + %nav.main-nav + .container= render 'layouts/nav/project' + + .container + .content= yield + - else + .container.navless-container + .content= yield diff --git a/app/views/projects/_clone_panel.html.haml b/app/views/projects/_clone_panel.html.haml index 7228c760d2..c5ab64505c 100644 --- a/app/views/projects/_clone_panel.html.haml +++ b/app/views/projects/_clone_panel.html.haml @@ -5,7 +5,7 @@ .span3.pull-right .pull-right - unless @project.empty_repo? - - if can?(current_user, :fork_project, @project) && @project.namespace != current_user.namespace + - if current_user && can?(current_user, :fork_project, @project) && @project.namespace != current_user.namespace - if current_user.already_forked?(@project) = link_to project_path(current_user.fork_of(@project)), class: 'btn grouped disabled' do %i.icon-code-fork diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index 624604142b..c2da9f273b 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -21,7 +21,7 @@ Stats - - if current_controller?(:commits) && current_user.private_token + - if current_user && current_controller?(:commits) && current_user.private_token %li.pull-right = link_to project_commits_path(@project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed" do %i.icon-rss diff --git a/app/views/projects/issues/_head.html.haml b/app/views/projects/issues/_head.html.haml index 44d14d5cdf..438cc02b47 100644 --- a/app/views/projects/issues/_head.html.haml +++ b/app/views/projects/issues/_head.html.haml @@ -5,6 +5,7 @@ = link_to 'Milestones', project_milestones_path(@project), class: "tab" = nav_link(controller: :labels) do = link_to 'Labels', project_labels_path(@project), class: "tab" - %li.pull-right - = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do - %i.icon-rss + - if current_user + %li.pull-right + = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do + %i.icon-rss From ffd0a985ee86691ddb4807cf9be267bdd37c7815 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 24 Sep 2013 16:00:21 +0300 Subject: [PATCH 03/15] Point to project page from public area --- app/controllers/public/projects_controller.rb | 13 ----- app/views/public/projects/_tree.html.haml | 5 -- app/views/public/projects/index.html.haml | 2 +- app/views/public/projects/show.html.haml | 49 ------------------- 4 files changed, 1 insertion(+), 68 deletions(-) delete mode 100644 app/views/public/projects/_tree.html.haml delete mode 100644 app/views/public/projects/show.html.haml diff --git a/app/controllers/public/projects_controller.rb b/app/controllers/public/projects_controller.rb index 3504bd3f1a..87e903a1d2 100644 --- a/app/controllers/public/projects_controller.rb +++ b/app/controllers/public/projects_controller.rb @@ -10,17 +10,4 @@ class Public::ProjectsController < ApplicationController @projects = @projects.search(params[:search]) if params[:search].present? @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20) end - - def show - @project = Project.public_only.find_with_namespace(params[:id]) - render_404 and return unless @project - - @repository = @project.repository - unless @project.empty_repo? - @recent_tags = @repository.tags.first(10) - - @commit = @repository.commit(params[:ref]) - @tree = Tree.new(@repository, @commit.id) - end - end end diff --git a/app/views/public/projects/_tree.html.haml b/app/views/public/projects/_tree.html.haml deleted file mode 100644 index bd09c236a0..0000000000 --- a/app/views/public/projects/_tree.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -- if tree.readme - = render "projects/tree/readme", readme: tree.readme -- else - .alert - %h3.nothing_here_message This project does not have README file diff --git a/app/views/public/projects/index.html.haml b/app/views/public/projects/index.html.haml index 7dbe560e7f..bea99b54ef 100644 --- a/app/views/public/projects/index.html.haml +++ b/app/views/public/projects/index.html.haml @@ -17,7 +17,7 @@ %li .project-title %i.icon-share.cgray - = link_to public_project_path(project) do + = link_to project_path(project) do %strong= project.name_with_namespace .pull-right %pre.public-clone git clone #{project.http_url_to_repo} diff --git a/app/views/public/projects/show.html.haml b/app/views/public/projects/show.html.haml deleted file mode 100644 index 195b9bc07d..0000000000 --- a/app/views/public/projects/show.html.haml +++ /dev/null @@ -1,49 +0,0 @@ -%h3.page-title - = @project.name_with_namespace - .pull-right - %pre.public-clone git clone #{@project.http_url_to_repo} - .pull-right - - if current_user - = link_to 'Browse project', @project, class: 'btn btn-create append-right-10' - - -%div - = link_to public_root_path do - ← To projects list - .pull-right - %span.light= @project.description - -%br -.row - - unless @project.empty_repo? - .span9 - = render 'tree', tree: @tree - .span3 - %h5 Repository: - %div - %p - %span.light Bare size is - #{@project.repository.size} MB - - %p - = pluralize(@repository.round_commit_count, 'commit') - %p - = pluralize(@repository.branch_names.count, 'branch') - %p - = pluralize(@repository.tag_names.count, 'tag') - - - if @recent_tags.present? - %hr - %h5 Most Recent Tags: - %ul.unstyled - - @recent_tags.each do |tag| - %li - %p - %i.icon-tag - %strong= tag.name - %small.light.pull-right - %i.icon-calendar - = time_ago_in_words(tag.commit.committed_date) - ago - - else - = 'Empty Repository' From 09cb2ba8151a60056f4d17fb448ed79c31f02bee Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 24 Sep 2013 22:12:48 +0300 Subject: [PATCH 04/15] Fix password update --- app/controllers/profiles_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 780f47d996..75f12f8a6a 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -33,8 +33,8 @@ class ProfilesController < ApplicationController end def update_password - params[:user].select! do |key, value| - %w(current_password password password_confirmation).include?(key.to_s) + password_attributes = params[:user].select do |key, value| + %w(password password_confirmation).include?(key.to_s) end unless @user.valid_password?(params[:user][:current_password]) @@ -42,7 +42,7 @@ class ProfilesController < ApplicationController return end - if @user.update_attributes(params[:user]) + if @user.update_attributes(password_attributes) flash[:notice] = "Password was successfully updated. Please login with it" redirect_to new_user_session_path else From d90462033ef47a8218d2029efddf1614c6051ccd Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 24 Sep 2013 22:13:28 +0300 Subject: [PATCH 05/15] Remove writing issues/notes from non-auth user abilities --- app/models/ability.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 7f044b220a..26988c5e6a 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -30,7 +30,17 @@ class Ability end if project && project.public - public_project_rules + [ + :read_project, + :read_wiki, + :read_issue, + :read_milestone, + :read_project_snippet, + :read_team_member, + :read_merge_request, + :read_note, + :download_code + ] else [] end From 61eb050993e85459282dd6f39c1f703d29b6d3a7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 24 Sep 2013 22:14:03 +0300 Subject: [PATCH 06/15] Different layout for browsing public area and public project page while not logged-in --- .../layouts/_public_head_panel.html.haml | 22 ++++++++++++ app/views/layouts/public.html.haml | 34 ++----------------- app/views/layouts/public_projects.html.haml | 9 +++++ 3 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 app/views/layouts/_public_head_panel.html.haml create mode 100644 app/views/layouts/public_projects.html.haml diff --git a/app/views/layouts/_public_head_panel.html.haml b/app/views/layouts/_public_head_panel.html.haml new file mode 100644 index 0000000000..3c4bd857c2 --- /dev/null +++ b/app/views/layouts/_public_head_panel.html.haml @@ -0,0 +1,22 @@ +%header.navbar.navbar-static-top.navbar-gitlab + .navbar-inner + .container + %div.app_logo + %span.separator + = link_to public_root_path, class: "home" do + %h1 GITLAB + %span.separator + %h1.project_name + - if @project + = project_title(@project) + - else + Public Projects + + %ul.nav + %li + %a + %div.hide.turbolink-spinner + %i.icon-refresh.icon-spin + Loading... + %li + = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in' diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml index c1fe5fcae7..f922dcc420 100644 --- a/app/views/layouts/public.html.haml +++ b/app/views/layouts/public.html.haml @@ -5,35 +5,7 @@ - if current_user = render "layouts/head_panel", title: "Public Projects" - else - %header.navbar.navbar-static-top.navbar-gitlab - .navbar-inner - .container - %div.app_logo - %span.separator - = link_to public_root_path, class: "home" do - %h1 GITLAB - %span.separator - %h1.project_name - - if @project - = project_title(@project) - - else - Public Projects + = render "layouts/public_head_panel" - %ul.nav - %li - %a - %div.hide.turbolink-spinner - %i.icon-refresh.icon-spin - Loading... - %li - = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in' - - - if @project - %nav.main-nav - .container= render 'layouts/nav/project' - - .container - .content= yield - - else - .container.navless-container - .content= yield + .container.navless-container + .content= yield diff --git a/app/views/layouts/public_projects.html.haml b/app/views/layouts/public_projects.html.haml new file mode 100644 index 0000000000..cfe6a63055 --- /dev/null +++ b/app/views/layouts/public_projects.html.haml @@ -0,0 +1,9 @@ +!!! 5 +%html{ lang: "en"} + = render "layouts/head", title: @project.name_with_namespace + %body{class: "ui_mars application", :'data-page' => body_data_page} + = render "layouts/public_head_panel" + %nav.main-nav + .container= render 'layouts/nav/project' + .container + .content= yield From 2f6342978bfb0bd7aafc345a36bb0846b73cc80d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 24 Sep 2013 22:14:28 +0300 Subject: [PATCH 07/15] Public projects feature - step2 * Render right layout depends on current_user * show sample git username/email when repo is empty * Show extra info when browsing public area * Fixed some tests related to public projects * show comments in read-only for public projects * Remove old public routing --- app/assets/stylesheets/sections/projects.scss | 24 +++++--------- .../projects/application_controller.rb | 2 +- app/controllers/projects_controller.rb | 11 ++++--- app/helpers/projects_helper.rb | 16 ++++++++++ app/views/projects/empty.html.haml | 4 +-- app/views/projects/notes/_note.html.haml | 2 +- app/views/public/projects/index.html.haml | 31 +++++++++++++------ config/routes.rb | 2 -- features/public/public_projects.feature | 9 +++--- features/steps/public/projects_feature.rb | 15 +++++++-- 10 files changed, 72 insertions(+), 44 deletions(-) diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss index f2707f6237..0491b68db5 100644 --- a/app/assets/stylesheets/sections/projects.scss +++ b/app/assets/stylesheets/sections/projects.scss @@ -79,21 +79,6 @@ ul.nav.nav-projects-tabs { margin: 0px; } -.public-projects { - li { - .project-title { - font-size: 14px; - line-height: 2; - font-weight: normal; - } - - .description { - margin-left: 15px; - color: #aaa; - } - } -} - .my-projects { li { .project-title { @@ -110,7 +95,6 @@ ul.nav.nav-projects-tabs { } } - .public-clone { background: #333; color: #f5f5f5; @@ -123,3 +107,11 @@ ul.nav.nav-projects-tabs { position: relative; top: -5px; } + +.public-projects .repo-info { + color: #777; + + a { + color: #777; + } +} diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index d525bd4a70..8fd4565f36 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -20,7 +20,7 @@ class Projects::ApplicationController < ApplicationController if current_user 'projects' else - 'public' + 'public_projects' end end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 9ba2a758b8..f31fb666e3 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -55,10 +55,9 @@ class ProjectsController < Projects::ApplicationController end def show - return authenticate_user! unless @project.public + return authenticate_user! unless @project.public || current_user limit = (params[:limit] || 20).to_i - @events = @project.events.recent @events = event_filter.apply_filter(@events) @events = @events.limit(limit).offset(params[:offset] || 0) @@ -70,12 +69,12 @@ class ProjectsController < Projects::ApplicationController respond_to do |format| format.html do if @project.empty_repo? - render "projects/empty" + render "projects/empty", layout: user_layout else if current_user @last_push = current_user.recent_push(@project.id) end - render :show, layout: current_user ? "project" : "public" + render :show, layout: user_layout end end format.js @@ -126,4 +125,8 @@ class ProjectsController < Projects::ApplicationController def set_title @title = 'New Project' end + + def user_layout + current_user ? "projects" : "public_projects" + end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 3a1cf59fd1..9071c688df 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -103,4 +103,20 @@ module ProjectsHelper nav_tabs.flatten end + + def git_user_name + if current_user + current_user.name + else + "Your name" + end + end + + def git_user_email + if current_user + current_user.email + else + "your@email.com" + end + end end diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index 001857cefd..9f3502e90d 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -16,8 +16,8 @@ %legend Git global setup: %pre.dark :preserve - git config --global user.name "#{current_user.name}" - git config --global user.email "#{current_user.email}" + git config --global user.name "#{git_user_name}" + git config --global user.email "#{git_user_email}" %fieldset %legend Create Repository diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index fbc924c4e1..324b698f3b 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -5,7 +5,7 @@ %i.icon-link Link here   - - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) + - if(note.author_id == current_user.try(:id)) || can?(current_user, :admin_note, @project) = link_to "#", title: "Edit comment", class: "js-note-edit" do %i.icon-edit Edit diff --git a/app/views/public/projects/index.html.haml b/app/views/public/projects/index.html.haml index bea99b54ef..21aee64457 100644 --- a/app/views/public/projects/index.html.haml +++ b/app/views/public/projects/index.html.haml @@ -2,29 +2,40 @@ .span6 %h3.page-title Projects (#{@projects.total_count}) - %small with read-only access + .light + You can browse public projects in read-only mode until signed in. + .span6 .pull-right = form_tag public_projects_path, method: :get, class: 'form-inline' do |f| .search-holder - .controls - = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "span3 search-text-input", id: "projects_search" - = submit_tag 'Search', class: "btn btn-primary wide" - + = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "span3 search-text-input", id: "projects_search" + = submit_tag 'Search', class: "btn btn-primary wide" +%hr .public-projects - %ul.bordered-list + %ul.bordered-list.top-list - @projects.each do |project| %li - .project-title - %i.icon-share.cgray + %h4 = link_to project_path(project) do - %strong= project.name_with_namespace + = project.name_with_namespace .pull-right %pre.public-clone git clone #{project.http_url_to_repo} - if project.description.present? - %div.description + %p = project.description + + .repo-info + - unless project.empty_repo? + = link_to pluralize(project.repository.round_commit_count, 'commit'), project_commits_path(project, project.default_branch) + · + = link_to pluralize(project.repository.branch_names.count, 'branch'), project_branches_path(project) + · + = link_to pluralize(project.repository.tag_names.count, 'tag'), project_tags_path(project) + - else + %i.icon-warning-sign + Empty repository - unless @projects.present? %h3.nothing_here_message No public projects diff --git a/config/routes.rb b/config/routes.rb index 2b444c2a29..9d47faa19d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -55,8 +55,6 @@ Gitlab::Application.routes.draw do # namespace :public do resources :projects, only: [:index] - resources :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }, only: [:show] - root to: "projects#index" end diff --git a/features/public/public_projects.feature b/features/public/public_projects.feature index 1866d3f47f..178a769194 100644 --- a/features/public/public_projects.feature +++ b/features/public/public_projects.feature @@ -9,11 +9,10 @@ Feature: Public Projects Feature And I should not see project "Enterprise" Scenario: I visit public project page - When I visit public page for "Community" project - Then I should see public project details - And I should see project readme + When I visit project "Community" page + Then I should see project "Community" home page Scenario: I visit an empty public project page Given public empty project "Empty Public Project" - When I visit empty public project page - Then I should see empty public project details \ No newline at end of file + When I visit empty project page + Then I should see empty public project details diff --git a/features/steps/public/projects_feature.rb b/features/steps/public/projects_feature.rb index 2268e9b9c5..2f2c4de0b2 100644 --- a/features/steps/public/projects_feature.rb +++ b/features/steps/public/projects_feature.rb @@ -31,19 +31,28 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps create :project, name: 'Empty Public Project', public: true end - step 'I visit empty public project page' do + step 'I visit empty project page' do project = Project.find_by_name('Empty Public Project') - visit public_project_path(project) + visit project_path(project) + end + + step 'I visit project "Community" page' do + project = Project.find_by_name('Community') + visit project_path(project) end step 'I should see empty public project details' do - page.should have_content 'Empty Repository' + page.should have_content 'Git global setup' end step 'private project "Enterprise"' do create :project, name: 'Enterprise' end + step 'I should see project "Community" home page' do + page.should have_content 'Repo size is' + end + private def project From bcdc7b5d63ece0136ef7c87517c975e69d3b8aab Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 25 Sep 2013 13:27:16 +0300 Subject: [PATCH 08/15] Group security tests --- spec/features/security/group_access_spec.rb | 83 +++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 spec/features/security/group_access_spec.rb diff --git a/spec/features/security/group_access_spec.rb b/spec/features/security/group_access_spec.rb new file mode 100644 index 0000000000..b6167174f2 --- /dev/null +++ b/spec/features/security/group_access_spec.rb @@ -0,0 +1,83 @@ +require 'spec_helper' + +describe "Group access" do + describe "GET /projects/new" do + it { new_group_path.should be_allowed_for :admin } + it { new_group_path.should be_allowed_for :user } + it { new_group_path.should be_denied_for :visitor } + end + + describe "Group" do + let(:group) { create(:group) } + + let(:master) { create(:user) } + let(:reporter) { create(:user) } + let(:guest) { create(:user) } + + before do + group.add_user(master, Gitlab::Access::MASTER) + group.add_user(reporter, Gitlab::Access::REPORTER) + group.add_user(guest, Gitlab::Access::GUEST) + end + + describe "GET /groups/:path" do + subject { group_path(group) } + + it { should be_allowed_for group.owner } + 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_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /groups/:path/issues" do + subject { issues_group_path(group) } + + it { should be_allowed_for group.owner } + 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_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /groups/:path/merge_requests" do + subject { merge_requests_group_path(group) } + + it { should be_allowed_for group.owner } + 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_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /groups/:path/members" do + subject { members_group_path(group) } + + it { should be_allowed_for group.owner } + 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_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /groups/:path/edit" do + subject { edit_group_path(group) } + + it { should be_allowed_for group.owner } + it { should be_denied_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 + end +end From ea779cc5abe9218193197d1c7b60d898dde47904 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 25 Sep 2013 14:04:01 +0300 Subject: [PATCH 09/15] Public/Private projects security specs --- .../security/project/private_access_spec.rb | 218 ++++++++ .../security/project/public_access_spec.rb | 251 ++++++++++ spec/features/security/project_access_spec.rb | 474 ------------------ 3 files changed, 469 insertions(+), 474 deletions(-) create mode 100644 spec/features/security/project/private_access_spec.rb create mode 100644 spec/features/security/project/public_access_spec.rb delete mode 100644 spec/features/security/project_access_spec.rb diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb new file mode 100644 index 0000000000..7f3f8c50f0 --- /dev/null +++ b/spec/features/security/project/private_access_spec.rb @@ -0,0 +1,218 @@ +require 'spec_helper' + +describe "Private Project Access" do + let(:project) { create(:project_with_code) } + + let(:master) { create(:user) } + let(:guest) { create(:user) } + let(:reporter) { create(:user) } + + before do + # full access + project.team << [master, :master] + + # readonly + project.team << [reporter, :reporter] + end + + describe "GET /:project_path" 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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/team" do + subject { project_team_index_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_path/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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/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_denied_for guest } + it { @blob_path.should be_denied_for :user } + it { @blob_path.should be_denied_for :visitor } + end + + describe "GET /:project_path/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_path/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_path/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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/branches/recent" do + subject { recent_project_branches_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_path/branches" do + subject { project_branches_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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/tags" do + subject { project_tags_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_denied_for guest } + it { should be_denied_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /:project_path/hooks" do + subject { project_hooks_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 +end diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb new file mode 100644 index 0000000000..267643fd8e --- /dev/null +++ b/spec/features/security/project/public_access_spec.rb @@ -0,0 +1,251 @@ +require 'spec_helper' + +describe "Public Project Access" do + let(:project) { create(:project_with_code) } + + let(:master) { create(:user) } + let(:guest) { create(:user) } + let(:reporter) { 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_path" 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_allowed_for :visitor } + end + + describe "GET /:project_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/team" do + subject { project_team_index_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_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/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_path/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_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/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_path/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_allowed_for :visitor } + end + + describe "GET /:project_path/merge_requests/new" do + subject { new_project_merge_request_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_path/branches/recent" do + subject { recent_project_branches_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_allowed_for :visitor } + end + + describe "GET /:project_path/branches" do + subject { project_branches_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_allowed_for :visitor } + end + + describe "GET /:project_path/tags" do + subject { project_tags_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_allowed_for :visitor } + end + + describe "GET /:project_path/hooks" do + subject { project_hooks_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 +end diff --git a/spec/features/security/project_access_spec.rb b/spec/features/security/project_access_spec.rb deleted file mode 100644 index d0964a947d..0000000000 --- a/spec/features/security/project_access_spec.rb +++ /dev/null @@ -1,474 +0,0 @@ -require 'spec_helper' - -describe "Application access" do - describe "GET /" do - it { root_path.should be_allowed_for :admin } - it { root_path.should be_allowed_for :user } - it { root_path.should be_denied_for :visitor } - end - - describe "GET /projects/new" do - it { new_project_path.should be_allowed_for :admin } - it { new_project_path.should be_allowed_for :user } - it { new_project_path.should be_denied_for :visitor } - end - - describe "Project" do - let(:project) { create(:project_with_code) } - - let(:master) { create(:user) } - let(:guest) { create(:user) } - let(:reporter) { create(:user) } - - before do - # full access - project.team << [master, :master] - - # readonly - project.team << [reporter, :reporter] - 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_denied_for guest } - it { should be_denied_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_denied_for guest } - it { should be_denied_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_denied_for guest } - it { should be_denied_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_denied_for guest } - it { should be_denied_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_denied_for guest } - it { should be_denied_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_denied_for guest } - it { should be_denied_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_denied_for guest } - it { should be_denied_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_denied_for guest } - it { @blob_path.should be_denied_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_denied_for guest } - it { should be_denied_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_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_denied_for guest } - it { should be_denied_for :user } - it { should be_denied_for :visitor } - end - - describe "GET /project_code/branches/recent" do - subject { recent_project_branches_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/branches" do - subject { project_branches_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_denied_for guest } - it { should be_denied_for :user } - it { should be_denied_for :visitor } - end - - describe "GET /project_code/tags" do - subject { project_tags_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_denied_for guest } - it { should be_denied_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_denied_for guest } - it { should be_denied_for :user } - 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/branches/recent" do - subject { recent_project_branches_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/branches" do - subject { project_branches_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/tags" do - subject { project_tags_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 From 6954d50fd3307f25f16ac06f21aebe37cb7059db Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 25 Sep 2013 14:04:16 +0300 Subject: [PATCH 10/15] Dashboard security specs --- .../security/dashboard_access_spec.rb | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 spec/features/security/dashboard_access_spec.rb diff --git a/spec/features/security/dashboard_access_spec.rb b/spec/features/security/dashboard_access_spec.rb new file mode 100644 index 0000000000..adec5926c6 --- /dev/null +++ b/spec/features/security/dashboard_access_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' + +describe "Dashboard access" do + describe "GET /dashboard" do + subject { dashboard_path } + + it { should be_allowed_for :admin } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /dashboard/issues" do + subject { issues_dashboard_path } + + it { should be_allowed_for :admin } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /dashboard/merge_requests" do + subject { merge_requests_dashboard_path } + + it { should be_allowed_for :admin } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /dashboard/projects" do + subject { projects_dashboard_path } + + it { should be_allowed_for :admin } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /help" do + subject { help_path } + + it { should be_allowed_for :admin } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /projects/new" do + it { new_project_path.should be_allowed_for :admin } + it { new_project_path.should be_allowed_for :user } + it { new_project_path.should be_denied_for :visitor } + end + + describe "GET /groups/new" do + it { new_group_path.should be_allowed_for :admin } + it { new_group_path.should be_allowed_for :user } + it { new_group_path.should be_denied_for :visitor } + end +end From bae15dc5f78276106151cfcf9d0c8988521db42e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 25 Sep 2013 14:04:32 +0300 Subject: [PATCH 11/15] Version up to 6.2.0.pre --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index dfda3e0b4f..79e046f49a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.1.0 +6.2.0.pre From 087d7e554f603faf946ea7ccb910e7b99a0801c2 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 25 Sep 2013 14:05:03 +0300 Subject: [PATCH 12/15] Extend profile security specs --- spec/features/security/profile_access_spec.rb | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb index 52130b3f8c..7754b28347 100644 --- a/spec/features/security/profile_access_spec.rb +++ b/spec/features/security/profile_access_spec.rb @@ -45,5 +45,32 @@ describe "Users Security" do it { should be_allowed_for :user } it { should be_denied_for :visitor } end + + describe "GET /profile/history" do + subject { history_profile_path } + + it { should be_allowed_for @u1 } + it { should be_allowed_for :admin } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /profile/notifications" do + subject { profile_notifications_path } + + it { should be_allowed_for @u1 } + it { should be_allowed_for :admin } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end + + describe "GET /profile/groups" do + subject { profile_groups_path } + + it { should be_allowed_for @u1 } + it { should be_allowed_for :admin } + it { should be_allowed_for :user } + it { should be_denied_for :visitor } + end end end From 573d367be5a61e9b344e48b6678cdd8067fe6bd1 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 25 Sep 2013 14:05:35 +0300 Subject: [PATCH 13/15] Modify permissions for project and group * Hooks and team pages allowed only for masters/owners * Group page allowed for admin * Corrent authentication for Projects controller * Hide some project elements from visitor --- app/controllers/projects/hooks_controller.rb | 3 +- .../projects/snippets_controller.rb | 2 - .../projects/team_members_controller.rb | 3 +- app/controllers/projects_controller.rb | 6 +- app/models/ability.rb | 2 +- app/models/group.rb | 4 ++ app/views/projects/_clone_panel.html.haml | 67 ++++++++++--------- 7 files changed, 44 insertions(+), 43 deletions(-) diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index 3367ddb5d1..1a94dbab5e 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -1,7 +1,6 @@ class Projects::HooksController < Projects::ApplicationController # Authorize - before_filter :authorize_read_project! - before_filter :authorize_admin_project!, only: [:new, :create, :destroy] + before_filter :authorize_admin_project! respond_to :html diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 59063103ec..dd0c1a5708 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -14,8 +14,6 @@ class Projects::SnippetsController < Projects::ApplicationController # Allow destroy snippet before_filter :authorize_admin_project_snippet!, only: [:destroy] - layout 'projects' - respond_to :html def index diff --git a/app/controllers/projects/team_members_controller.rb b/app/controllers/projects/team_members_controller.rb index 6fee770cae..b4b318fa59 100644 --- a/app/controllers/projects/team_members_controller.rb +++ b/app/controllers/projects/team_members_controller.rb @@ -1,7 +1,6 @@ class Projects::TeamMembersController < Projects::ApplicationController # Authorize - before_filter :authorize_read_project! - before_filter :authorize_admin_project!, except: [:index, :show] + before_filter :authorize_admin_project! layout "project_settings" diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index f31fb666e3..7264128691 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,7 +1,7 @@ -class ProjectsController < Projects::ApplicationController +class ProjectsController < ApplicationController skip_before_filter :authenticate_user!, only: [:show] - skip_before_filter :project, only: [:new, :create] - skip_before_filter :repository, only: [:new, :create] + before_filter :project, except: [:new, :create] + before_filter :repository, except: [:new, :create] # Authorize before_filter :authorize_read_project!, except: [:index, :new, :create] diff --git a/app/models/ability.rb b/app/models/ability.rb index 26988c5e6a..ad070dad29 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -154,7 +154,7 @@ class Ability def group_abilities user, group rules = [] - if group.users.include?(user) + if group.users.include?(user) || user.admin? rules << :read_group end diff --git a/app/models/group.rb b/app/models/group.rb index fce8d71217..0b36c93437 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -32,6 +32,10 @@ class Group < Namespace end end + def add_user(user, group_access) + self.users_groups.create(user_id: user.id, group_access: group_access) + end + def change_owner(user) self.owner = user membership = users_groups.where(user_id: user.id).first diff --git a/app/views/projects/_clone_panel.html.haml b/app/views/projects/_clone_panel.html.haml index c5ab64505c..c2f85e8ebe 100644 --- a/app/views/projects/_clone_panel.html.haml +++ b/app/views/projects/_clone_panel.html.haml @@ -19,37 +19,38 @@ %i.icon-download-alt %span.only-wide Download - .dropdown.pull-right - %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %i.icon-plus-sign-alt - %span.only-wide New - %b.caret - %ul.dropdown-menu - - if @project.issues_enabled && can?(current_user, :write_issue, @project) - %li - = link_to url_for_new_issue, title: "New Issue" do - Issue - - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project) - %li - = link_to new_project_merge_request_path(@project), title: "New Merge Request" do - Merge Request - - if @project.snippets_enabled && can?(current_user, :write_snippet, @project) - %li - = link_to new_project_snippet_path(@project), title: "New Snippet" do - Snippet - - if can? current_user, :push_code, @project - %li.divider - %li - = link_to new_project_branch_path(@project) do - %i.icon-code-fork - Git branch - %li - = link_to new_project_tag_path(@project) do - %i.icon-tag - Git tag + - if current_user + .dropdown.pull-right + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} + %i.icon-plus-sign-alt + %span.only-wide New + %b.caret + %ul.dropdown-menu + - if @project.issues_enabled && can?(current_user, :write_issue, @project) + %li + = link_to url_for_new_issue, title: "New Issue" do + Issue + - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project) + %li + = link_to new_project_merge_request_path(@project), title: "New Merge Request" do + Merge Request + - if @project.snippets_enabled && can?(current_user, :write_snippet, @project) + %li + = link_to new_project_snippet_path(@project), title: "New Snippet" do + Snippet + - if can? current_user, :push_code, @project + %li.divider + %li + = link_to new_project_branch_path(@project) do + %i.icon-code-fork + Git branch + %li + = link_to new_project_tag_path(@project) do + %i.icon-tag + Git tag - - if can?(current_user, :admin_team_member, @project) - %li.divider - %li - = link_to new_project_team_member_path(@project), title: "New project member" do - Project member + - if can?(current_user, :admin_team_member, @project) + %li.divider + %li + = link_to new_project_team_member_path(@project), title: "New project member" do + Project member From 0a01994466622c5fce69252042a35231ab418379 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 25 Sep 2013 14:23:06 +0300 Subject: [PATCH 14/15] Fix public project tests --- features/steps/public/projects_feature.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/steps/public/projects_feature.rb b/features/steps/public/projects_feature.rb index 2f2c4de0b2..e9a4d56e36 100644 --- a/features/steps/public/projects_feature.rb +++ b/features/steps/public/projects_feature.rb @@ -11,7 +11,6 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps step 'I should see project "Empty Public Project"' do page.should have_content "Empty Public Project" - puts page.save_page('foo.html') end step 'I should see public project details' do @@ -24,7 +23,7 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps end step 'public project "Community"' do - create :project_with_code, name: 'Community', public: true + create :project_with_code, name: 'Community', public: true, default_branch: 'master' end step 'public empty project "Empty Public Project"' do From e8292e733bd35eefad4c222f324c3d5070ac83eb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 25 Sep 2013 15:49:35 +0300 Subject: [PATCH 15/15] Mention public projects in CHANGELOG --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index e955925138..3db03f76ed 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v 6.2.0 + - Public projects are visible from the outside + v 6.1.0 - Project specific IDs for issues, mr, milestones Above items will get a new id and for example all bookmarked issue urls will change.