diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index c17c6f9694ae13a9357924919cd2036c946b87c2..0b442f5383a2ed8f9f0b4d48841d08cee15be404 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -4,15 +4,24 @@ class UsersController < ApplicationController def show @user = User.find_by_username!(params[:username]) - @projects = Project.personal(@user).accessible_to(current_user) unless current_user || @user.public_profile? return authenticate_user! end - @groups = @user.groups.accessible_to(current_user) - accessible_projects = @user.authorized_projects.accessible_to(current_user) - @events = @user.recent_events.where(project_id: accessible_projects.pluck(:id)).limit(20) + # Projects user can view + authorized_projects_ids = ProjectsFinder.new.execute(current_user).pluck(:id) + + @projects = @user.personal_projects. + where(id: authorized_projects_ids) + + # Collect only groups common for both users + @groups = @user.groups & GroupsFinder.new.execute(current_user) + + # Get user activity feed for projects common for both users + @events = @user.recent_events. + where(project_id: authorized_projects_ids).limit(20) + @title = @user.name end diff --git a/app/finders/base_finder.rb b/app/finders/base_finder.rb index 7fc5840561cb7748e71bfbef1dee83ba202fed83..7150bb2e31b1ee24640bcfdbc84d238c8c6c0da1 100644 --- a/app/finders/base_finder.rb +++ b/app/finders/base_finder.rb @@ -49,7 +49,7 @@ class BaseFinder elsif current_user && params[:authorized_only].presence klass.of_projects(current_user.authorized_projects).references(:project) else - klass.of_projects(Project.accessible_to(current_user)).references(:project) + klass.of_projects(ProjectsFinder.new.execute(current_user)).references(:project) end end diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb new file mode 100644 index 0000000000000000000000000000000000000000..d3597ef090192ee01f5380c84344df1303ed7b79 --- /dev/null +++ b/app/finders/groups_finder.rb @@ -0,0 +1,38 @@ +class GroupsFinder + def execute(current_user, options = {}) + all_groups(current_user) + end + + private + + def all_groups(current_user) + if current_user + if current_user.authorized_groups.any? + # User has access to groups + # + # Return only: + # groups with public projects + # groups with internal projects + # groups with joined projects + # + group_ids = Project.public_and_internal_only.pluck(:namespace_id) + + current_user.authorized_groups.pluck(:id) + Group.where(id: group_ids) + else + # User has no group membership + # + # Return only: + # groups with public projects + # groups with internal projects + # + Group.where(id: Project.public_and_internal_only.pluck(:namespace_id)) + end + else + # Not authenticated + # + # Return only: + # groups with public projects + Group.where(id: Project.public_only.pluck(:namespace_id)) + end + end +end diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index bfaba7587884bb6aea7b979fa1641edd4e8e9f2e..26898bad493283c69308770ac095a60534cb41fa 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -1,5 +1,5 @@ class ProjectsFinder - def execute(current_user, options) + def execute(current_user, options = {}) group = options[:group] if group @@ -56,8 +56,36 @@ class ProjectsFinder end end - def all_projects - # TODO: implement - raise 'Not implemented yet' + def all_projects(current_user) + if current_user + if current_user.authorized_projects.any? + # User has access to private projects + # + # Return only: + # public projects + # internal projects + # joined projects + # + Project.where( + "projects.id IN (?) OR projects.visibility_level IN (?)", + current_user.authorized_projects.pluck(:id), + Project.public_and_internal_levels + ) + else + # User has no access to private projects + # + # Return only: + # public projects + # internal projects + # + Project.public_and_internal_only + end + else + # Not authenticated + # + # Return only: + # public projects + Project.public_only + end end end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 01c31205695ed5f2dcbb25c5dd26068ec52797dc..a4471507da888fadfc1f4a144941914789279699 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -81,7 +81,7 @@ module SearchHelper # Autocomplete results for the current user's projects def projects_autocomplete(term, limit = 5) - Project.accessible_to(current_user).search_by_title(term).non_archived.limit(limit).map do |p| + ProjectsFinder.new.execute(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) diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb old mode 100755 new mode 100644 diff --git a/app/models/ability.rb b/app/models/ability.rb index df9b210dfca1e9eb2d7665de7176571e2ab2a5fd..c60aa2d622e841e912a1544f117fb49e5b61fad0 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -51,7 +51,7 @@ class Ability nil end - if group && group.has_projects_accessible_to?(nil) + if group && group.public_profile? [:read_group] else [] diff --git a/app/models/group.rb b/app/models/group.rb index 2e68779d3674e95f6b11e144061d71fd5ea498a1..e51e19ab60ca3a24b0b1c515fd1101466a54e409 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -27,12 +27,6 @@ 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 @@ -77,4 +71,8 @@ class Group < Namespace self.errors.add :avatar, "only images allowed" end end + + def public_profile? + projects.public_only.any? + end end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 7973eef7e1cdcb35656ef199d077a68e720ea687..446e5f04c63188db00d55bbca1ab04eb3048f7c4 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -47,14 +47,6 @@ class Namespace < ActiveRecord::Base def self.global_id '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 diff --git a/app/models/project.rb b/app/models/project.rb index 758ef14703c1631842cfce3e626dcc472e504f6b..f92cc40642ae73c3c2f79c1d158895ab87f5bad8 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -164,12 +164,6 @@ class Project < ActiveRecord::Base 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 diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index 8a1fce17ce7b4cc175100f63dd595721ed0ccf37..21214511182c7ca159834aed01d47c0ba71b8f2c 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -12,7 +12,7 @@ module Search return result unless query.present? group = Group.find_by(id: params[:group_id]) if params[:group_id].present? - projects = Project.accessible_to(current_user) + projects = ProjectsFinder.new.execute(current_user) projects = projects.where(namespace_id: group.id) if group project_ids = projects.pluck(:id)