Skip to content
Snippets Groups Projects
Commit cfd5870b authored by Douwe Maan's avatar Douwe Maan
Browse files

Merge branch 'allow-disabling-of-git-access-protocol' into 'master'

Add setting that allows admins to choose which Git access protocols are enabled.

## What does this MR do?

It allows admins to disable one of the two protocols for Git access. They can choose to enable just SSH, HTTP or allow both. If one of them is disabled, the clone URL in the project will show only the allowed protocol, and no dropdown to change protocols will be presented.

## What are the relevant issue numbers?

Full implementation on GitLab's side for #18601 

GitLab Shell implementation: gitlab-shell!62

GitLab Workhorse implementation: gitlab-workhorse!51

## Screenshots (if relevant)

![Screen_Shot_2016-06-16_at_12.26.19_PM](/uploads/bad845142e9704a7385b2eaca51fd4eb/Screen_Shot_2016-06-16_at_12.26.19_PM.png)
![Screen_Shot_2016-06-20_at_4.24.54_PM](/uploads/6e452dd269e06f0be23841ce93866ed6/Screen_Shot_2016-06-20_at_4.24.54_PM.png)



/cc @jschatz1  this MR touches the UI. Please review.

See merge request !4696
parents 1141eaf5 0bdf6fe4
No related branches found
No related tags found
No related merge requests found
Showing
with 158 additions and 25 deletions
Loading
@@ -23,6 +23,7 @@ v 8.10.0 (unreleased)
Loading
@@ -23,6 +23,7 @@ v 8.10.0 (unreleased)
- Add notification settings dropdown for groups - Add notification settings dropdown for groups
- Allow importing from Github using Personal Access Tokens. (Eric K Idema) - Allow importing from Github using Personal Access Tokens. (Eric K Idema)
- API: Todos !3188 (Robert Schilling) - API: Todos !3188 (Robert Schilling)
- Add "Enabled Git access protocols" to Application Settings
- Fix user creation with stronger minimum password requirements !4054 (nathan-pmt) - Fix user creation with stronger minimum password requirements !4054 (nathan-pmt)
- PipelinesFinder uses git cache data - PipelinesFinder uses git cache data
- Check for conflicts with existing Project's wiki path when creating a new project. - Check for conflicts with existing Project's wiki path when creating a new project.
Loading
Loading
Loading
@@ -281,3 +281,21 @@
Loading
@@ -281,3 +281,21 @@
color: $gl-icon-color; color: $gl-icon-color;
} }
} }
.clone-dropdown-btn a {
color: $dropdown-link-color;
&:hover {
text-decoration: none;
}
}
.btn-static {
background-color: $background-color !important;
border: 1px solid lightgrey;
cursor: default;
&:active {
-moz-box-shadow: inset 0 0 0 white;
-webkit-box-shadow: inset 0 0 0 white;
box-shadow: inset 0 0 0 white;
}
}
Loading
@@ -110,6 +110,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
Loading
@@ -110,6 +110,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:send_user_confirmation_email, :send_user_confirmation_email,
:container_registry_token_expire_delay, :container_registry_token_expire_delay,
:repository_storage, :repository_storage,
:enabled_git_access_protocol,
restricted_visibility_levels: [], restricted_visibility_levels: [],
import_sources: [], import_sources: [],
disabled_oauth_sign_in_sources: [] disabled_oauth_sign_in_sources: []
Loading
Loading
Loading
@@ -19,6 +19,8 @@ class Projects::GitHttpController < Projects::ApplicationController
Loading
@@ -19,6 +19,8 @@ class Projects::GitHttpController < Projects::ApplicationController
render_ok render_ok
elsif receive_pack? && receive_pack_allowed? elsif receive_pack? && receive_pack_allowed?
render_ok render_ok
elsif http_blocked?
render_not_allowed
else else
render_not_found render_not_found
end end
Loading
@@ -154,6 +156,10 @@ class Projects::GitHttpController < Projects::ApplicationController
Loading
@@ -154,6 +156,10 @@ class Projects::GitHttpController < Projects::ApplicationController
render plain: 'Not Found', status: :not_found render plain: 'Not Found', status: :not_found
end end
   
def render_not_allowed
render plain: download_access.message, status: :forbidden
end
def ci? def ci?
@ci.present? @ci.present?
end end
Loading
@@ -162,12 +168,28 @@ class Projects::GitHttpController < Projects::ApplicationController
Loading
@@ -162,12 +168,28 @@ class Projects::GitHttpController < Projects::ApplicationController
return false unless Gitlab.config.gitlab_shell.upload_pack return false unless Gitlab.config.gitlab_shell.upload_pack
   
if user if user
Gitlab::GitAccess.new(user, project).download_access_check.allowed? download_access.allowed?
else else
ci? || project.public? ci? || project.public?
end end
end end
   
def access
return @access if defined?(@access)
@access = Gitlab::GitAccess.new(user, project, 'http')
end
def download_access
return @download_access if defined?(@download_access)
@download_access = access.check('git-upload-pack')
end
def http_blocked?
!access.protocol_allowed?
end
def receive_pack_allowed? def receive_pack_allowed?
return false unless Gitlab.config.gitlab_shell.receive_pack return false unless Gitlab.config.gitlab_shell.receive_pack
   
