diff options
author | Luke Bennett <lbennett@gitlab.com> | 2019-05-06 13:15:03 +0000 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2019-05-06 13:15:03 +0000 |
commit | 18c07084a6faea04ab446e523fff603843406ac8 (patch) | |
tree | b13bd44f9f56f32afb4ed387284e45102d653a4f | |
parent | 53823531ff88f8c568973841fac66e3629df7522 (diff) | |
download | gitlab-ce-18c07084a6faea04ab446e523fff603843406ac8.tar.gz |
Destroy repo mirrors instead of disabling them
It is important to destroy data related to repo mirrors when they are
disabled.
Use `_destroy` nested attribute instead of `enabled` for push mirrors.
Call `remove_import_data` after saving a project if its pull mirror is
disabled.
-rw-r--r-- | app/assets/javascripts/mirrors/mirror_repos.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/mirrors/ssh_mirror.js | 114 | ||||
-rw-r--r-- | app/controllers/projects/mirrors_controller.rb | 1 | ||||
-rw-r--r-- | app/views/projects/mirrors/_authentication_method.html.haml | 21 | ||||
-rw-r--r-- | app/views/projects/mirrors/_mirror_repos_push.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/mirrors/_ssh_host_keys.html.haml | 2 | ||||
-rw-r--r-- | changelogs/unreleased/ce-its-simple-just-destroy-the-mirrors.yml | 5 | ||||
-rw-r--r-- | locale/gitlab.pot | 12 | ||||
-rw-r--r-- | spec/features/projects/settings/repository_settings_spec.rb | 19 |
9 files changed, 29 insertions, 149 deletions
diff --git a/app/assets/javascripts/mirrors/mirror_repos.js b/app/assets/javascripts/mirrors/mirror_repos.js index 196b84621b6..33e9b1c4e46 100644 --- a/app/assets/javascripts/mirrors/mirror_repos.js +++ b/app/assets/javascripts/mirrors/mirror_repos.js @@ -87,7 +87,7 @@ export default class MirrorRepos { project: { remote_mirrors_attributes: { id: $target.data('mirrorId'), - enabled: 0, + _destroy: 1, }, }, }; diff --git a/app/assets/javascripts/mirrors/ssh_mirror.js b/app/assets/javascripts/mirrors/ssh_mirror.js index f7e80950803..bb5ae6ce2d1 100644 --- a/app/assets/javascripts/mirrors/ssh_mirror.js +++ b/app/assets/javascripts/mirrors/ssh_mirror.js @@ -24,12 +24,6 @@ export default class SSHMirror { this.$wellAuthTypeChanging = this.$form.find('.js-well-changing-auth'); this.$wellPasswordAuth = this.$form.find('.js-well-password-auth'); - this.$wellSSHAuth = this.$form.find('.js-well-ssh-auth'); - this.$sshPublicKeyWrap = this.$form.find('.js-ssh-public-key-wrap'); - this.$regeneratePublicSshKeyButton = this.$wellSSHAuth.find('.js-btn-regenerate-ssh-key'); - this.$regeneratePublicSshKeyModal = this.$wellSSHAuth.find( - '.js-regenerate-public-ssh-key-confirm-modal', - ); } init() { @@ -40,15 +34,6 @@ export default class SSHMirror { this.$dropdownAuthType.on('change', e => this.handleAuthTypeChange(e)); this.$btnDetectHostKeys.on('click', e => this.handleDetectHostKeys(e)); this.$btnSSHHostsShowAdvanced.on('click', e => this.handleSSHHostsAdvanced(e)); - this.$regeneratePublicSshKeyButton.on('click', () => - this.$regeneratePublicSshKeyModal.toggle(true), - ); - $('.js-confirm', this.$regeneratePublicSshKeyModal).on('click', e => - this.regeneratePublicSshKey(e), - ); - $('.js-cancel', this.$regeneratePublicSshKeyModal).on('click', () => - this.$regeneratePublicSshKeyModal.toggle(false), - ); } /** @@ -162,54 +147,11 @@ export default class SSHMirror { * Authentication method dropdown change event listener */ handleAuthTypeChange() { - const projectMirrorAuthTypeEndpoint = `${this.$form.attr('action')}.json`; - const $sshPublicKey = this.$sshPublicKeyWrap.find('.ssh-public-key'); const selectedAuthType = this.$dropdownAuthType.val(); this.$wellPasswordAuth.collapse('hide'); - this.$wellSSHAuth.collapse('hide'); this.updateHiddenAuthType(selectedAuthType); - - // This request should happen only if selected Auth type was SSH - // and SSH Public key was not present on page load - if (selectedAuthType === AUTH_METHOD.SSH && !$sshPublicKey.text().trim()) { - if (!this.$wellSSHAuth.length) return; - - // Construct request body - const authTypeData = { - project: { - ...this.$regeneratePublicSshKeyButton.data().projectData, - }, - }; - - this.$wellAuthTypeChanging.collapse('show'); - this.$dropdownAuthType.disable(); - - axios - .put(projectMirrorAuthTypeEndpoint, JSON.stringify(authTypeData), { - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - }) - .then(({ data }) => { - // Show SSH public key container and fill in public key - this.toggleAuthWell(selectedAuthType); - this.toggleSSHAuthWellMessage(true); - this.setSSHPublicKey(data.import_data_attributes.ssh_public_key); - - this.$wellAuthTypeChanging.collapse('hide'); - this.$dropdownAuthType.enable(); - }) - .catch(() => { - Flash(__('Something went wrong on our end.')); - - this.$wellAuthTypeChanging.collapse('hide'); - this.$dropdownAuthType.enable(); - }); - } else { - this.toggleAuthWell(selectedAuthType); - this.$wellSSHAuth.find('.js-ssh-public-key-present').collapse('show'); - } + this.toggleAuthWell(selectedAuthType); } /** @@ -235,7 +177,6 @@ export default class SSHMirror { */ toggleAuthWell(authType) { this.$wellPasswordAuth.collapse(authType === AUTH_METHOD.PASSWORD ? 'show' : 'hide'); - this.$wellSSHAuth.collapse(authType === AUTH_METHOD.SSH ? 'show' : 'hide'); this.updateHiddenAuthType(authType); } @@ -244,64 +185,11 @@ export default class SSHMirror { this.$hiddenAuthType.prop('disabled', authType === AUTH_METHOD.SSH); } - /** - * Toggle SSH auth information message - */ - toggleSSHAuthWellMessage(sshKeyPresent) { - this.$sshPublicKeyWrap.collapse(sshKeyPresent ? 'show' : 'hide'); - this.$wellSSHAuth.find('.js-ssh-public-key-present').collapse(sshKeyPresent ? 'show' : 'hide'); - this.$regeneratePublicSshKeyButton.collapse(sshKeyPresent ? 'show' : 'hide'); - this.$wellSSHAuth.find('.js-ssh-public-key-pending').collapse(sshKeyPresent ? 'hide' : 'show'); - } - - /** - * Sets SSH Public key to Clipboard button and shows it on UI. - */ - setSSHPublicKey(sshPublicKey) { - this.$sshPublicKeyWrap.find('.ssh-public-key').text(sshPublicKey); - this.$sshPublicKeyWrap - .find('.btn-copy-ssh-public-key') - .attr('data-clipboard-text', sshPublicKey); - } - - regeneratePublicSshKey(event) { - event.preventDefault(); - - this.$regeneratePublicSshKeyModal.toggle(false); - - const button = this.$regeneratePublicSshKeyButton; - const spinner = $('.js-spinner', button); - const endpoint = button.data('endpoint'); - const authTypeData = { - project: { - ...this.$regeneratePublicSshKeyButton.data().projectData, - }, - }; - - button.attr('disabled', 'disabled'); - spinner.removeClass('d-none'); - - axios - .patch(endpoint, authTypeData) - .then(({ data }) => { - button.removeAttr('disabled'); - spinner.addClass('d-none'); - - this.setSSHPublicKey(data.import_data_attributes.ssh_public_key); - }) - .catch(() => { - Flash(__('Unable to regenerate public ssh key.')); - }); - } - destroy() { this.$repositoryUrl.off('keyup'); this.$form.find('.js-known-hosts').off('keyup'); this.$dropdownAuthType.off('change'); this.$btnDetectHostKeys.off('click'); this.$btnSSHHostsShowAdvanced.off('click'); - this.$regeneratePublicSshKeyButton.off('click'); - $('.js-confirm', this.$regeneratePublicSshKeyModal).off('click'); - $('.js-cancel', this.$regeneratePublicSshKeyModal).off('click'); } } diff --git a/app/controllers/projects/mirrors_controller.rb b/app/controllers/projects/mirrors_controller.rb index ef330ae00f4..6c6adc233b7 100644 --- a/app/controllers/projects/mirrors_controller.rb +++ b/app/controllers/projects/mirrors_controller.rb @@ -81,6 +81,7 @@ class Projects::MirrorsController < Projects::ApplicationController password ssh_known_hosts regenerate_ssh_private_key + _destroy ] ] end diff --git a/app/views/projects/mirrors/_authentication_method.html.haml b/app/views/projects/mirrors/_authentication_method.html.haml index ef6db07a1bb..ee82d68d398 100644 --- a/app/views/projects/mirrors/_authentication_method.html.haml +++ b/app/views/projects/mirrors/_authentication_method.html.haml @@ -1,8 +1,5 @@ - mirror = f.object -- is_push = local_assigns.fetch(:is_push, false) - auth_options = [[_('Password'), 'password'], [_('SSH public key'), 'ssh_public_key']] -- regen_data = { auth_method: 'ssh_public_key', regenerate_ssh_private_key: true } -- ssh_public_key_present = mirror.ssh_public_key.present? .form-group = f.label :auth_method, _('Authentication method'), class: 'label-bold' @@ -17,21 +14,3 @@ .well-password-auth.collapse.js-well-password-auth = f.label :password, _("Password"), class: "label-bold" = f.password_field :password, value: mirror.password, class: 'form-control qa-password', autocomplete: 'new-password' - - unless is_push - .well-ssh-auth.collapse.js-well-ssh-auth - %p.js-ssh-public-key-present{ class: ('collapse' unless ssh_public_key_present) } - = _('Here is the public SSH key that needs to be added to the remote server. For more information, please refer to the documentation.') - %p.js-ssh-public-key-pending{ class: ('collapse' if ssh_public_key_present) } - = _('An SSH key will be automatically generated when the form is submitted. For more information, please refer to the documentation.') - - .clearfix.js-ssh-public-key-wrap{ class: ('collapse' unless ssh_public_key_present) } - %code.prepend-top-10.ssh-public-key - = mirror.ssh_public_key - = clipboard_button(text: mirror.ssh_public_key, title: _("Copy SSH public key to clipboard"), class: 'prepend-top-10 btn-copy-ssh-public-key') - - = button_tag type: 'button', - data: { endpoint: project_mirror_path(@project), project_data: { import_data_attributes: regen_data } }, - class: "btn btn-inverted btn-warning prepend-top-10 js-btn-regenerate-ssh-key#{ ' collapse' unless ssh_public_key_present }" do - = icon('spinner spin', class: 'js-spinner d-none') - = _('Regenerate key') - = render 'projects/mirrors/regenerate_public_ssh_key_confirm_modal' diff --git a/app/views/projects/mirrors/_mirror_repos_push.html.haml b/app/views/projects/mirrors/_mirror_repos_push.html.haml index 1d9c83653fe..b7c885b4a63 100644 --- a/app/views/projects/mirrors/_mirror_repos_push.html.haml +++ b/app/views/projects/mirrors/_mirror_repos_push.html.haml @@ -5,4 +5,4 @@ = rm_f.hidden_field :url, class: 'js-mirror-url-hidden', required: true, pattern: "(#{protocols}):\/\/.+" = rm_f.hidden_field :only_protected_branches, class: 'js-mirror-protected-hidden' = render partial: 'projects/mirrors/ssh_host_keys', locals: { f: rm_f } - = render partial: 'projects/mirrors/authentication_method', locals: { f: rm_f, is_push: true } + = render partial: 'projects/mirrors/authentication_method', locals: { f: rm_f } diff --git a/app/views/projects/mirrors/_ssh_host_keys.html.haml b/app/views/projects/mirrors/_ssh_host_keys.html.haml index f61aa6ecd11..7762fb4b844 100644 --- a/app/views/projects/mirrors/_ssh_host_keys.html.haml +++ b/app/views/projects/mirrors/_ssh_host_keys.html.haml @@ -3,7 +3,7 @@ - verified_at = mirror.ssh_known_hosts_verified_at .form-group.js-ssh-host-keys-section{ class: ('collapse' unless mirror.ssh_mirror_url?) } - %button.btn.btn-inverted.btn-success.inline.js-detect-host-keys.append-right-10{ type: 'button' } + %button.btn.btn-inverted.btn-secondary.inline.js-detect-host-keys.append-right-10{ type: 'button' } = icon('spinner spin', class: 'js-spinner d-none') = _('Detect host keys') .fingerprint-ssh-info.js-fingerprint-ssh-info.prepend-top-10.append-bottom-10{ class: ('collapse' unless mirror.ssh_mirror_url?) } diff --git a/changelogs/unreleased/ce-its-simple-just-destroy-the-mirrors.yml b/changelogs/unreleased/ce-its-simple-just-destroy-the-mirrors.yml new file mode 100644 index 00000000000..ac5fc27cf36 --- /dev/null +++ b/changelogs/unreleased/ce-its-simple-just-destroy-the-mirrors.yml @@ -0,0 +1,5 @@ +--- +title: Destroy project remote mirrors instead of disabling +merge_request: 27087 +author: +type: security diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 122f31fec44..445984c7847 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -811,9 +811,6 @@ msgstr "" msgid "Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication" msgstr "" -msgid "An SSH key will be automatically generated when the form is submitted. For more information, please refer to the documentation." -msgstr "" - msgid "An application called %{link_to_client} is requesting access to your GitLab account." msgstr "" @@ -2811,9 +2808,6 @@ msgstr "" msgid "Copy SSH public key" msgstr "" -msgid "Copy SSH public key to clipboard" -msgstr "" - msgid "Copy URL to clipboard" msgstr "" @@ -4762,9 +4756,6 @@ msgstr "" msgid "Help page text and support page url." msgstr "" -msgid "Here is the public SSH key that needs to be added to the remote server. For more information, please refer to the documentation." -msgstr "" - msgid "Hide file browser" msgstr "" @@ -10154,9 +10145,6 @@ msgstr "" msgid "Unable to load the diff. %{button_try_again}" msgstr "" -msgid "Unable to regenerate public ssh key." -msgstr "" - msgid "Unable to resolve" msgstr "" diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index 1259ad45791..f7de769cee9 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -217,5 +217,24 @@ describe 'Projects > Settings > Repository settings' do expect(RepositoryCleanupWorker.jobs.count).to eq(1) end end + + context 'with an existing mirror', :js do + let(:mirrored_project) { create(:project, :repository, :remote_mirror) } + + before do + mirrored_project.add_maintainer(user) + + visit project_settings_repository_path(mirrored_project) + end + + it 'delete remote mirrors' do + expect(mirrored_project.remote_mirrors.count).to eq(1) + + find('.js-delete-mirror').click + wait_for_requests + + expect(mirrored_project.remote_mirrors.count).to eq(0) + end + end end end |