diff options
author | Andreas Brandl <abrandl@gitlab.com> | 2018-03-02 16:01:06 +0100 |
---|---|---|
committer | Andreas Brandl <abrandl@gitlab.com> | 2018-03-07 19:14:07 +0100 |
commit | c4161ab0d6f168ab6bc859aa40022c327dd65c2c (patch) | |
tree | 8bef188d5e837f1eca2b9883b3409224772d6f7f | |
parent | e6c74e8cddc626acd326db7b45ceaf2469c56a31 (diff) | |
download | gitlab-ce-42877-for-10-5.tar.gz |
Extract method User#authorizations_for_projects.42877-for-10-5
-rw-r--r-- | app/finders/snippets_finder.rb | 6 | ||||
-rw-r--r-- | app/models/project.rb | 16 | ||||
-rw-r--r-- | app/models/user.rb | 9 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 26 |
4 files changed, 40 insertions, 17 deletions
diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb index 8d7c15f5bea..0048e684c13 100644 --- a/app/finders/snippets_finder.rb +++ b/app/finders/snippets_finder.rb @@ -69,11 +69,7 @@ class SnippetsFinder < UnionFinder # we can shortcut and just return. return yield(Project.all) if current_user.full_private_access? - authorized = current_user - .project_authorizations - .select(1) - .where('project_authorizations.project_id = projects.id') - authorized_projects = yield(Project.where('EXISTS (?)', authorized)) + authorized_projects = yield(Project.where('EXISTS (?)', current_user.authorizations_for_projects)) levels = Gitlab::VisibilityLevel.levels_for_user(current_user) visible_projects = yield(Project.where(visibility_level: levels)) diff --git a/app/models/project.rb b/app/models/project.rb index 2ba6a863500..194e9a2593b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -318,14 +318,9 @@ class Project < ActiveRecord::Base # logged in user. def self.public_or_visible_to_user(user = nil) if user - authorized = user - .project_authorizations - .select(1) - .where('project_authorizations.project_id = projects.id') - - levels = Gitlab::VisibilityLevel.levels_for_user(user) - - where('EXISTS (?) OR projects.visibility_level IN (?)', authorized, levels) + where('EXISTS (?) OR projects.visibility_level IN (?)', + user.authorizations_for_projects, + Gitlab::VisibilityLevel.levels_for_user(user)) else public_to_user end @@ -346,14 +341,11 @@ class Project < ActiveRecord::Base elsif user column = ProjectFeature.quoted_access_level_column(feature) - authorized = user.project_authorizations.select(1) - .where('project_authorizations.project_id = projects.id') - with_project_feature .where("#{column} IN (?) OR (#{column} = ? AND EXISTS (?))", visible, ProjectFeature::PRIVATE, - authorized) + user.authorizations_for_projects) else with_feature_access_level(feature, visible) end diff --git a/app/models/user.rb b/app/models/user.rb index e81e555c090..9093ba2a04f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -596,6 +596,15 @@ class User < ActiveRecord::Base authorized_projects(min_access_level).exists?({ id: project.id }) 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 # to at most the given projects. # diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index dd1bfba1421..970a5ed056e 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1604,6 +1604,32 @@ describe User do it { is_expected.to eq([private_group]) } 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 context 'with a minimum access level' do it 'includes projects for which the user is an owner' do |