mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-20 14:11:11 +00:00
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.
This commit is contained in:
@ -77,5 +77,6 @@ class DashboardController < ApplicationController
|
||||
def default_filter
|
||||
params[:scope] = 'assigned-to-me' if params[:scope].blank?
|
||||
params[:state] = 'opened' if params[:state].blank?
|
||||
params[:authorized_only] = true
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,5 @@
|
||||
class GroupsController < ApplicationController
|
||||
skip_before_filter :authenticate_user!, only: [:show, :issues, :members, :merge_requests]
|
||||
respond_to :html
|
||||
before_filter :group, except: [:new, :create]
|
||||
|
||||
@ -36,7 +37,7 @@ class GroupsController < ApplicationController
|
||||
@events = Event.in_projects(project_ids)
|
||||
@events = event_filter.apply_filter(@events)
|
||||
@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|
|
||||
format.html
|
||||
@ -98,19 +99,23 @@ class GroupsController < ApplicationController
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def project_ids
|
||||
projects.map(&:id)
|
||||
projects.pluck(:id)
|
||||
end
|
||||
|
||||
# Dont allow unauthorized access to group
|
||||
def authorize_read_group!
|
||||
unless @group and (projects.present? or can?(current_user, :read_group, @group))
|
||||
if current_user.nil?
|
||||
return authenticate_user!
|
||||
else
|
||||
return render_404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def authorize_create_group!
|
||||
unless can?(current_user, :create_group, nil)
|
||||
@ -131,13 +136,21 @@ class GroupsController < ApplicationController
|
||||
def determine_layout
|
||||
if [:new, :create].include?(action_name.to_sym)
|
||||
'navless'
|
||||
else
|
||||
elsif current_user
|
||||
'group'
|
||||
else
|
||||
'public_group'
|
||||
end
|
||||
end
|
||||
|
||||
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[:group_id] = @group.id
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ class Public::ProjectsController < ApplicationController
|
||||
layout 'public'
|
||||
|
||||
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.sort(@sort = params[:sort])
|
||||
@projects = @projects.includes(:namespace).page(params[:page]).per(20)
|
||||
|
@ -1,15 +1,15 @@
|
||||
class UsersController < ApplicationController
|
||||
|
||||
skip_before_filter :authenticate_user!, only: [:show]
|
||||
layout :determine_layout
|
||||
|
||||
def show
|
||||
@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?
|
||||
return authenticate_user!
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -7,6 +7,14 @@ module GroupsHelper
|
||||
"Are you sure you want to leave \"#{group}\" group?"
|
||||
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
|
||||
title = @group.name
|
||||
|
||||
|
@ -4,8 +4,7 @@ module SearchHelper
|
||||
|
||||
resources_results = [
|
||||
groups_autocomplete(term),
|
||||
projects_autocomplete(term),
|
||||
public_projects_autocomplete(term),
|
||||
projects_autocomplete(term)
|
||||
].flatten
|
||||
|
||||
generic_results = project_autocomplete + default_autocomplete + help_autocomplete
|
||||
@ -82,17 +81,7 @@ module SearchHelper
|
||||
|
||||
# Autocomplete results for the current user's projects
|
||||
def projects_autocomplete(term, limit = 5)
|
||||
current_user.authorized_projects.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|
|
||||
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)
|
||||
|
@ -42,10 +42,22 @@ class Ability
|
||||
:read_note,
|
||||
: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
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def global_abilities(user)
|
||||
rules = []
|
||||
@ -172,7 +184,7 @@ class Ability
|
||||
def group_abilities user, group
|
||||
rules = []
|
||||
|
||||
if group.users.include?(user) || user.admin?
|
||||
if user.admin? || group.users.include?(user) || group.has_projects_accessible_to?(user)
|
||||
rules << :read_group
|
||||
end
|
||||
|
||||
|
@ -26,6 +26,12 @@ class Group < Namespace
|
||||
|
||||
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
|
||||
name
|
||||
end
|
||||
|
@ -48,6 +48,14 @@ class Namespace < ActiveRecord::Base
|
||||
'GLN'
|
||||
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
|
||||
path
|
||||
end
|
||||
|
@ -114,8 +114,6 @@ class Project < ActiveRecord::Base
|
||||
scope :sorted_by_activity, -> { reorder("projects.last_activity_at DESC") }
|
||||
scope :personal, ->(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) }
|
||||
|
||||
@ -126,6 +124,18 @@ class Project < ActiveRecord::Base
|
||||
where('projects.last_activity_at < ?', 6.months.ago)
|
||||
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
|
||||
includes(:events).where('events.action = ?', Event::PUSHED)
|
||||
end
|
||||
|
@ -41,16 +41,16 @@ class FilteringService
|
||||
def init_collection
|
||||
table_name = klass.table_name
|
||||
|
||||
return klass.of_projects(Project.public_only) unless current_user
|
||||
|
||||
if project
|
||||
if current_user.can?(:read_project, project)
|
||||
if project.public? || (current_user && current_user.can?(:read_project, project))
|
||||
project.send(table_name)
|
||||
else
|
||||
[]
|
||||
end
|
||||
else
|
||||
elsif current_user && params[:authorized_only].presence
|
||||
klass.of_projects(current_user.authorized_projects)
|
||||
else
|
||||
klass.of_projects(Project.accessible_to(current_user))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -11,12 +11,8 @@ module Search
|
||||
query = Shellwords.shellescape(query) if 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?
|
||||
projects = Project.where(id: authorized_projects_ids)
|
||||
projects = Project.accessible_to(current_user)
|
||||
projects = projects.where(namespace_id: group.id) if group
|
||||
projects = projects.search(query)
|
||||
project_ids = projects.pluck(:id)
|
||||
|
@ -5,7 +5,9 @@
|
||||
%p.light
|
||||
Only issues from
|
||||
%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
|
||||
|
||||
.row
|
||||
|
@ -1,5 +1,7 @@
|
||||
- show_roles = should_user_see_group_roles?(current_user, @group)
|
||||
%h3.page-title
|
||||
Group members
|
||||
- if show_roles
|
||||
%p.light
|
||||
Members of group have access to all group projects.
|
||||
Read more about permissions
|
||||
@ -13,7 +15,7 @@
|
||||
= 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'
|
||||
|
||||
- if current_user.can? :manage_group, @group
|
||||
- if current_user && current_user.can?(:manage_group, @group)
|
||||
.pull-right
|
||||
= link_to '#', class: 'btn btn-new js-toggle-visibility-link' do
|
||||
Add members
|
||||
@ -30,7 +32,7 @@
|
||||
(#{@members.total_count})
|
||||
%ul.well-list
|
||||
- @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'
|
||||
|
||||
:coffeescript
|
||||
|
@ -5,7 +5,9 @@
|
||||
%p.light
|
||||
Only merge requests from
|
||||
%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
|
||||
.row
|
||||
.col-md-3
|
||||
|
@ -1,5 +1,6 @@
|
||||
.dashboard
|
||||
.activities.col-md-8.hidden-sm
|
||||
- if current_user
|
||||
= render "events/event_last_push", event: @last_push
|
||||
= link_to dashboard_path, class: 'btn btn-tiny' do
|
||||
← To dashboard
|
||||
@ -21,6 +22,7 @@
|
||||
- if @group.description.present?
|
||||
%p= @group.description
|
||||
= render "projects", projects: @projects
|
||||
- if current_user
|
||||
.prepend-top-20
|
||||
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed" do
|
||||
%strong
|
||||
|
@ -5,10 +5,12 @@
|
||||
= nav_link(path: 'groups#issues') do
|
||||
= link_to issues_group_path(@group) do
|
||||
Issues
|
||||
- if current_user
|
||||
%span.count= current_user.assigned_issues.opened.of_group(@group).count
|
||||
= nav_link(path: 'groups#merge_requests') do
|
||||
= link_to merge_requests_group_path(@group) do
|
||||
Merge Requests
|
||||
- if current_user
|
||||
%span.count= current_user.cared_merge_requests.opened.of_group(@group).count
|
||||
= nav_link(path: 'groups#members') do
|
||||
= link_to "Members", members_group_path(@group)
|
||||
|
10
app/views/layouts/public_group.html.haml
Normal file
10
app/views/layouts/public_group.html.haml
Normal file
@ -0,0 +1,10 @@
|
||||
!!! 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 @@
|
||||
= render "layouts/head", title: @project.name_with_namespace
|
||||
%body{class: "#{app_theme} application", :'data-page' => body_data_page}
|
||||
= 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
|
||||
.container= render 'layouts/nav/project'
|
||||
.container
|
||||
|
@ -1,5 +1,6 @@
|
||||
.side-filters.hidden-xs.hidden-sm
|
||||
= form_tag filter_path(entity), method: 'get' do
|
||||
- if current_user
|
||||
%fieldset.scope-filter
|
||||
%ul.nav.nav-pills.nav-stacked
|
||||
%li{class: ("active" if params[:scope] == 'assigned-to-me')}
|
||||
|
@ -14,10 +14,10 @@
|
||||
%small member since #{@user.created_at.stamp("Nov 12, 2031")}
|
||||
.clearfix
|
||||
%h4 Groups:
|
||||
= render 'groups', groups: @user.groups
|
||||
= render 'groups', groups: @groups
|
||||
%hr
|
||||
%h4 User Activity:
|
||||
= render @events
|
||||
.col-md-4
|
||||
= render 'profile', user: @user
|
||||
= render 'projects', user: @user
|
||||
= render 'projects'
|
||||
|
@ -1,5 +1,6 @@
|
||||
- user = member.user
|
||||
- return unless user
|
||||
- show_roles = true if show_roles.nil?
|
||||
%li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)}
|
||||
= image_tag avatar_icon(user.email, 16), class: "avatar s16"
|
||||
%strong= user.name
|
||||
@ -7,6 +8,7 @@
|
||||
- if user == current_user
|
||||
%span.label.label-success It's you
|
||||
|
||||
- if show_roles
|
||||
%span.pull-right
|
||||
%strong= member.human_access
|
||||
- if show_controls
|
||||
|
118
features/public/public_groups.feature
Normal file
118
features/public/public_groups.feature
Normal file
@ -0,0 +1,118 @@
|
||||
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
|
93
features/steps/public/groups_feature.rb
Normal file
93
features/steps/public/groups_feature.rb
Normal file
@ -0,0 +1,93 @@
|
||||
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
|
||||
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)
|
||||
@ -22,6 +23,11 @@ describe "Group access" do
|
||||
group.add_user(guest, Gitlab::Access::GUEST)
|
||||
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
|
||||
subject { group_path(group) }
|
||||
|
87
spec/features/security/group/internal_group_access_spec.rb
Normal file
87
spec/features/security/group/internal_group_access_spec.rb
Normal file
@ -0,0 +1,87 @@
|
||||
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
|
88
spec/features/security/group/mixed_group_access_spec.rb
Normal file
88
spec/features/security/group/mixed_group_access_spec.rb
Normal file
@ -0,0 +1,88 @@
|
||||
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
|
87
spec/features/security/group/public_group_access_spec.rb
Normal file
87
spec/features/security/group/public_group_access_spec.rb
Normal file
@ -0,0 +1,87 @@
|
||||
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
|
Reference in New Issue
Block a user