debian-mirror-gitlab/app/models/concerns/mirror_authentication.rb

89 lines
2.5 KiB
Ruby
Raw Normal View History

2019-02-15 15:39:39 +05:30
# frozen_string_literal: true
# Mirroring may use password or SSH public-key authentication. This concern
# implements support for persisting the necessary data in a `credentials`
# serialized attribute. It also needs an `url` method to be defined
module MirrorAuthentication
extend ActiveSupport::Concern
included do
validates :auth_method, inclusion: { in: %w[password ssh_public_key] }, allow_blank: true
# We should generate a key even if there's no SSH URL present
before_validation :generate_ssh_private_key!, if: -> {
2023-01-13 00:05:48 +05:30
regenerate_ssh_private_key || (auth_method == 'ssh_public_key' && ssh_private_key.blank?)
2019-02-15 15:39:39 +05:30
}
credentials_field :auth_method, reader: false
credentials_field :ssh_known_hosts
credentials_field :ssh_known_hosts_verified_at
credentials_field :ssh_known_hosts_verified_by_id
credentials_field :ssh_private_key
credentials_field :user
credentials_field :password
end
class_methods do
def credentials_field(name, reader: true)
if reader
define_method(name) do
credentials[name] if credentials.present?
end
end
define_method("#{name}=") do |value|
2020-03-13 15:44:24 +05:30
credentials_will_change!
2019-02-15 15:39:39 +05:30
self.credentials ||= {}
# Removal of the password, username, etc, generally causes an update of
# the value to the empty string. Detect and gracefully handle this case.
if value.present?
self.credentials[name] = value
else
self.credentials.delete(name)
end
end
end
end
attr_accessor :regenerate_ssh_private_key
def ssh_key_auth?
ssh_mirror_url? && auth_method == 'ssh_public_key'
end
def password_auth?
auth_method == 'password'
end
def ssh_mirror_url?
url&.start_with?('ssh://')
end
def ssh_known_hosts_verified_by
@ssh_known_hosts_verified_by ||= ::User.find_by(id: ssh_known_hosts_verified_by_id)
end
def ssh_known_hosts_fingerprints
::SshHostKey.fingerprint_host_keys(ssh_known_hosts)
end
def auth_method
auth_method = credentials.fetch(:auth_method, nil) if credentials.present?
auth_method.presence || 'password'
end
def ssh_public_key
2019-07-07 11:18:12 +05:30
return if ssh_private_key.blank?
2019-02-15 15:39:39 +05:30
comment = "git@#{::Gitlab.config.gitlab.host}"
2022-04-04 11:22:00 +05:30
SSHData::PrivateKey.parse(ssh_private_key).first.public_key.openssh(comment: comment)
2019-02-15 15:39:39 +05:30
end
def generate_ssh_private_key!
2022-04-04 11:22:00 +05:30
self.ssh_private_key = SSHData::PrivateKey::RSA.generate(4096).openssl.to_pem
2019-02-15 15:39:39 +05:30
end
end