diff options
author | Patricio Cano <suprnova32@gmail.com> | 2016-06-15 17:30:55 -0500 |
---|---|---|
committer | Patricio Cano <suprnova32@gmail.com> | 2016-07-05 16:54:22 -0500 |
commit | 512adc21feff5135de94d23ed6808296b365490a (patch) | |
tree | a1067fee6ea02eeae2f13750f17b64ff7544a9b0 | |
parent | 1141eaf5c83f927ccc064b6c5d162081fdd22894 (diff) | |
download | gitlab-ce-512adc21feff5135de94d23ed6808296b365490a.tar.gz |
Add setting that allows admins to choose which Git access protocols are enabled
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/buttons.scss | 7 | ||||
-rw-r--r-- | app/controllers/admin/application_settings_controller.rb | 1 | ||||
-rw-r--r-- | app/helpers/application_settings_helper.rb | 22 | ||||
-rw-r--r-- | app/helpers/projects_helper.rb | 10 | ||||
-rw-r--r-- | app/models/application_setting.rb | 2 | ||||
-rw-r--r-- | app/views/admin/application_settings/_form.html.haml | 6 | ||||
-rw-r--r-- | app/views/shared/_clone_panel.html.haml | 23 | ||||
-rw-r--r-- | db/migrate/20160615173316_add_enabled_git_access_protocols_to_application_settings.rb | 11 | ||||
-rw-r--r-- | db/schema.rb | 1 | ||||
-rw-r--r-- | doc/api/settings.md | 1 | ||||
-rw-r--r-- | spec/features/admin/admin_disables_git_access_protocol_spec.rb | 66 |
12 files changed, 139 insertions, 12 deletions
diff --git a/CHANGELOG b/CHANGELOG index 3da5583d452..62cfc81cc0b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -176,6 +176,7 @@ v 8.9.0 - Fix horizontal scrollbar for long commit message. - GitLab Performance Monitoring now tracks the total method execution time and call count per method - Add Environments and Deployments + - Add "Enabled Git access protocols" to Application Settings - Redesign account and email confirmation emails - Don't fail builds for projects that are deleted - Support Docker Registry manifest v1 diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 1e3083cce55..1b900d10859 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -281,3 +281,10 @@ color: $gl-icon-color; } } + +.clone-dropdown-btn a { + color: #555; + &:hover { + text-decoration: none; + } +} diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 5f65dd3aff0..51ae9264ed7 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -110,6 +110,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :send_user_confirmation_email, :container_registry_token_expire_delay, :repository_storage, + :enabled_git_access_protocols, restricted_visibility_levels: [], import_sources: [], disabled_oauth_sign_in_sources: [] diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 6e580c62ccd..bc196fb2918 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -31,6 +31,28 @@ module ApplicationSettingsHelper current_application_settings.akismet_enabled? end + def allowed_protocols_present? + current_application_settings.enabled_git_access_protocols.present? + end + + def enabled_protocol + case current_application_settings.enabled_git_access_protocols + when 'http' + gitlab_config.protocol + when 'ssh' + 'ssh' + end + end + + def enabled_project_tooltip(project, protocol) + case protocol + when 'ssh' + sanitize(ssh_clone_button(project), tags: %w(a), attributes: %w(id class title data-html data-container data-placement data-title data-original-title aria-describedby)) + else + sanitize(http_clone_button(project), tags: %w(a), attributes: %w(id class title data-html data-container data-placement data-title data-original-title aria-describedby)) + end + end + # Return a group of checkboxes that use Bootstrap's button plugin for a # toggle button effect. def restricted_level_checkboxes(help_block_id) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index f312a7ccca3..88787576dd3 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -206,10 +206,14 @@ module ProjectsHelper end def default_clone_protocol - if !current_user || current_user.require_ssh_key? - gitlab_config.protocol + if allowed_protocols_present? + enabled_protocol else - "ssh" + if !current_user || current_user.require_ssh_key? + gitlab_config.protocol + else + 'ssh' + end end end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 5fa6eacd234..7d0114fc549 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -59,6 +59,8 @@ class ApplicationSetting < ActiveRecord::Base presence: true, inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } } + validates_inclusion_of :enabled_git_access_protocols, in: %w(ssh http), allow_blank: true, allow_nil: true + validates_each :restricted_visibility_levels do |record, attr, value| unless value.nil? value.each do |level| diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index c1f70bc1866..5647ac90a16 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -44,6 +44,12 @@ and GitLab.com = link_to "(?)", help_page_path("integration", "gitlab") .form-group + %label.control-label.col-sm-2 Enabled Git access protocols + .col-sm-10 + = select(:application_setting, :enabled_git_access_protocols, [['Both SSH and HTTP', nil], ['Only SSH', 'ssh'], ['Only HTTP(S)', 'http']], {}, class: 'form-control') + %span.help-block#clone-protocol-help + Allow only the selected protocols to be used for Git access. + .form-group .col-sm-offset-2.col-sm-10 .checkbox = f.label :version_check_enabled do diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index 84b3f44c0ad..565bd869749 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -2,15 +2,20 @@ .git-clone-holder.input-group .input-group-btn - %a#clone-dropdown.clone-dropdown-btn.btn{href: '#', 'data-toggle' => 'dropdown'} - %span - = default_clone_protocol.upcase - = icon('caret-down') - %ul.dropdown-menu.dropdown-menu-right.clone-options-dropdown - %li - = ssh_clone_button(project) - %li - = http_clone_button(project) + -if allowed_protocols_present? + .clone-dropdown-btn.btn + %span + = enabled_project_tooltip(project, enabled_protocol) + - else + %a#clone-dropdown.clone-dropdown-btn.btn{href: '#', data: { toggle: 'dropdown' }} + %span + = default_clone_protocol.upcase + = icon('caret-down') + %ul.dropdown-menu.dropdown-menu-right.clone-options-dropdown + %li + = ssh_clone_button(project) + %li + = http_clone_button(project) = text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true .input-group-btn diff --git a/db/migrate/20160615173316_add_enabled_git_access_protocols_to_application_settings.rb b/db/migrate/20160615173316_add_enabled_git_access_protocols_to_application_settings.rb new file mode 100644 index 00000000000..c75e20880db --- /dev/null +++ b/db/migrate/20160615173316_add_enabled_git_access_protocols_to_application_settings.rb @@ -0,0 +1,11 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. +# rubocop:disable all + +class AddEnabledGitAccessProtocolsToApplicationSettings < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + def change + add_column :application_settings, :enabled_git_access_protocols, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index c1e88c1ed7e..e0fe35f6b5f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -86,6 +86,7 @@ ActiveRecord::Schema.define(version: 20160705163108) do t.integer "container_registry_token_expire_delay", default: 5 t.text "after_sign_up_text" t.string "repository_storage", default: "default" + t.string "enabled_git_access_protocols" end create_table "audit_events", force: :cascade do |t| diff --git a/doc/api/settings.md b/doc/api/settings.md index 741c5a29581..baadad18ce8 100644 --- a/doc/api/settings.md +++ b/doc/api/settings.md @@ -68,6 +68,7 @@ PUT /application/settings | `after_sign_out_path` | string | no | Where to redirect users after logout | | `container_registry_token_expire_delay` | integer | no | Container Registry token duration in minutes | | `repository_storage` | string | no | Storage path for new projects. The value should be the name of one of the repository storage paths defined in your gitlab.yml | +| `enabled_git_access_protocols` | string | no | Enabled protocols for Git access. Allowed values are: `ssh`, `http`, and `nil` to allow both protocols. ```bash curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/application/settings?signup_enabled=false&default_project_visibility=1 diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb new file mode 100644 index 00000000000..550dcb62453 --- /dev/null +++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb @@ -0,0 +1,66 @@ +require 'rails_helper' + +feature 'Admin disables Git access protocol', feature: true do + let(:project) { create(:empty_project, :empty_repo) } + let(:admin) { create(:admin) } + + background do + login_as(admin) + end + + context 'with HTTP disabled' do + background do + disable_http_protocol + end + + scenario 'shows only SSH url' do + visit_project + + expect(page).to have_content("git clone #{project.ssh_url_to_repo}") + expect(page).not_to have_selector('#clone-dropdown') + end + end + + context 'with SSH disabled' do + background do + disable_ssh_protocol + end + + scenario 'shows only HTTP url' do + visit_project + + expect(page).to have_content("git clone #{project.http_url_to_repo}") + expect(page).not_to have_selector('#clone-dropdown') + end + end + + context 'with nothing disabled' do + background do + create(:personal_key, user: admin) + end + + scenario 'shows default SSH url and protocol selection dropdown' do + visit_project + + expect(page).to have_content("git clone #{project.ssh_url_to_repo}") + expect(page).to have_selector('#clone-dropdown') + end + + end + + def visit_project + visit namespace_project_path(project.namespace, project) + end + + def disable_http_protocol + visit admin_application_settings_path + find('#application_setting_enabled_git_access_protocols').find(:xpath, 'option[2]').select_option + click_on 'Save' + end + + def disable_ssh_protocol + visit admin_application_settings_path + find('#application_setting_enabled_git_access_protocols').find(:xpath, 'option[3]').select_option + click_on 'Save' + end +end |