1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# frozen_string_literal: true
module Gitlab
class GitAccessSnippet < GitAccess
extend ::Gitlab::Utils::Override
ERROR_MESSAGES = {
authentication_mechanism: 'The authentication mechanism is not supported.',
read_snippet: 'You are not allowed to read this snippet.',
update_snippet: 'You are not allowed to update this snippet.',
snippet_not_found: 'The snippet you were looking for could not be found.',
no_repo: 'The snippet repository you were looking for could not be found.'
}.freeze
alias_method :snippet, :container
def initialize(actor, snippet, protocol, **kwargs)
super(actor, snippet, protocol, **kwargs)
@auth_result_type = nil
@authentication_abilities &= [:download_code, :push_code]
end
override :project
def project
container.project if container.is_a?(ProjectSnippet)
end
override :check
def check(cmd, changes)
check_snippet_accessibility!
super
end
override :download_ability
def download_ability
:read_snippet
end
override :push_ability
def push_ability
:update_snippet
end
private
# TODO: Implement EE/Geo https://gitlab.com/gitlab-org/gitlab/issues/205629
override :check_custom_action
def check_custom_action
# snippets never return custom actions, such as geo replication.
end
override :check_valid_actor!
def check_valid_actor!
# TODO: Investigate if expanding actor/authentication types are needed.
# https://gitlab.com/gitlab-org/gitlab/issues/202190
if actor && !allowed_actor?
raise ForbiddenError, ERROR_MESSAGES[:authentication_mechanism]
end
super
end
def allowed_actor?
actor.is_a?(User) || actor.instance_of?(Key)
end
override :check_push_access!
def check_push_access!
raise ForbiddenError, ERROR_MESSAGES[:update_snippet] unless user
check_change_access!
end
def check_snippet_accessibility!
if snippet.blank?
raise NotFoundError, ERROR_MESSAGES[:snippet_not_found]
end
end
override :can_read_project?
def can_read_project?
return true if user&.migration_bot?
super
end
override :check_download_access!
def check_download_access!
passed = guest_can_download_code? || user_can_download_code?
unless passed
raise ForbiddenError, ERROR_MESSAGES[:read_snippet]
end
end
override :check_change_access!
def check_change_access!
unless user_can_push?
raise ForbiddenError, ERROR_MESSAGES[:update_snippet]
end
check_size_before_push!
changes_list.each do |change|
# If user does not have access to make at least one change, cancel all
# push by allowing the exception to bubble up
check_single_change_access(change)
end
check_push_size!
end
override :check_single_change_access
def check_single_change_access(change, _skip_lfs_integrity_check: false)
Checks::SnippetCheck.new(change, default_branch: snippet.default_branch, root_ref: snippet.repository.root_ref, logger: logger).validate!
Checks::PushFileCountCheck.new(change, repository: repository, limit: Snippet.max_file_limit, logger: logger).validate!
rescue Checks::TimedLogger::TimeoutError
raise TimeoutError, logger.full_message
end
override :user_access
def user_access
@user_access ||= UserAccessSnippet.new(user, snippet: snippet)
end
override :check_size_limit?
def check_size_limit?
return false if user&.migration_bot?
super
end
end
end
Gitlab::GitAccessSnippet.prepend_if_ee('EE::Gitlab::GitAccessSnippet')
|