Read about our upcoming Code of Conduct on this issue

Commit cbb31889 authored by Bob Van Landuyt's avatar Bob Van Landuyt
Browse files

Port `read_cross_project` ability from EE

parent f4b85fad2564
......@@ -126,10 +126,15 @@ def can?(object, action, subject = :global)
Ability.allowed?(object, action, subject)
end
def access_denied!
def access_denied!(message = nil)
respond_to do |format|
format.json { head :not_found }
format.any { render "errors/access_denied", layout: "errors", status: 404 }
format.any { head :not_found }
format.html do
render "errors/access_denied",
layout: "errors",
status: 404,
locals: { message: message }
end
end
end
......
......@@ -55,7 +55,7 @@ def make_sure_position_is_set(issues)
end
def issue
@issue ||= issues_finder.execute.find(params[:id])
@issue ||= issues_finder.find(params[:id])
end
def filter_params
......
module ControllerWithCrossProjectAccessCheck
extend ActiveSupport::Concern
included do
extend Gitlab::CrossProjectAccess::ClassMethods
before_action :cross_project_check
end
def cross_project_check
if Gitlab::CrossProjectAccess.find_check(self)&.should_run?(self)
authorize_cross_project_page!
end
end
def authorize_cross_project_page!
return if can?(current_user, :read_cross_project)
rejection_message = _(
"This page is unavailable because you are not allowed to read information "\
"across multiple projects."
)
access_denied!(rejection_message)
end
end
......@@ -3,16 +3,20 @@ module RoutableActions
def find_routable!(routable_klass, requested_full_path, extra_authorization_proc: nil)
routable = routable_klass.find_by_full_path(requested_full_path, follow_redirects: request.get?)
if routable_authorized?(routable, extra_authorization_proc)
ensure_canonical_path(routable, requested_full_path)
routable
else
route_not_found
handle_not_found_or_authorized(routable)
nil
end
end
# This is overridden in gitlab-ee.
def handle_not_found_or_authorized(_routable)
route_not_found
end
def routable_authorized?(routable, extra_authorization_proc)
action = :"read_#{routable.class.to_s.underscore}"
return false unless can?(current_user, action, routable)
......
class Dashboard::ApplicationController < ApplicationController
include ControllerWithCrossProjectAccessCheck
layout 'dashboard'
requires_cross_project_access
private
def projects
......
class Dashboard::GroupsController < Dashboard::ApplicationController
include GroupTree
skip_cross_project_access_check :index
def index
groups = GroupsFinder.new(current_user, all_available: false).execute
render_group_tree(groups)
......
......@@ -4,6 +4,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
before_action :set_non_archived_param
before_action :default_sorting
skip_cross_project_access_check :index, :starred
def index
@projects = load_projects(params.merge(non_public: true)).page(params[:page])
......
class Dashboard::SnippetsController < Dashboard::ApplicationController
skip_cross_project_access_check :index
def index
@snippets = SnippetsFinder.new(
current_user,
......
class Groups::ApplicationController < ApplicationController
include RoutableActions
include ControllerWithCrossProjectAccessCheck
layout 'group'
skip_before_action :authenticate_user!
before_action :group
requires_cross_project_access
private
......
class Groups::AvatarsController < Groups::ApplicationController
before_action :authorize_admin_group!
skip_cross_project_access_check :destroy
def destroy
@group.remove_avatar!
@group.save
......
module Groups
class ChildrenController < Groups::ApplicationController
before_action :group
skip_cross_project_access_check :index
def index
parent = if params[:parent_id].present?
......
......@@ -6,6 +6,10 @@ class Groups::GroupMembersController < Groups::ApplicationController
# Authorize
before_action :authorize_admin_group_member!, except: [:index, :leave, :request_access]
skip_cross_project_access_check :index, :create, :update, :destroy, :request_access,
:approve_access_request, :leave, :resend_invite,
:override
def index
@sort = params[:sort].presence || sort_value_name
@project = @group.projects.find(params[:project_id]) if params[:project_id]
......
module Groups
module Settings
class CiCdController < Groups::ApplicationController
skip_cross_project_access_check :show
before_action :authorize_admin_pipeline!
def show
......
......@@ -2,6 +2,8 @@ module Groups
class VariablesController < Groups::ApplicationController
before_action :authorize_admin_build!
skip_cross_project_access_check :show, :update
def show
respond_to do |format|
format.json do
......
......@@ -19,6 +19,12 @@ class GroupsController < Groups::ApplicationController
before_action :user_actions, only: [:show, :subgroups]
skip_cross_project_access_check :index, :new, :create, :edit, :update,
:destroy, :projects
# When loading show as an atom feed, we render events that could leak cross
# project information
skip_cross_project_access_check :show, if: -> { request.format.html? }
layout :determine_layout
def index
......
class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
include Gitlab::GonHelper
include Gitlab::Allowable
include PageLayoutHelper
include OauthApplications
......@@ -8,6 +9,8 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
before_action :add_gon_variables
before_action :load_scopes, only: [:index, :create, :edit]
helper_method :can?
layout 'profile'
def index
......
......@@ -34,9 +34,9 @@ def load_autocomplete_service
def target
case params[:type]&.downcase
when 'issue'
IssuesFinder.new(current_user, project_id: @project.id).execute.find_by(iid: params[:type_id])
IssuesFinder.new(current_user, project_id: @project.id).find_by(iid: params[:type_id])
when 'mergerequest'
MergeRequestsFinder.new(current_user, project_id: @project.id).execute.find_by(iid: params[:type_id])
MergeRequestsFinder.new(current_user, project_id: @project.id).find_by(iid: params[:type_id])
when 'commit'
@project.commit(params[:type_id])
end
......
......@@ -133,7 +133,7 @@ def assign_blob_vars
end
def after_edit_path
from_merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.find_by(iid: params[:from_merge_request_iid])
from_merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).find_by(iid: params[:from_merge_request_iid])
if from_merge_request && @branch_name == @ref
diffs_project_merge_request_path(from_merge_request.target_project, from_merge_request) +
"##{hexdigest(@path)}"
......
......@@ -75,7 +75,7 @@ def branch_from
def branch_to
@target_project = selected_target_project
if params[:ref].present?
if @target_project && params[:ref].present?
@ref = params[:ref]
@commit = @target_project.commit(Gitlab::Git::BRANCH_REF_PREFIX + @ref)
end
......@@ -85,7 +85,7 @@ def branch_to
def update_branches
@target_project = selected_target_project
@target_branches = @target_project.repository.branch_names
@target_branches = @target_project ? @target_project.repository.branch_names : []
render layout: false
end
......@@ -121,7 +121,7 @@ def selected_target_project
@project
elsif params[:target_project_id].present?
MergeRequestTargetProjectFinder.new(current_user: current_user, source_project: @project)
.execute.find(params[:target_project_id])
.find_by(id: params[:target_project_id])
else
@project.forked_from_project
end
......
class SearchController < ApplicationController
skip_before_action :authenticate_user!
include ControllerWithCrossProjectAccessCheck
include SearchHelper
include RendersCommits
skip_before_action :authenticate_user!
requires_cross_project_access if: -> do
search_term_present = params[:search].present? || params[:term].present?
search_term_present && !params[:project_id].present?
end
layout 'search'
def show
......
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