Commit 31594149 authored by Andreas Brandl's avatar Andreas Brandl
Browse files

Extract method User#authorizations_for_projects.

parent 7fb675d7d82e
...@@ -72,11 +72,7 @@ def projects_for_user ...@@ -72,11 +72,7 @@ def projects_for_user
# we can shortcut and just return. # we can shortcut and just return.
return yield(Project.all) if current_user.full_private_access? return yield(Project.all) if current_user.full_private_access?
authorized = current_user authorized_projects = yield(Project.where('EXISTS (?)', current_user.authorizations_for_projects))
.project_authorizations
.select(1)
.where('project_authorizations.project_id = projects.id')
authorized_projects = yield(Project.where('EXISTS (?)', authorized))
levels = Gitlab::VisibilityLevel.levels_for_user(current_user) levels = Gitlab::VisibilityLevel.levels_for_user(current_user)
visible_projects = yield(Project.where(visibility_level: levels)) visible_projects = yield(Project.where(visibility_level: levels))
......
...@@ -319,14 +319,9 @@ class Project < ActiveRecord::Base ...@@ -319,14 +319,9 @@ class Project < ActiveRecord::Base
# logged in user. # logged in user.
def self.public_or_visible_to_user(user = nil) def self.public_or_visible_to_user(user = nil)
if user if user
authorized = user where('EXISTS (?) OR projects.visibility_level IN (?)',
.project_authorizations user.authorizations_for_projects,
.select(1) Gitlab::VisibilityLevel.levels_for_user(user))
.where('project_authorizations.project_id = projects.id')
levels = Gitlab::VisibilityLevel.levels_for_user(user)
where('EXISTS (?) OR projects.visibility_level IN (?)', authorized, levels)
else else
public_to_user public_to_user
end end
...@@ -347,14 +342,11 @@ def self.with_feature_available_for_user(feature, user) ...@@ -347,14 +342,11 @@ def self.with_feature_available_for_user(feature, user)
elsif user elsif user
column = ProjectFeature.quoted_access_level_column(feature) column = ProjectFeature.quoted_access_level_column(feature)
authorized = user.project_authorizations.select(1)
.where('project_authorizations.project_id = projects.id')
with_project_feature with_project_feature
.where("#{column} IN (?) OR (#{column} = ? AND EXISTS (?))", .where("#{column} IN (?) OR (#{column} = ? AND EXISTS (?))",
visible, visible,
ProjectFeature::PRIVATE, ProjectFeature::PRIVATE,
authorized) user.authorizations_for_projects)
else else
with_feature_access_level(feature, visible) with_feature_access_level(feature, visible)
end end
......
...@@ -601,6 +601,15 @@ def authorized_project?(project, min_access_level = nil) ...@@ -601,6 +601,15 @@ def authorized_project?(project, min_access_level = nil)
authorized_projects(min_access_level).exists?({ id: project.id }) authorized_projects(min_access_level).exists?({ id: project.id })
end end
# Typically used in conjunction with projects table to get projects
# a user has been given access to.
#
# Example use:
# `Project.where('EXISTS(?)', user.authorizations_for_projects)`
def authorizations_for_projects
project_authorizations.select(1).where('project_authorizations.project_id = projects.id')
end
# Returns the projects this user has reporter (or greater) access to, limited # Returns the projects this user has reporter (or greater) access to, limited
# to at most the given projects. # to at most the given projects.
# #
......
...@@ -1635,6 +1635,32 @@ ...@@ -1635,6 +1635,32 @@
end end
end end
describe '#authorizations_for_projects' do
let!(:user) { create(:user) }
subject { Project.where("EXISTS (?)", user.authorizations_for_projects) }
it 'includes projects that belong to a user, but no other projects' do
owned = create(:project, :private, namespace: user.namespace)
member = create(:project, :private).tap { |p| p.add_master(user) }
other = create(:project)
expect(subject).to include(owned)
expect(subject).to include(member)
expect(subject).not_to include(other)
end
it 'includes projects a user has access to, but no other projects' do
other_user = create(:user)
accessible = create(:project, :private, namespace: other_user.namespace) do |project|
project.add_developer(user)
end
other = create(:project)
expect(subject).to include(accessible)
expect(subject).not_to include(other)
end
end
describe '#authorized_projects', :delete do describe '#authorized_projects', :delete do
context 'with a minimum access level' do context 'with a minimum access level' do
it 'includes projects for which the user is an owner' do it 'includes projects for which the user is an owner' do
......
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