Loading
Loading
Loading
@@ -31,6 +31,28 @@ module ApplicationSettingsHelper
Loading
@@ -31,6 +31,28 @@ module ApplicationSettingsHelper
current_application_settings.akismet_enabled? current_application_settings.akismet_enabled?
end end
   
def allowed_protocols_present?
current_application_settings.enabled_git_access_protocol.present?
end
def enabled_protocol
case current_application_settings.enabled_git_access_protocol
when 'http'
gitlab_config.protocol
when 'ssh'
'ssh'
end
end
def enabled_project_button(project, protocol)
case protocol
when 'ssh'
ssh_clone_button(project, 'bottom', append_link: false)
else
http_clone_button(project, 'bottom', append_link: false)
end
end
# Return a group of checkboxes that use Bootstrap's button plugin for a # Return a group of checkboxes that use Bootstrap's button plugin for a
# toggle button effect. # toggle button effect.
def restricted_level_checkboxes(help_block_id) def restricted_level_checkboxes(help_block_id)
Loading
Loading
Loading
@@ -12,7 +12,7 @@ module BranchesHelper
Loading
@@ -12,7 +12,7 @@ module BranchesHelper
def can_push_branch?(project, branch_name) def can_push_branch?(project, branch_name)
return false unless project.repository.branch_exists?(branch_name) return false unless project.repository.branch_exists?(branch_name)
   
::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch_name) ::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(branch_name)
end end
   
def project_branches def project_branches
Loading
Loading
Loading
@@ -40,33 +40,33 @@ module ButtonHelper
Loading
@@ -40,33 +40,33 @@ module ButtonHelper
type: :button type: :button
end end
   
def http_clone_button(project) def http_clone_button(project, placement = 'right', append_link: true)
klass = 'http-selector' klass = 'http-selector'
klass << ' has-tooltip' if current_user.try(:require_password?) klass << ' has-tooltip' if current_user.try(:require_password?)
   
protocol = gitlab_config.protocol.upcase protocol = gitlab_config.protocol.upcase
   
content_tag :a, protocol, content_tag (append_link ? :a : :span), protocol,
class: klass, class: klass,
href: project.http_url_to_repo, href: (project.http_url_to_repo if append_link),
data: { data: {
html: true, html: true,
placement: 'right', placement: placement,
container: 'body', container: 'body',
title: "Set a password on your account<br>to pull or push via #{protocol}" title: "Set a password on your account<br>to pull or push via #{protocol}"
} }
end end
   
def ssh_clone_button(project) def ssh_clone_button(project, placement = 'right', append_link: true)
klass = 'ssh-selector' klass = 'ssh-selector'
klass << ' has-tooltip' if current_user.try(:require_ssh_key?) klass << ' has-tooltip' if current_user.try(:require_ssh_key?)
   
content_tag :a, 'SSH', content_tag (append_link ? :a : :span), 'SSH',
class: klass, class: klass,
href: project.ssh_url_to_repo, href: (project.ssh_url_to_repo if append_link),
data: { data: {
html: true, html: true,
placement: 'right', placement: placement,
container: 'body', container: 'body',
title: 'Add an SSH key to your profile<br>to pull or push via SSH.' title: 'Add an SSH key to your profile<br>to pull or push via SSH.'
} }
Loading
Loading
Loading
@@ -206,10 +206,14 @@ module ProjectsHelper
Loading
@@ -206,10 +206,14 @@ module ProjectsHelper
end end
   
def default_clone_protocol def default_clone_protocol
if !current_user || current_user.require_ssh_key? if allowed_protocols_present?
gitlab_config.protocol enabled_protocol
else else
"ssh" if !current_user || current_user.require_ssh_key?
gitlab_config.protocol
else
'ssh'
end
end end
end end
   
Loading
Loading
Loading
@@ -59,6 +59,9 @@ class ApplicationSetting < ActiveRecord::Base
Loading
@@ -59,6 +59,9 @@ class ApplicationSetting < ActiveRecord::Base
presence: true, presence: true,
inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } } inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } }
   
validates :enabled_git_access_protocol,
inclusion: { in: %w(ssh http), allow_blank: true, allow_nil: true }
validates_each :restricted_visibility_levels do |record, attr, value| validates_each :restricted_visibility_levels do |record, attr, value|
unless value.nil? unless value.nil?
value.each do |level| value.each do |level|
Loading
Loading
Loading
@@ -481,7 +481,7 @@ class MergeRequest < ActiveRecord::Base
Loading
@@ -481,7 +481,7 @@ class MergeRequest < ActiveRecord::Base
end end
   
def can_be_merged_by?(user) def can_be_merged_by?(user)
::Gitlab::GitAccess.new(user, project).can_push_to_branch?(target_branch) ::Gitlab::GitAccess.new(user, project, 'web').can_push_to_branch?(target_branch)
end end
   
