diff options
Diffstat (limited to 'lib/gitlab')
-rw-r--r-- | lib/gitlab/checks/change_access.rb | 37 | ||||
-rw-r--r-- | lib/gitlab/user_access.rb | 16 |
2 files changed, 48 insertions, 5 deletions
diff --git a/lib/gitlab/checks/change_access.rb b/lib/gitlab/checks/change_access.rb index c85f79127bc..0d8f114cc59 100644 --- a/lib/gitlab/checks/change_access.rb +++ b/lib/gitlab/checks/change_access.rb @@ -10,6 +10,7 @@ module Gitlab ) @oldrev, @newrev, @ref = change.values_at(:oldrev, :newrev, :ref) @branch_name = Gitlab::Git.branch_name(@ref) + @tag_name = Gitlab::Git.tag_name(@ref) @user_access = user_access @project = project @env = env @@ -36,7 +37,7 @@ module Gitlab if forced_push? return "You are not allowed to force push code to a protected branch on this project." - elsif Gitlab::Git.blank_ref?(@newrev) + elsif blank_ref? return "You are not allowed to delete protected branches from this project." end @@ -58,11 +59,33 @@ module Gitlab def tag_checks return if skip_authorization - tag_ref = Gitlab::Git.tag_name(@ref) + return unless @tag_name - if tag_ref && protected_tag?(tag_ref) && user_access.cannot_do_action?(:admin_project) + if tag_exists? && user_access.cannot_do_action?(:admin_project) "You are not allowed to change existing tags on this project." end + + protected_tag_checks + end + + def protected_tag_checks + return unless tag_protected? + + if forced_push? + return "You are not allowed to force push protected tags." #TODO: Wording, 'not allowed to update proteted tags'? + end + + if Gitlab::Git.blank_ref?(@newrev) + return "You are not allowed to delete protected tags." #TODO: Wording, do these need to mention 'you' if the rule applies to everyone + end + + if !user_access.can_push_tag?(@tag_name) + return "You are not allowed to create protected tags on this project." #TODO: Wording, it is a specific tag which you don't have access too, not all protected tags which might have different levels + end + end + + def tag_protected? + project.protected_tag?(@tag_name) end def push_checks @@ -75,14 +98,18 @@ module Gitlab private - def protected_tag?(tag_name) - project.repository.tag_exists?(tag_name) + def tag_exists? + project.repository.tag_exists?(@tag_name) end def forced_push? Gitlab::Checks::ForcePush.force_push?(@project, @oldrev, @newrev, env: @env) end + def blank_ref? + Gitlab::Git.blank_ref?(@newrev) + end + def matching_merge_request? Checks::MatchingMergeRequest.new(@newrev, @branch_name, @project).match? end diff --git a/lib/gitlab/user_access.rb b/lib/gitlab/user_access.rb index f260c0c535f..921159d91ef 100644 --- a/lib/gitlab/user_access.rb +++ b/lib/gitlab/user_access.rb @@ -28,6 +28,22 @@ module Gitlab true end + #TODO: Test this + #TODO move most to ProtectedTag::AccessChecker. Or maybe UserAccess::Protections::Tag + #TODO: then consider removing method, if it turns out can_access_git? and can?(:push_code are checked in change_access + def can_push_tag?(ref) + return false unless can_access_git? + + if project.protected_tag?(ref) + access_levels = project.protected_tags.matching(ref).map(&:push_access_levels).flatten + has_access = access_levels.any? { |access_level| access_level.check_access(user) } + + has_access + else + user.can?(:push_code, project) + end + end + def can_push_to_branch?(ref) return false unless can_access_git? |