diff options
Diffstat (limited to 'lib/gitlab')
-rw-r--r-- | lib/gitlab/checks/post_push_message.rb (renamed from lib/gitlab/checks/base_project.rb) | 2 | ||||
-rw-r--r-- | lib/gitlab/checks/project_created.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/checks/project_moved.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/git_access.rb | 72 | ||||
-rw-r--r-- | lib/gitlab/path_regex.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/user_access.rb | 3 |
6 files changed, 50 insertions, 33 deletions
diff --git a/lib/gitlab/checks/base_project.rb b/lib/gitlab/checks/post_push_message.rb index dd6c007b356..473c0385b34 100644 --- a/lib/gitlab/checks/base_project.rb +++ b/lib/gitlab/checks/post_push_message.rb @@ -1,6 +1,6 @@ module Gitlab module Checks - class BaseProject + class PostPushMessage def initialize(project, user, protocol) @project = project @user = user diff --git a/lib/gitlab/checks/project_created.rb b/lib/gitlab/checks/project_created.rb index bd1e204bc81..ac24ff13b2a 100644 --- a/lib/gitlab/checks/project_created.rb +++ b/lib/gitlab/checks/project_created.rb @@ -1,6 +1,6 @@ module Gitlab module Checks - class ProjectCreated < BaseProject + class ProjectCreated < PostPushMessage PROJECT_CREATED = "project_created".freeze def message diff --git a/lib/gitlab/checks/project_moved.rb b/lib/gitlab/checks/project_moved.rb index eca59e88e24..216d2d6acc3 100644 --- a/lib/gitlab/checks/project_moved.rb +++ b/lib/gitlab/checks/project_moved.rb @@ -1,6 +1,6 @@ module Gitlab module Checks - class ProjectMoved < BaseProject + class ProjectMoved < PostPushMessage REDIRECT_NAMESPACE = "redirect_namespace".freeze def initialize(project, user, protocol, redirected_path) diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 84299dd5790..4615d67ce90 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -28,32 +28,37 @@ module Gitlab PUSH_COMMANDS = %w{ git-receive-pack }.freeze ALL_COMMANDS = DOWNLOAD_COMMANDS + PUSH_COMMANDS - attr_reader :actor, :project, :protocol, :authentication_abilities, :redirected_path, :target_namespace + attr_reader :actor, :project, :protocol, :authentication_abilities, :namespace_path, :project_path, :redirected_path - def initialize(actor, project, protocol, authentication_abilities:, redirected_path: nil, target_namespace: nil) + def initialize(actor, project, protocol, authentication_abilities:, namespace_path: nil, project_path: nil, redirected_path: nil) @actor = actor @project = project @protocol = protocol - @redirected_path = redirected_path @authentication_abilities = authentication_abilities - @target_namespace = target_namespace + @namespace_path = namespace_path + @project_path = project_path + @redirected_path = redirected_path end def check(cmd, changes) check_protocol! check_valid_actor! check_active_user! - check_project_accessibility!(cmd) - check_project_moved! check_command_disabled!(cmd) check_command_existence!(cmd) - check_repository_existence!(cmd) + check_db_accessibility!(cmd) + + ensure_project!(cmd, changes) + + check_project_accessibility! + check_project_moved! + check_repository_existence! case cmd when *DOWNLOAD_COMMANDS check_download_access! when *PUSH_COMMANDS - check_push_access!(cmd, changes) + check_push_access!(changes) end true @@ -99,8 +104,8 @@ module Gitlab end end - def check_project_accessibility!(cmd) - unless can_create_project_in_namespace?(cmd) || can_read_project? + def check_project_accessibility! + if project.blank? || !can_read_project? raise NotFoundError, ERROR_MESSAGES[:project_not_found] end end @@ -143,8 +148,23 @@ module Gitlab end end - def check_repository_existence!(cmd) - unless can_create_project_in_namespace?(cmd) || project.repository.exists? + def check_db_accessibility!(cmd) + return unless receive_pack?(cmd) + + if Gitlab::Database.read_only? + raise UnauthorizedError, push_to_read_only_message + end + end + + def ensure_project!(cmd, changes) + if can_create_project_in_namespace?(cmd, changes) + @project = ::Projects::CreateFromPushService.new(user, project_path, namespace, protocol).execute + user_access.project = @project + end + end + + def check_repository_existence! + unless project.repository.exists? raise UnauthorizedError, ERROR_MESSAGES[:no_repo] end end @@ -161,13 +181,7 @@ module Gitlab end end - def check_push_access!(cmd, changes) - if Gitlab::Database.read_only? - raise UnauthorizedError, push_to_read_only_message - end - - return if can_create_project_in_namespace?(cmd) - + def check_push_access!(changes) if project.repository_read_only? raise UnauthorizedError, ERROR_MESSAGES[:read_only] end @@ -180,8 +194,6 @@ module Gitlab raise UnauthorizedError, ERROR_MESSAGES[:upload] end - return if changes.blank? # Allow access. - check_change_access!(changes) end @@ -198,6 +210,8 @@ module Gitlab end def check_change_access!(changes) + return if changes.blank? # Allow access. + changes_list = Gitlab::ChangesList.new(changes) # Iterate over all changes to find if user allowed all of them to be applied @@ -240,11 +254,11 @@ module Gitlab end || Guest.can?(:read_project, project) end - def can_create_project_in_namespace?(cmd) + def can_create_project_in_namespace?(cmd, changes) strong_memoize(:can_create_project_in_namespace) do - return false unless push?(cmd) && target_namespace && project.blank? + return false unless !project && receive_pack?(cmd) && changes == '_any' - user.can?(:create_projects, target_namespace) + user&.can?(:create_projects, namespace) end end @@ -260,10 +274,6 @@ module Gitlab command == 'git-receive-pack' end - def push?(cmd) - PUSH_COMMANDS.include?(cmd) - end - def upload_pack_disabled_over_http? !Gitlab.config.gitlab_shell.upload_pack end @@ -288,6 +298,12 @@ module Gitlab end end + def namespace + return unless namespace_path + + @namespace ||= Namespace.find_by_full_path(namespace_path) + end + def user_access @user_access ||= if ci? CiAccess.new diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb index c6a594d38d1..111c9f20049 100644 --- a/lib/gitlab/path_regex.rb +++ b/lib/gitlab/path_regex.rb @@ -188,7 +188,7 @@ module Gitlab end def full_project_git_path_regex - @full_project_git_path_regex ||= /\A\/?(?<namespace_path>#{full_namespace_route_regex})\/(?<project_path>#{project_git_route_regex})\z/.freeze + @full_project_git_path_regex ||= /\A\/?(?<namespace_path>#{full_namespace_route_regex})\/(?<project_path>#{project_route_regex})\.git\z/.freeze end def full_namespace_format_regex diff --git a/lib/gitlab/user_access.rb b/lib/gitlab/user_access.rb index f357488ac61..15eb1c41213 100644 --- a/lib/gitlab/user_access.rb +++ b/lib/gitlab/user_access.rb @@ -6,7 +6,8 @@ module Gitlab [user&.id, project&.id] end - attr_reader :user, :project + attr_reader :user + attr_accessor :project def initialize(user, project: nil) @user = user |