Commit 2f69213e authored by Jason Hollingsworth's avatar Jason Hollingsworth

Allow access to groups with public projects.

Fixed Group avatars to only display when user has read
permissions to at least one project in the group.
parent 138e2a50
...@@ -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,17 +99,21 @@ class GroupsController < ApplicationController ...@@ -98,17 +99,21 @@ 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))
return render_404 if current_user.nil?
return authenticate_user!
else
return render_404
end
end end
end end
...@@ -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
......
...@@ -6,6 +6,14 @@ module GroupsHelper ...@@ -6,6 +6,14 @@ module GroupsHelper
def leave_group_message(group) def leave_group_message(group)
"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)
......
...@@ -43,7 +43,19 @@ class Ability ...@@ -43,7 +43,19 @@ class Ability
:download_code :download_code
] ]
else 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
[]
end
end end
end end
...@@ -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
......
...@@ -25,6 +25,12 @@ class Group < Namespace ...@@ -25,6 +25,12 @@ class Group < Namespace
validates :avatar, file_size: { maximum: 100.kilobytes.to_i } validates :avatar, file_size: { maximum: 100.kilobytes.to_i }
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
......
...@@ -47,6 +47,14 @@ class Namespace < ActiveRecord::Base ...@@ -47,6 +47,14 @@ class Namespace < ActiveRecord::Base
def self.global_id def self.global_id
'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
......
...@@ -114,8 +114,6 @@ class Project < ActiveRecord::Base ...@@ -114,8 +114,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) }
...@@ -125,6 +123,18 @@ class Project < ActiveRecord::Base ...@@ -125,6 +123,18 @@ class Project < ActiveRecord::Base
def abandoned def abandoned
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)
......
...@@ -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
Members of group have access to all group projects. %p.light
Read more about permissions Members of group have access to all group projects.
%strong= link_to "here", help_permissions_path, class: "vlink" Read more about permissions
%strong= link_to "here", help_permissions_path, class: "vlink"
%hr %hr
...@@ -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
= render "events/event_last_push", event: @last_push - if current_user
= link_to dashboard_path, class: 'btn btn-tiny' do = render "events/event_last_push", event: @last_push
&larr; To dashboard = link_to dashboard_path, class: 'btn btn-tiny' do
&nbsp; &larr; To dashboard
&nbsp;
%span.cgray You will only see events from projects in this group %span.cgray You will only see events from projects in this group
%hr %hr
= render 'shared/event_filter' = render 'shared/event_filter'
...@@ -21,11 +22,12 @@ ...@@ -21,11 +22,12 @@
- if @group.description.present? - if @group.description.present?
%p= @group.description %p= @group.description
= render "projects", projects: @projects = render "projects", projects: @projects
.prepend-top-20 - if current_user
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed" do .prepend-top-20
%strong = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed" do
%i.icon-rss %strong
News Feed %i.icon-rss
News Feed
%hr %hr
= render 'shared/promo' = render 'shared/promo'
...@@ -5,11 +5,13 @@ ...@@ -5,11 +5,13 @@
= 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
%span.count= current_user.assigned_issues.opened.of_group(@group).count - if current_user
%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
%span.count= current_user.cared_merge_requests.opened.of_group(@group).count - if current_user
%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
%fieldset.scope-filter - if current_user
%ul.nav.nav-pills.nav-stacked %fieldset.scope-filter
%li{class: ("active" if params[:scope] == 'assigned-to-me')} %ul.nav.nav-pills.nav-stacked
= link_to filter_path(entity, scope: 'assigned-to-me') do %li{class: ("active" if params[:scope] == 'assigned-to-me')}
Assigned to me = link_to filter_path(entity, scope: 'assigned-to-me') do
%li{class: ("active" if params[:scope] == 'authored')} Assigned to me
= link_to filter_path(entity, scope: 'authored') do %li{class: ("active" if params[:scope] == 'authored')}
Created by me = link_to filter_path(entity, scope: 'authored') do
%li{class: ("active" if params[:scope] == 'all')} Created by me
= link_to filter_path(entity, scope: 'all') do %li{class: ("active" if params[:scope] == 'all')}
Everyone's = link_to filter_path(entity, scope: 'all') do
Everyone's
%fieldset.status-filter %fieldset.status-filter
%legend State %legend State
......
...@@ -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,22 +8,23 @@ ...@@ -7,22 +8,23 @@
- if user == current_user - if user == current_user
%span.label.label-success It's you %span.label.label-success It's you
%span.pull-right - if show_roles
%strong= member.human_access %span.pull-right
- if show_controls %strong= member.human_access
- if can?(current_user, :modify, member) - if show_controls
= link_to '#', class: "btn-tiny btn js-toggle-button", title: 'Edit access level' do - if can?(current_user, :modify, member)
%i.icon-edit = link_to '#', class: "btn-tiny btn js-toggle-button", title: 'Edit access level' do
- if can?(current_user, :destroy, member) %i.icon-edit
- if current_user == member.user - if can?(current_user, :destroy, member)
= link_to leave_profile_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do - if current_user == member.user
%i.icon-minus.icon-white = link_to leave_profile_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
- else %i.icon-minus.icon-white
= link_to group_users_group_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do - else
%i.icon-minus.icon-white = link_to group_users_group_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
%i.icon-minus.icon-white
.edit-member.hide.js-toggle-content
= form_for [@group, member], remote: true do |f| .edit-member.hide.js-toggle-content
.alert.prepend-top-20 = form_for [@group, member], remote: true do |f|
= f.select :group_access, options_for_select(UsersGroup.group_access_roles, member.group_access) .alert.prepend-top-20
= f.submit 'Save', class: 'btn btn-save btn-small' = f.select :group_access, options_for_select(UsersGroup.group_access_roles, member.group_access)
= f.submit 'Save', class: 'btn btn-save btn-small'
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)
...@@ -21,6 +22,11 @@ describe "Group access" do ...@@ -21,6 +22,11 @@ describe "Group access" do
group.add_user(reporter, Gitlab::Access::REPORTER) group.add_user(reporter, Gitlab::Access::REPORTER)
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