This instance will be upgraded to Heptapod 0.27.1 on 2021-12-08 at 22:00 UTC+1 (a few minutes of down time)

Unverified Commit 75eed4eb authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Implement project collection service



Main purpose is move big amount of methods from user, group, project
models and place filtering logic in one place.
It also fixes 500 error on group page for PostgreSQL
Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parent 5a08ee55f4de
......@@ -99,7 +99,7 @@ def group
end
def projects
@projects ||= group.projects_accessible_to(current_user).sorted_by_activity
@projects ||= Projects::CollectService.new.execute(current_user, group: group)
end
def project_ids
......
......@@ -50,7 +50,7 @@ def not_auth_abilities(user, subject)
else
nil
end
if group && group.has_projects_accessible_to?(nil)
[:read_group]
else
......@@ -184,7 +184,7 @@ def project_admin_rules
def group_abilities user, group
rules = []
if user.admin? || group.users.include?(user) || group.has_projects_accessible_to?(user)
if user.admin? || Projects::CollectService.new.execute(user, group: group).any?
rules << :read_group
end
......
......@@ -116,21 +116,28 @@ class Project < ActiveRecord::Base
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
scope :public_only, -> { where(visibility_level: Project::PUBLIC) }
scope :public_and_internal_only, -> { where(visibility_level: Project.public_and_internal_levels) }
scope :non_archived, -> { where(archived: false) }
enumerize :issues_tracker, in: (Gitlab.config.issues_tracker.keys).append(:gitlab), default: :gitlab
class << self
def public_and_internal_levels
[Project::PUBLIC, Project::INTERNAL]
end
def abandoned
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
......
# Projects::CollectService class
#
# Used to collect projects user has access to
#
module Projects
class CollectService
def execute(current_user, options)
group = options[:group]
if group
group_projects(current_user, group)
else
all_projects(current_user)
end
end
private
def group_projects(current_user, group)
if current_user
if group.users.include?(current_user)
# User is group member
#
# Return ALL group projects
group.projects
else
projects_members = UsersProject.where(
project_id: group.projects,
user_id: current_user
)
if projects_members.any?
# User is a project member
#
# Return only:
# public projects
# internal projects
# joined projects
#
group.projects.where(
"projects.id IN (?) OR projects.visibility_level IN (?)",
projects_members.pluck(:project_id),
Project.public_and_internal_levels
)
else
# User has no access to group or group projects
#
# Return only:
# public projects
# internal projects
#
group.projects.public_and_internal_only
end
end
else
# Not authenticated
#
# Return only:
# public projects
group.projects.public_only
end
end
end
def all_projects
# TODO: implement
raise 'Not implemented yet'
end
end
require 'spec_helper'
describe Projects::CollectService do
let(:user) { create :user }
let(:group) { create :group }
let(:project1) { create(:empty_project, group: group, visibility_level: Project::PUBLIC) }
let(:project2) { create(:empty_project, group: group, visibility_level: Project::INTERNAL) }
let(:project3) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) }
let(:project4) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) }
context 'non authenticated' do
subject { Projects::CollectService.new.execute(nil, group: group) }
it { should include(project1) }
it { should_not include(project2) }
it { should_not include(project3) }
it { should_not include(project4) }
end
context 'authenticated' do
subject { Projects::CollectService.new.execute(user, group: group) }
it { should include(project1) }
it { should include(project2) }
it { should_not include(project3) }
it { should_not include(project4) }
end
context 'authenticated, project member' do
before { project3.team << [user, :developer] }
subject { Projects::CollectService.new.execute(user, group: group) }
it { should include(project1) }
it { should include(project2) }
it { should include(project3) }
it { should_not include(project4) }
end
context 'authenticated, group member' do
before { group.add_user(user, Gitlab::Access::DEVELOPER) }
subject { Projects::CollectService.new.execute(user, group: group) }
it { should include(project1) }
it { should include(project2) }
it { should include(project3) }
it { should include(project4) }
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