Commit e116a356 authored by Yorick Peterse's avatar Yorick Peterse

Refactor User#authorized_groups/projects

These methods no longer include public groups/projects (that don't
belong to the actual user) as this is handled by the various finder
classes now. This also removes the need for passing extra arguments.

Note that memoizing was removed _explicitly_. For whatever reason doing
so messes up the users controller to a point where it claims a certain
user does _not_ have access to certain groups/projects when it does have
access. Existing code shouldn't be affected as these methods are only
called in ways that they'd run queries anyway (e.g. a combination of
"any?" and "each" which would run 2 queries regardless of memoizing).
parent a4fc8112
......@@ -389,40 +389,17 @@ class User < ActiveRecord::Base
end
end
# Returns the groups a user has access to, optionally including any public
# groups.
#
# public_internal - When set to "true" all public groups and groups of public
# projects are also included.
#
# Returns an ActiveRecord::Relation
def authorized_groups(public_internal = false)
# Returns the groups a user has access to
def authorized_groups
union = Gitlab::SQL::Union.
new([groups.select(:id), authorized_projects(public_internal).
select(:namespace_id)])
sql = "namespaces.id IN (#{union.to_sql})"
if public_internal
sql << ' OR public IS TRUE'
end
new([groups.select(:id), authorized_projects.select(:namespace_id)])
Group.where(sql)
Group.where("namespaces.id IN (#{union.to_sql})")
end
# Returns the groups a user is authorized to access.
#
# public_internal - When set to "true" all public/internal projects will also
# be included.
def authorized_projects(public_internal = false)
base = "projects.id IN (#{projects_union.to_sql})"
if public_internal
Project.where("#{base} OR projects.visibility_level IN (?)",
Project.public_and_internal_levels)
else
Project.where(base)
end
def authorized_projects
Project.where("projects.id IN (#{projects_union.to_sql})")
end
def owned_projects
......
......@@ -762,44 +762,26 @@ describe User do
describe '#authorized_groups' do
let!(:user) { create(:user) }
let!(:private_group) { create(:group) }
let!(:public_group) { create(:group, public: true) }
before do
private_group.add_user(user, Gitlab::Access::MASTER)
end
describe 'excluding public groups' do
subject { user.authorized_groups }
subject { user.authorized_groups }
it { is_expected.to eq([private_group]) }
end
describe 'including public groups' do
subject { user.authorized_groups(true) }
it { is_expected.to eq([public_group, private_group]) }
end
it { is_expected.to eq([private_group]) }
end
describe '#authorized_projects' do
let!(:user) { create(:user) }
let!(:private_project) { create(:project, :private) }
let!(:public_project) { create(:project, :public) }
before do
private_project.team << [user, Gitlab::Access::MASTER]
end
describe 'excluding public projects' do
subject { user.authorized_projects }
subject { user.authorized_projects }
it { is_expected.to eq([private_project]) }
end
describe 'including public projects' do
subject { user.authorized_projects(true) }
it { is_expected.to eq([public_project, private_project]) }
end
it { is_expected.to eq([private_project]) }
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