diff options
Diffstat (limited to 'app/models/remote_mirror.rb')
-rw-r--r-- | app/models/remote_mirror.rb | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb index c1f53b5da4f..b7b4d0f1be9 100644 --- a/app/models/remote_mirror.rb +++ b/app/models/remote_mirror.rb @@ -2,6 +2,7 @@ class RemoteMirror < ActiveRecord::Base include AfterCommitQueue + include MirrorAuthentication PROTECTED_BACKOFF_DELAY = 1.minute UNPROTECTED_BACKOFF_DELAY = 5.minutes @@ -14,8 +15,6 @@ class RemoteMirror < ActiveRecord::Base insecure_mode: true, algorithm: 'aes-256-cbc' - default_value_for :only_protected_branches, true - belongs_to :project, inverse_of: :remote_mirrors validates :url, presence: true, url: { protocols: %w(ssh git http https), allow_blank: true, enforce_user: true } @@ -28,6 +27,8 @@ class RemoteMirror < ActiveRecord::Base after_commit :remove_remote, on: :destroy + before_validation :store_credentials + scope :enabled, -> { where(enabled: true) } scope :started, -> { with_update_status(:started) } scope :stuck, -> { started.where('last_update_at < ? OR (last_update_at IS NULL AND updated_at < ?)', 1.day.ago, 1.day.ago) } @@ -84,7 +85,21 @@ class RemoteMirror < ActiveRecord::Base end def update_repository(options) - raw.update(options) + if ssh_mirror_url? + if ssh_key_auth? && ssh_private_key.present? + options[:ssh_key] = ssh_private_key + end + + if ssh_known_hosts.present? + options[:known_hosts] = ssh_known_hosts + end + end + + Gitlab::Git::RemoteMirror.new( + project.repository.raw, + remote_name, + **options + ).update end def sync? @@ -128,7 +143,8 @@ class RemoteMirror < ActiveRecord::Base super(value) && return unless Gitlab::UrlSanitizer.valid?(value) mirror_url = Gitlab::UrlSanitizer.new(value) - self.credentials = mirror_url.credentials + self.credentials ||= {} + self.credentials = self.credentials.merge(mirror_url.credentials) super(mirror_url.sanitized_url) end @@ -152,17 +168,28 @@ class RemoteMirror < ActiveRecord::Base def ensure_remote! return unless project - return unless remote_name && url + return unless remote_name && remote_url # If this fails or the remote already exists, we won't know due to # https://gitlab.com/gitlab-org/gitaly/issues/1317 - project.repository.add_remote(remote_name, url) + project.repository.add_remote(remote_name, remote_url) end private - def raw - @raw ||= Gitlab::Git::RemoteMirror.new(project.repository.raw, remote_name) + def store_credentials + # This is a necessary workaround for attr_encrypted, which doesn't otherwise + # notice that the credentials have changed + self.credentials = self.credentials + end + + # The remote URL omits any password if SSH public-key authentication is in use + def remote_url + return url unless ssh_key_auth? && password.present? + + Gitlab::UrlSanitizer.new(read_attribute(:url), credentials: { user: user }).full_url + rescue + super end def fallback_remote_name @@ -214,7 +241,7 @@ class RemoteMirror < ActiveRecord::Base project.repository.async_remove_remote(prev_remote_name) end - project.repository.add_remote(remote_name, url) + project.repository.add_remote(remote_name, remote_url) end def remove_remote @@ -224,6 +251,6 @@ class RemoteMirror < ActiveRecord::Base end def mirror_url_changed? - url_changed? || encrypted_credentials_changed? + url_changed? || credentials_changed? end end |