Class: Gitlab::GitAccess
- Inherits:
-
Object
- Object
- Gitlab::GitAccess
- Includes:
- Utils::StrongMemoize
- Defined in:
- lib/gitlab/git_access.rb
Direct Known Subclasses
GitAccessDesign, GitAccessProject, GitAccessSnippet, GitAccessWiki
Constant Summary collapse
- ForbiddenError =
Class.new(StandardError)
- NotFoundError =
Class.new(StandardError)
- TimeoutError =
Class.new(StandardError)
- ANY =
Use the magic string ‘_any’ to indicate we do not know what the changes are. This is also what gitlab-shell does.
'_any'
- ERROR_MESSAGES =
{ upload: 'You are not allowed to upload code for this project.', download: 'You are not allowed to download code from this project.', auth_upload: 'You are not allowed to upload code.', auth_download: 'You are not allowed to download code.', deploy_key_upload: 'This deploy key does not have write access to this project.', no_repo: 'A repository for this project does not exist yet.', project_not_found: "The project you were looking for could not be found or you don't have permission to view it.", auth_by_job_token_forbidden: 'Insufficient permissions to pull from the repository of project %{target_project_path}.', auth_by_job_token_project_not_in_allowlist: 'Authentication by CI/CD job token not allowed from %{source_project_path} to %{target_project_path}.', command_not_allowed: "The command you're trying to execute is not allowed.", upload_pack_disabled_over_http: 'Pulling over HTTP is not allowed.', receive_pack_disabled_over_http: 'Pushing over HTTP is not allowed.', read_only: 'The repository is temporarily read-only. Please try again later.', archived: "You can't push code to an archived project.", cannot_push_to_read_only: "You can't push code to a read-only GitLab instance.", push_code: 'You are not allowed to push code to this project.' }.freeze
- INTERNAL_TIMEOUT =
50.seconds.freeze
- LOG_HEADER =
<<~MESSAGE Push operation timed out Timing information for debugging purposes: MESSAGE
- DOWNLOAD_COMMANDS =
%w[git-upload-pack git-upload-archive].freeze
- PUSH_COMMANDS =
%w[git-receive-pack].freeze
- ALL_COMMANDS =
DOWNLOAD_COMMANDS + PUSH_COMMANDS
Instance Attribute Summary collapse
-
#actor ⇒ Object
readonly
Returns the value of attribute actor.
-
#auth_result_type ⇒ Object
readonly
Returns the value of attribute auth_result_type.
-
#authentication_abilities ⇒ Object
readonly
Returns the value of attribute authentication_abilities.
-
#changes ⇒ Object
readonly
Returns the value of attribute changes.
-
#cmd ⇒ Object
readonly
Returns the value of attribute cmd.
-
#container ⇒ Object
Returns the value of attribute container.
-
#protocol ⇒ Object
readonly
Returns the value of attribute protocol.
-
#push_options ⇒ Object
readonly
Returns the value of attribute push_options.
-
#redirected_path ⇒ Object
readonly
Returns the value of attribute redirected_path.
-
#repository_path ⇒ Object
readonly
Returns the value of attribute repository_path.
Class Method Summary collapse
Instance Method Summary collapse
- #check(cmd, changes) ⇒ Object
- #deploy_key_can_download_code? ⇒ Boolean
-
#download_ability ⇒ Symbol
The name of a Declarative Policy ability to check.
- #guest_can_download? ⇒ Boolean
-
#initialize(actor, container, protocol, authentication_abilities:, repository_path: nil, redirected_path: nil, auth_result_type: nil, push_options: nil) ⇒ GitAccess
constructor
A new instance of GitAccess.
- #logger ⇒ Object
- #protocol_allowed? ⇒ Boolean
-
#push_ability ⇒ Symbol
The name of a Declarative Policy ability to check.
- #request_from_ci_build? ⇒ Boolean
- #user_can_download? ⇒ Boolean
Constructor Details
#initialize(actor, container, protocol, authentication_abilities:, repository_path: nil, redirected_path: nil, auth_result_type: nil, push_options: nil) ⇒ GitAccess
Returns a new instance of GitAccess.
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/gitlab/git_access.rb', line 63 def initialize(actor, container, protocol, authentication_abilities:, repository_path: nil, redirected_path: nil, auth_result_type: nil, push_options: nil) @actor = actor @container = container @protocol = protocol @authentication_abilities = Array(authentication_abilities) @repository_path = repository_path @redirected_path = redirected_path @auth_result_type = auth_result_type @push_options = Gitlab::PushOptions.new() end |
Instance Attribute Details
#actor ⇒ Object (readonly)
Returns the value of attribute actor.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def actor @actor end |
#auth_result_type ⇒ Object (readonly)
Returns the value of attribute auth_result_type.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def auth_result_type @auth_result_type end |
#authentication_abilities ⇒ Object (readonly)
Returns the value of attribute authentication_abilities.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def authentication_abilities @authentication_abilities end |
#changes ⇒ Object (readonly)
Returns the value of attribute changes.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def changes @changes end |
#cmd ⇒ Object (readonly)
Returns the value of attribute cmd.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def cmd @cmd end |
#container ⇒ Object
Returns the value of attribute container.
51 52 53 |
# File 'lib/gitlab/git_access.rb', line 51 def container @container end |
#protocol ⇒ Object (readonly)
Returns the value of attribute protocol.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def protocol @protocol end |
#push_options ⇒ Object (readonly)
Returns the value of attribute push_options.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def @push_options end |
#redirected_path ⇒ Object (readonly)
Returns the value of attribute redirected_path.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def redirected_path @redirected_path end |
#repository_path ⇒ Object (readonly)
Returns the value of attribute repository_path.
48 49 50 |
# File 'lib/gitlab/git_access.rb', line 48 def repository_path @repository_path end |
Class Method Details
.error_message(key) ⇒ Object
53 54 55 56 57 58 59 60 61 |
# File 'lib/gitlab/git_access.rb', line 53 def self.(key) self.ancestors.each do |cls| return cls.const_get(:ERROR_MESSAGES, false).fetch(key) rescue NameError, KeyError next end raise ArgumentError, "No error message defined for #{key}" end |
Instance Method Details
#check(cmd, changes) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/gitlab/git_access.rb', line 74 def check(cmd, changes) @changes = changes @cmd = cmd check_protocol! check_valid_actor! check_active_user! check_authentication_abilities! check_command_disabled! check_command_existence! custom_action = check_custom_action return custom_action if custom_action check_db_accessibility! check_container! check_repository_existence! case cmd when *DOWNLOAD_COMMANDS check_download_access! when *PUSH_COMMANDS check_push_access! end check_additional_conditions! success_result end |
#deploy_key_can_download_code? ⇒ Boolean
111 112 113 114 115 116 |
# File 'lib/gitlab/git_access.rb', line 111 def deploy_key_can_download_code? authentication_abilities.include?(:download_code) && deploy_key? && deploy_key.has_access_to?(container) && (project? && repository_access_level != ::Featurable::DISABLED) end |
#download_ability ⇒ Symbol
Returns the name of a Declarative Policy ability to check.
124 125 126 |
# File 'lib/gitlab/git_access.rb', line 124 def download_ability raise NotImplementedError end |
#guest_can_download? ⇒ Boolean
107 108 109 |
# File 'lib/gitlab/git_access.rb', line 107 def guest_can_download? ::Users::Anonymous.can?(download_ability, container) end |
#logger ⇒ Object
103 104 105 |
# File 'lib/gitlab/git_access.rb', line 103 def logger @logger ||= Checks::TimedLogger.new(timeout: INTERNAL_TIMEOUT, header: LOG_HEADER) end |
#protocol_allowed? ⇒ Boolean
139 140 141 |
# File 'lib/gitlab/git_access.rb', line 139 def protocol_allowed? Gitlab::ProtocolAccess.allowed?(protocol, project: project) end |
#push_ability ⇒ Symbol
Returns the name of a Declarative Policy ability to check.
129 130 131 |
# File 'lib/gitlab/git_access.rb', line 129 def push_ability raise NotImplementedError end |
#request_from_ci_build? ⇒ Boolean
133 134 135 136 137 |
# File 'lib/gitlab/git_access.rb', line 133 def request_from_ci_build? return false unless protocol == 'http' auth_result_type == :build || auth_result_type == :ci end |
#user_can_download? ⇒ Boolean
118 119 120 121 |
# File 'lib/gitlab/git_access.rb', line 118 def user_can_download? authentication_abilities.include?(:download_code) && user_access.can_do_action?(download_ability) end |