diff options
Diffstat (limited to 'app/models/concerns/protected_ref_deploy_key_access.rb')
-rw-r--r-- | app/models/concerns/protected_ref_deploy_key_access.rb | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/app/models/concerns/protected_ref_deploy_key_access.rb b/app/models/concerns/protected_ref_deploy_key_access.rb new file mode 100644 index 00000000000..4275476a1ff --- /dev/null +++ b/app/models/concerns/protected_ref_deploy_key_access.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module ProtectedRefDeployKeyAccess + extend ActiveSupport::Concern + + included do + belongs_to :deploy_key + + protected_ref_fk = "#{module_parent.model_name.singular}_id" + validates :deploy_key_id, uniqueness: { scope: protected_ref_fk, allow_nil: true } + validate :validate_deploy_key_membership + end + + class_methods do + def non_role_types + super << :deploy_key + end + end + + def type + return :deploy_key if deploy_key.present? + + super + end + + def humanize + return deploy_key.title if deploy_key? + + super + end + + def check_access(current_user) + super do + break enabled_deploy_key_for_user?(current_user) if deploy_key? + + yield if block_given? + end + end + + private + + def deploy_key? + type == :deploy_key + end + + def validate_deploy_key_membership + return if deploy_key.nil? || deploy_key_has_write_access_to_project? + + errors.add(:deploy_key, 'is not enabled for this project') + end + + def enabled_deploy_key_for_user?(current_user) + current_user.can?(:read_project, project) && + deploy_key.user_id == current_user.id && + deploy_key_has_write_access_to_project? + end + + def deploy_key_has_write_access_to_project? + DeployKey.with_write_access_for_project(project, deploy_key: deploy_key).exists? + end +end |