def mergeable_ci_state? def mergeable_ci_state?
Loading
Loading
Loading
@@ -23,7 +23,7 @@ module Commits
Loading
@@ -23,7 +23,7 @@ module Commits
private private
   
def check_push_permissions def check_push_permissions
allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(@target_branch) allowed = ::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(@target_branch)
   
unless allowed unless allowed
raise ValidationError.new('You are not allowed to push into this branch') raise ValidationError.new('You are not allowed to push into this branch')
Loading
Loading
Loading
@@ -43,7 +43,7 @@ module Files
Loading
@@ -43,7 +43,7 @@ module Files
end end
   
def validate def validate
allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(@target_branch) allowed = ::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(@target_branch)
   
unless allowed unless allowed
raise_error("You are not allowed to push into this branch") raise_error("You are not allowed to push into this branch")
Loading
Loading
Loading
@@ -43,6 +43,12 @@
Loading
@@ -43,6 +43,12 @@
= link_to "(?)", help_page_path("integration", "bitbucket") = link_to "(?)", help_page_path("integration", "bitbucket")
and GitLab.com and GitLab.com
= link_to "(?)", help_page_path("integration", "gitlab") = 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_protocol, [['Both SSH and HTTP(S)', 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 .form-group
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
.checkbox .checkbox
Loading
Loading
Loading
@@ -2,15 +2,20 @@
Loading
@@ -2,15 +2,20 @@
   
.git-clone-holder.input-group .git-clone-holder.input-group
.input-group-btn .input-group-btn
%a#clone-dropdown.clone-dropdown-btn.btn{href: '#', 'data-toggle' => 'dropdown'} -if allowed_protocols_present?
%span .clone-dropdown-btn.btn.btn-static
= default_clone_protocol.upcase %span
= icon('caret-down') = enabled_project_button(project, enabled_protocol)
%ul.dropdown-menu.dropdown-menu-right.clone-options-dropdown - else
%li %a#clone-dropdown.clone-dropdown-btn.btn{href: '#', data: { toggle: 'dropdown' }}
= ssh_clone_button(project) %span
%li = default_clone_protocol.upcase
= http_clone_button(project) = 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 = text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true
.input-group-btn .input-group-btn
Loading
Loading
# 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_protocol, :string
end
end
Loading
@@ -86,6 +86,7 @@ ActiveRecord::Schema.define(version: 20160705163108) do
Loading
@@ -86,6 +86,7 @@ ActiveRecord::Schema.define(version: 20160705163108) do
t.integer "container_registry_token_expire_delay", default: 5 t.integer "container_registry_token_expire_delay", default: 5
t.text "after_sign_up_text" t.text "after_sign_up_text"
t.string "repository_storage", default: "default" t.string "repository_storage", default: "default"
t.string "enabled_git_access_protocol"
end end
   
create_table "audit_events", force: :cascade do |t| create_table "audit_events", force: :cascade do |t|
Loading
Loading
Loading
@@ -21,6 +21,7 @@
Loading
@@ -21,6 +21,7 @@
   
## Administrator documentation ## Administrator documentation
   
- [Access restrictions](administration/access_restrictions.md) Define which Git access protocols can be used to talk to GitLab
- [Authentication/Authorization](administration/auth/README.md) Configure - [Authentication/Authorization](administration/auth/README.md) Configure
external authentication with LDAP, SAML, CAS and additional Omniauth providers. external authentication with LDAP, SAML, CAS and additional Omniauth providers.
- [Custom Git hooks](administration/custom_hooks.md) Custom Git hooks (on the filesystem) for when webhooks aren't enough. - [Custom Git hooks](administration/custom_hooks.md) Custom Git hooks (on the filesystem) for when webhooks aren't enough.
Loading
Loading
# Access Restrictions
> **Note:** This feature is only available on versions 8.10 and above.
With GitLab's Access restrictions you can choose which Git access protocols you
want your users to use to communicate with GitLab. This feature can be enabled
via the `Application Settings` in the Admin interface.
The setting is called `Enabled Git access protocols`, and it gives you the option
to choose between:
- Both SSH and HTTP(S)
- Only SSH
- Only HTTP(s)
![Settings Overview](img/access_restrictions.png)
## Enabled Protocol
When both SSH and HTTP(S) are enabled, GitLab will behave as usual, it will give
your users the option to choose which protocol they would like to use.
When you choose to allow only one of the protocols, a couple of things will happen:
- The project page will only show the allowed protocol's URL, with no option to
change it.
- A tooltip will be shown when you hover over the URL's protocol, if an action
on the user's part is required, e.g. adding an SSH key, or setting a password.
![Project URL with SSH only access](img/restricted_url.png)
On top of these UI restrictions, GitLab will deny all Git actions on the protocol
not selected.
> **Note:** Please keep in mind that disabling an access protocol does not actually
block access to the server itself. The ports used for the protocol, be it SSH or
HTTP, will still be accessible. What GitLab does is restrict access on the
application level.
\ No newline at end of file
doc/administration/img/access_restrictions.png

310 KiB

doc/administration/img/restricted_url.png

184 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment