Commit 79dd7bee authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'feature/public_groups' into 'master'

Public Groups

This is the initial work (meaning no tests) for making groups public if they have a public project (or internal for logged in users). This allows issues and merge requests to be viewed, but _not_ group membership. As part of this I have also added back the link in the public project title section (it was removed as it didn't make sense before).

This addesses the following suggestions/issues:

http://feedback.gitlab.com/forums/176466-general/suggestions/5314461-groups-containing-one-or-more-public-projects-shou
Issue #32
https://github.com/gitlabhq/gitlabhq/issues/5203
as well as a few closed issues.

This also changes the public user page to only show groups that are accessible to the user in some manner.
parents 86e25595 2f69213e
...@@ -77,5 +77,6 @@ class DashboardController < ApplicationController ...@@ -77,5 +77,6 @@ class DashboardController < ApplicationController
def default_filter def default_filter
params[:scope] = 'assigned-to-me' if params[:scope].blank? params[:scope] = 'assigned-to-me' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank? params[:state] = 'opened' if params[:state].blank?
params[:authorized_only] = true
end end
end end
class GroupsController < ApplicationController class GroupsController < ApplicationController
skip_before_filter :authenticate_user!, only: [:show, :issues, :members, :merge_requests]
respond_to :html respond_to :html
before_filter :group, except: [:new, :create] before_filter :group, except: [:new, :create]
...@@ -36,7 +37,7 @@ class GroupsController < ApplicationController ...@@ -36,7 +37,7 @@ class GroupsController < ApplicationController
@events = Event.in_projects(project_ids) @events = Event.in_projects(project_ids)
@events = event_filter.apply_filter(@events) @events = event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0) @events = @events.limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push @last_push = current_user.recent_push if current_user
respond_to do |format| respond_to do |format|
format.html format.html
...@@ -98,19 +99,23 @@ class GroupsController < ApplicationController ...@@ -98,19 +99,23 @@ class GroupsController < ApplicationController
end end
def projects def projects
@projects ||= current_user.authorized_projects.where(namespace_id: group.id).sorted_by_activity @projects ||= group.projects_accessible_to(current_user).sorted_by_activity
end end
def project_ids def project_ids
projects.map(&:id) projects.pluck(:id)
end end
# Dont allow unauthorized access to group # Dont allow unauthorized access to group
def authorize_read_group! def authorize_read_group!
unless @group and (projects.present? or can?(current_user, :read_group, @group)) unless @group and (projects.present? or can?(current_user, :read_group, @group))
if current_user.nil?
return authenticate_user!
else
return render_404 return render_404
end end
end end
end
def authorize_create_group! def authorize_create_group!
unless can?(current_user, :create_group, nil) unless can?(current_user, :create_group, nil)
...@@ -131,13 +136,21 @@ class GroupsController < ApplicationController ...@@ -131,13 +136,21 @@ class GroupsController < ApplicationController
def determine_layout def determine_layout
if [:new, :create].include?(action_name.to_sym) if [:new, :create].include?(action_name.to_sym)
'navless' 'navless'
else elsif current_user
'group' 'group'
else
'public_group'
end end
end end
def default_filter def default_filter
params[:scope] = 'assigned-to-me' if params[:scope].blank? if params[:scope].blank?
if current_user
params[:scope] = 'assigned-to-me'
else
params[:scope] = 'all'
end
end
params[:state] = 'opened' if params[:state].blank? params[:state] = 'opened' if params[:state].blank?
params[:group_id] = @group.id params[:group_id] = @group.id
end end
......
...@@ -6,7 +6,7 @@ class Public::ProjectsController < ApplicationController ...@@ -6,7 +6,7 @@ class Public::ProjectsController < ApplicationController
layout 'public' layout 'public'
def index def index
@projects = Project.public_or_internal_only(current_user) @projects = Project.publicish(current_user)
@projects = @projects.search(params[:search]) if params[:search].present? @projects = @projects.search(params[:search]) if params[:search].present?
@projects = @projects.sort(@sort = params[:sort]) @projects = @projects.sort(@sort = params[:sort])
@projects = @projects.includes(:namespace).page(params[:page]).per(20) @projects = @projects.includes(:namespace).page(params[:page]).per(20)
......
class UsersController < ApplicationController class UsersController < ApplicationController
skip_before_filter :authenticate_user!, only: [:show] skip_before_filter :authenticate_user!, only: [:show]
layout :determine_layout layout :determine_layout
def show def show
@user = User.find_by_username!(params[:username]) @user = User.find_by_username!(params[:username])
@projects = @user.authorized_projects.includes(:namespace).select {|project| can?(current_user, :read_project, project)} @projects = @user.authorized_projects.accessible_to(current_user)
if !current_user && @projects.empty? if !current_user && @projects.empty?
return authenticate_user! return authenticate_user!
end end
@events = @user.recent_events.where(project_id: @projects.map(&:id)).limit(20) @groups = @user.groups.accessible_to(current_user)
@events = @user.recent_events.where(project_id: @projects.pluck(:id)).limit(20)
@title = @user.name @title = @user.name
end end
......
...@@ -7,6 +7,14 @@ module GroupsHelper ...@@ -7,6 +7,14 @@ module GroupsHelper
"Are you sure you want to leave \"#{group}\" group?" "Are you sure you want to leave \"#{group}\" group?"
end end
def should_user_see_group_roles?(user, group)
if user
user.is_admin? || group.members.exists?(user_id: user.id)
else
false
end
end
def group_head_title def group_head_title
title = @group.name title = @group.name
......
...@@ -4,8 +4,7 @@ module SearchHelper ...@@ -4,8 +4,7 @@ module SearchHelper
resources_results = [ resources_results = [
groups_autocomplete(term), groups_autocomplete(term),
projects_autocomplete(term), projects_autocomplete(term)
public_projects_autocomplete(term),
].flatten ].flatten
generic_results = project_autocomplete + default_autocomplete + help_autocomplete generic_results = project_autocomplete + default_autocomplete + help_autocomplete
...@@ -82,17 +81,7 @@ module SearchHelper ...@@ -82,17 +81,7 @@ module SearchHelper
# Autocomplete results for the current user's projects # Autocomplete results for the current user's projects
def projects_autocomplete(term, limit = 5) def projects_autocomplete(term, limit = 5)
current_user.authorized_projects.search_by_title(term).non_archived.limit(limit).map do |p| Project.accessible_to(current_user).search_by_title(term).non_archived.limit(limit).map do |p|
{
label: "project: #{search_result_sanitize(p.name_with_namespace)}",
url: project_path(p)
}
end
end
# Autocomplete results for the current user's projects
def public_projects_autocomplete(term, limit = 5)
Project.public_or_internal_only(current_user).search_by_title(term).non_archived.limit(limit).map do |p|
{ {
label: "project: #{search_result_sanitize(p.name_with_namespace)}", label: "project: #{search_result_sanitize(p.name_with_namespace)}",
url: project_path(p) url: project_path(p)
......
...@@ -42,10 +42,22 @@ class Ability ...@@ -42,10 +42,22 @@ class Ability
:read_note, :read_note,
:download_code :download_code
] ]
else
group = if subject.kind_of?(Group)
subject
elsif subject.respond_to?(:group)
subject.group
else
nil
end
if group && group.has_projects_accessible_to?(nil)
[:read_group]
else else
[] []
end end
end end
end
def global_abilities(user) def global_abilities(user)
rules = [] rules = []
...@@ -172,7 +184,7 @@ class Ability ...@@ -172,7 +184,7 @@ class Ability
def group_abilities user, group def group_abilities user, group
rules = [] rules = []
if group.users.include?(user) || user.admin? if user.admin? || group.users.include?(user) || group.has_projects_accessible_to?(user)
rules << :read_group rules << :read_group
end end
......
...@@ -26,6 +26,12 @@ class Group < Namespace ...@@ -26,6 +26,12 @@ class Group < Namespace
mount_uploader :avatar, AttachmentUploader mount_uploader :avatar, AttachmentUploader
def self.accessible_to(user)
accessible_ids = Project.accessible_to(user).pluck(:namespace_id)
accessible_ids += user.groups.pluck(:id) if user
where(id: accessible_ids)
end
def human_name def human_name
name name
end end
......
...@@ -48,6 +48,14 @@ class Namespace < ActiveRecord::Base ...@@ -48,6 +48,14 @@ class Namespace < ActiveRecord::Base
'GLN' 'GLN'
end end
def projects_accessible_to(user)
projects.accessible_to(user)
end
def has_projects_accessible_to?(user)
projects_accessible_to(user).present?
end
def to_param def to_param
path path
end end
......
...@@ -115,8 +115,6 @@ class Project < ActiveRecord::Base ...@@ -115,8 +115,6 @@ class Project < ActiveRecord::Base
scope :sorted_by_activity, -> { reorder("projects.last_activity_at DESC") } scope :sorted_by_activity, -> { reorder("projects.last_activity_at DESC") }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) } scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) } scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
scope :public_only, -> { where(visibility_level: PUBLIC) }
scope :public_or_internal_only, ->(user) { where("visibility_level IN (:levels)", levels: user ? [ INTERNAL, PUBLIC ] : [ PUBLIC ]) }
scope :non_archived, -> { where(archived: false) } scope :non_archived, -> { where(archived: false) }
...@@ -127,6 +125,18 @@ class Project < ActiveRecord::Base ...@@ -127,6 +125,18 @@ class Project < ActiveRecord::Base
where('projects.last_activity_at < ?', 6.months.ago) where('projects.last_activity_at < ?', 6.months.ago)
end end
def publicish(user)
visibility_levels = [Project::PUBLIC]
visibility_levels += [Project::INTERNAL] if user
where(visibility_level: visibility_levels)
end
def accessible_to(user)
accessible_ids = publicish(user).pluck(:id)
accessible_ids += user.authorized_projects.pluck(:id) if user
where(id: accessible_ids)
end
def with_push def with_push
includes(:events).where('events.action = ?', Event::PUSHED) includes(:events).where('events.action = ?', Event::PUSHED)
end end
......
...@@ -41,16 +41,16 @@ class FilteringService ...@@ -41,16 +41,16 @@ class FilteringService
def init_collection def init_collection
table_name = klass.table_name table_name = klass.table_name
return klass.of_projects(Project.public_only) unless current_user
if project if project
if current_user.can?(:read_project, project) if project.public? || (current_user && current_user.can?(:read_project, project))
project.send(table_name) project.send(table_name)
else else
[] []
end end
else elsif current_user && params[:authorized_only].presence
klass.of_projects(current_user.authorized_projects) klass.of_projects(current_user.authorized_projects)
else
klass.of_projects(Project.accessible_to(current_user))
end end
end end
......
...@@ -11,12 +11,8 @@ module Search ...@@ -11,12 +11,8 @@ module Search
query = Shellwords.shellescape(query) if query.present? query = Shellwords.shellescape(query) if query.present?
return result unless query.present? return result unless query.present?
authorized_projects_ids = []
authorized_projects_ids += current_user.authorized_projects.pluck(:id) if current_user
authorized_projects_ids += Project.public_or_internal_only(current_user).pluck(:id)
group = Group.find_by(id: params[:group_id]) if params[:group_id].present? group = Group.find_by(id: params[:group_id]) if params[:group_id].present?
projects = Project.where(id: authorized_projects_ids) projects = Project.accessible_to(current_user)
projects = projects.where(namespace_id: group.id) if group projects = projects.where(namespace_id: group.id) if group
projects = projects.search(query) projects = projects.search(query)
project_ids = projects.pluck(:id) project_ids = projects.pluck(:id)
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
%p.light %p.light
Only issues from Only issues from
%strong #{@group.name} %strong #{@group.name}
group are listed here. To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page. group are listed here.
- if current_user
To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page.
%hr %hr
.row .row
......
- show_roles = should_user_see_group_roles?(current_user, @group)
%h3.page-title %h3.page-title
Group members Group members
%p.light - if show_roles
%p.light
Members of group have access to all group projects. Members of group have access to all group projects.
Read more about permissions Read more about permissions
%strong= link_to "here", help_permissions_path, class: "vlink" %strong= link_to "here", help_permissions_path, class: "vlink"
...@@ -13,7 +15,7 @@ ...@@ -13,7 +15,7 @@
= search_field_tag :search, params[:search], { placeholder: 'Find member by name', class: 'form-control search-text-input input-mn-300' } = search_field_tag :search, params[:search], { placeholder: 'Find member by name', class: 'form-control search-text-input input-mn-300' }
= submit_tag 'Search', class: 'btn' = submit_tag 'Search', class: 'btn'
- if current_user.can? :manage_group, @group - if current_user && current_user.can?(:manage_group, @group)
.pull-right .pull-right
= link_to '#', class: 'btn btn-new js-toggle-visibility-link' do = link_to '#', class: 'btn btn-new js-toggle-visibility-link' do
Add members Add members
...@@ -30,7 +32,7 @@ ...@@ -30,7 +32,7 @@
(#{@members.total_count}) (#{@members.total_count})
%ul.well-list %ul.well-list
- @members.each do |member| - @members.each do |member|
= render 'users_groups/users_group', member: member, show_controls: true = render 'users_groups/users_group', member: member, show_roles: show_roles, show_controls: true
= paginate @members, theme: 'gitlab' = paginate @members, theme: 'gitlab'
:coffeescript :coffeescript
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
%p.light %p.light
Only merge requests from Only merge requests from
%strong #{@group.name} %strong #{@group.name}
group are listed here. To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page. group are listed here.
- if current_user
To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page.
%hr %hr
.row .row
.col-md-3 .col-md-3
......
.dashboard .dashboard
.activities.col-md-8.hidden-sm .activities.col-md-8.hidden-sm
- if current_user
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
= link_to dashboard_path, class: 'btn btn-tiny' do = link_to dashboard_path, class: 'btn btn-tiny' do
&larr; To dashboard &larr; To dashboard
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
- if @group.description.present? - if @group.description.present?
%p= @group.description %p= @group.description
= render "projects", projects: @projects = render "projects", projects: @projects
- if current_user
.prepend-top-20 .prepend-top-20
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed" do = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed" do
%strong %strong
......
...@@ -5,10 +5,12 @@ ...@@ -5,10 +5,12 @@
= nav_link(path: 'groups#issues') do = nav_link(path: 'groups#issues') do
= link_to issues_group_path(@group) do = link_to issues_group_path(@group) do
Issues Issues
- if current_user
%span.count= current_user.assigned_issues.opened.of_group(@group).count %span.count= current_user.assigned_issues.opened.of_group(@group).count
= nav_link(path: 'groups#merge_requests') do = nav_link(path: 'groups#merge_requests') do
= link_to merge_requests_group_path(@group) do = link_to merge_requests_group_path(@group) do
Merge Requests Merge Requests
- if current_user
%span.count= current_user.cared_merge_requests.opened.of_group(@group).count %span.count= current_user.cared_merge_requests.opened.of_group(@group).count
= nav_link(path: 'groups#members') do = nav_link(path: 'groups#members') do
= link_to "Members", members_group_path(@group) = link_to "Members", members_group_path(@group)
......
!!! 5
%html{ lang: "en"}
= render "layouts/head", title: group_head_title
%body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/broadcast"
= render "layouts/public_head_panel", title: "group: #{@group.name}"
%nav.main-nav.navbar-collapse.collapse
.container= render 'layouts/nav/group'
.container
.content= yield
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
= render "layouts/head", title: @project.name_with_namespace = render "layouts/head", title: @project.name_with_namespace
%body{class: "#{app_theme} application", :'data-page' => body_data_page} %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/public_head_panel", title: @project.name_with_namespace = render "layouts/public_head_panel", title: project_title(@project)
%nav.main-nav %nav.main-nav
.container= render 'layouts/nav/project' .container= render 'layouts/nav/project'
.container .container
......
.side-filters.hidden-xs.hidden-sm .side-filters.hidden-xs.hidden-sm
= form_tag filter_path(entity), method: 'get' do = form_tag filter_path(entity), method: 'get' do
- if current_user
%fieldset.scope-filter %fieldset.scope-filter
%ul.nav.nav-pills.nav-stacked %ul.nav.nav-pills.nav-stacked
%li{class: ("active" if params[:scope] == 'assigned-to-me')} %li{class: ("active" if params[:scope] == 'assigned-to-me')}
......
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
%small member since #{@user.created_at.stamp("Nov 12, 2031")} %small member since #{@user.created_at.stamp("Nov 12, 2031")}
.clearfix .clearfix
%h4 Groups: %h4 Groups:
= render 'groups', groups: @user.groups = render 'groups', groups: @groups
%hr %hr
%h4 User Activity: %h4 User Activity:
= render @events = render @events
.col-md-4 .col-md-4
= render 'profile', user: @user = render 'profile', user: @user
= render 'projects', user: @user = render 'projects'
- user = member.user - user = member.user
- return unless user - return unless user
- show_roles = true if show_roles.nil?
%li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)} %li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)}
= image_tag avatar_icon(user.email, 16), class: "avatar s16" = image_tag avatar_icon(user.email, 16), class: "avatar s16"
%strong= user.name %strong= user.name
...@@ -7,6 +8,7 @@ ...@@ -7,6 +8,7 @@
- if user == current_user - if user == current_user
%span.label.label-success It's you %span.label.label-success It's you
- if show_roles
%span.pull-right %span.pull-right
%strong= member.human_access %strong= member.human_access
- if show_controls - if show_controls
......
Feature: Public Projects Feature
Background:
Given group "TestGroup" has private project "Enterprise"
Scenario: I should not see group with private projects as visitor
When I visit group "TestGroup" page
Then I should be redirected to sign in page
Scenario: I should not see group with private projects group as user
When I sign in as a user
And I visit group "TestGroup" page
Then page status code should be 404
Scenario: I should not see group with private and internal projects as visitor
Given group "TestGroup" has internal project "Internal"
When I visit group "TestGroup" page
Then I should be redirected to sign in page
Scenario: I should see group with private and internal projects as user
Given group "TestGroup" has internal project "Internal"
When I sign in as a user
And I visit group "TestGroup" page
Then I should see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group issues for internal project as user
Given group "TestGroup" has internal project "Internal"
When I sign in as a user
And I visit group "TestGroup" issues page
And I change filter to Everyone's
Then I should see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group merge requests for internal project as user
Given group "TestGroup" has internal project "Internal"
When I sign in as a user
And I visit group "TestGroup" merge requests page
And I change filter to Everyone's
Then I should see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group's members as user
Given group "TestGroup" has internal project "Internal"
And "John Doe" is owner of group "TestGroup"
When I sign in as a user
And I visit group "TestGroup" members page
Then I should see group member "John Doe"
And I should not see member roles
Scenario: I should see group with private, internal and public projects as visitor
Given group "TestGroup" has internal project "Internal"
Given group "TestGroup" has public project "Community"
When I visit group "TestGroup" page
Then I should see project "Community" items
And I should not see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group issues for public project as visitor
Given group "TestGroup" has internal project "Internal"
Given group "TestGroup" has public project "Community"
When I visit group "TestGroup" issues page
Then I should see project "Community" items
And I should not see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group merge requests for public project as visitor
Given group "TestGroup" has internal project "Internal"
Given group "TestGroup" has public project "Community"
When I visit group "TestGroup" merge requests page
Then I should see project "Community" items
And I should not see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group's members as visitor
Given group "TestGroup" has internal project "Internal"
Given group "TestGroup" has public project "Community"
And "John Doe" is owner of group "TestGroup"
When I visit group "TestGroup" members page
Then I should see group member "John Doe"
And I should not see member roles
Scenario: I should see group with private, internal and public projects as user
Given group "TestGroup" has internal project "Internal"
Given group "TestGroup" has public project "Community"
When I sign in as a user
And I visit group "TestGroup" page
Then I should see project "Community" items
And I should see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group issues for internal and public projects as user
Given group "TestGroup" has internal project "Internal"
Given group "TestGroup" has public project "Community"
When I sign in as a user
And I visit group "TestGroup" issues page
And I change filter to Everyone's
Then I should see project "Community" items
And I should see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group merge requests for internal and public projects as user
Given group "TestGroup" has internal project "Internal"
Given group "TestGroup" has public project "Community"
When I sign in as a user
And I visit group "TestGroup" merge requests page
And I change filter to Everyone's
Then I should see project "Community" items
And I should see project "Internal" items
And I should not see project "Enterprise" items
Scenario: I should see group's members as user
Given group "TestGroup" has internal project "Internal"
Given group "TestGroup" has public project "Community"
And "John Doe" is owner of group "TestGroup"
When I sign in as a user
And I visit group "TestGroup" members page
Then I should see group member "John Doe"
And I should not see member roles
class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedGroup
include SharedProject
step 'group "TestGroup" has private project "Enterprise"' do
group_has_project("TestGroup", "Enterprise", Gitlab::VisibilityLevel::PRIVATE)
end
step 'group "TestGroup" has internal project "Internal"' do
group_has_project("TestGroup", "Internal", Gitlab::VisibilityLevel::INTERNAL)
end
step 'group "TestGroup" has public project "Community"' do
group_has_project("TestGroup", "Community", Gitlab::VisibilityLevel::PUBLIC)
end
step '"John Doe" is owner of group "TestGroup"' do
group = Group.find_by(name: "TestGroup") || create(:group, name: "TestGroup")
user = create(:user, name: "John Doe")
group.add_user(user, Gitlab::Access::OWNER)
end
step 'I visit group "TestGroup" page' do
visit group_path(Group.find_by(name: "TestGroup"))
end
step 'I visit group "TestGroup" issues page' do
visit issues_group_path(Group.find_by(name: "TestGroup"))
end
step 'I visit group "TestGroup" merge requests page' do
visit merge_requests_group_path(Group.find_by(name: "TestGroup"))
end
step 'I visit group "TestGroup" members page' do
visit members_group_path(Group.find_by(name: "TestGroup"))
end
step 'I should not see project "Enterprise" items' do
page.should_not have_content "Enterprise"
end
step 'I should see project "Internal" items' do
page.should have_content "Internal"
end
step 'I should not see project "Internal" items' do
page.should_not have_content "Internal"
end
step 'I should see project "Community" items' do
page.should have_content "Community"
end
step 'I change filter to Everyone\'s' do
click_link "Everyone's"
end
step 'I should see group member "John Doe"' do
page.should have_content "John Doe"
end
step 'I should not see member roles' do
page.body.should_not match(%r{owner|developer|reporter|guest}i)
end
protected
def group_has_project(groupname, projectname, visibility_level)
group = Group.find_by(name: groupname) || create(:group, name: groupname)
project = create(:project,
namespace: group,
name: projectname,
path: "#{groupname}-#{projectname}",
visibility_level: visibility_level
)
create(:issue,
title: "#{projectname} feature",
project: project
)
create(:merge_request,
title: "#{projectname} feature implemented",
source_project: project,
target_project: project
)
create(:closed_issue_event,
project: project
)
end
end
...@@ -14,6 +14,7 @@ describe "Group access" do ...@@ -14,6 +14,7 @@ describe "Group access" do
let(:master) { create(:user) } let(:master) { create(:user) }
let(:reporter) { create(:user) } let(:reporter) { create(:user) }
let(:guest) { create(:user) } let(:guest) { create(:user) }
let(:nonmember) { create(:user) }
before do before do
group.add_user(owner, Gitlab::Access::OWNER) group.add_user(owner, Gitlab::Access::OWNER)
...@@ -22,6 +23,11 @@ describe "Group access" do ...@@ -22,6 +23,11 @@ describe "Group access" do
group.add_user(guest, Gitlab::Access::GUEST) group.add_user(guest, Gitlab::Access::GUEST)
end end
describe "Group should not have accessible projects" do
it { group.has_projects_accessible_to?(nil).should be_false }
it { group.has_projects_accessible_to?(nonmember).should be_false }
end
describe "GET /groups/:path" do describe "GET /groups/:path" do
subject { group_path(group) } subject { group_path(group) }
......
require 'spec_helper'
describe "Group with internal project access" do
describe "Group" do
let(:group) { create(:group) }
let(:owner) { create(:owner) }
let(:master) { create(:user) }
let(:reporter) { create(:user) }
let(:guest) { create(:user) }
let(:nonmember) { create(:user) }
before do
group.add_user(owner, Gitlab::Access::OWNER)
group.add_user(master, Gitlab::Access::MASTER)
group.add_user(reporter, Gitlab::Access::REPORTER)
group.add_user(guest, Gitlab::Access::GUEST)
create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::INTERNAL)
end
describe "Group should have accessible projects for users" do
it { group.has_projects_accessible_to?(nil).should be_false }
it { group.has_projects_accessible_to?(nonmember).should be_true }
end
describe "GET /groups/:path" do
subject { group_path(group) }
it { should be_allowed_for 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_allowed_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 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_allowed_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 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_allowed_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 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_allowed_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 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
require 'spec_helper'
describe "Group access" do
describe "Group" do
let(:group) { create(:group) }
let(:owner) { create(:owner) }
let(:master) { create(:user) }
let(:reporter) { create(:user) }
let(:guest) { create(:user) }
let(:nonmember) { create(:user) }
before do
group.add_user(owner, Gitlab::Access::OWNER)
group.add_user(master, Gitlab::Access::MASTER)
group.add_user(reporter, Gitlab::Access::REPORTER)
group.add_user(guest, Gitlab::Access::GUEST)
create(:project, path: "internal_project", group: group, visibility_level: Gitlab::VisibilityLevel::INTERNAL)
create(:project, path: "public_project", group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
describe "Group should have accessible projects" do
it { group.has_projects_accessible_to?(nil).should be_true }
it { group.has_projects_accessible_to?(nonmember).should be_true }
end
describe "GET /groups/:path" do
subject { group_path(group) }
it { should be_allowed_for 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_allowed_for :user }
it { should be_allowed_for :visitor }
end
describe "GET /groups/:path/issues" do
subject { issues_group_path(group) }
it { should be_allowed_for 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_allowed_for :user }
it { should be_allowed_for :visitor }
end
describe "GET /groups/:path/merge_requests" do
subject { merge_requests_group_path(group) }
it { should be_allowed_for 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_allowed_for :user }
it { should be_allowed_for :visitor }
end
describe "GET /groups/:path/members" do
subject { members_group_path(group) }
it { should be_allowed_for 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_allowed_for :user }
it { should be_allowed_for :visitor }
end
describe "GET /groups/:path/edit" do
subject { edit_group_path(group) }
it { should be_allowed_for 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
require 'spec_helper'
describe "Group with public project access" do
describe "Group" do
let(:group) { create(:group) }
let(:owner) { create(:owner) }
let(:master) { create(:user) }
let(:reporter) { create(:user) }
let(:guest) { create(:user) }
let(:nonmember) { create(:user) }
before do
group.add_user(owner, Gitlab::Access::OWNER)
group.add_user(master, Gitlab::Access::MASTER)
group.add_user(reporter, Gitlab::Access::REPORTER)
group.add_user(guest, Gitlab::Access::GUEST)
create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
describe "Group should have accessible projects" do
it { group.has_projects_accessible_to?(nil).should be_true }
it { group.has_projects_accessible_to?(nonmember).should be_true }
end
describe "GET /groups/:path" do
subject { group_path(group) }
it { should be_allowed_for 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_allowed_for :user }
it { should be_allowed_for :visitor }
end
describe "GET /groups/:path/issues" do
subject { issues_group_path(group) }
it { should be_allowed_for 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_allowed_for :user }
it { should be_allowed_for :visitor }
end
describe "GET /groups/:path/merge_requests" do
subject { merge_requests_group_path(group) }
it { should be_allowed_for 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_allowed_for :user }
it { should be_allowed_for :visitor }
end
describe "GET /groups/:path/members" do
subject { members_group_path(group) }
it { should be_allowed_for 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_allowed_for :user }
it { should be_allowed_for :visitor }
end
describe "GET /groups/:path/edit" do
subject { edit_group_path(group) }
it { should be_allowed_for 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment