Commit cfd5870b authored by Douwe Maan's avatar Douwe Maan

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-org/gitlab-shell!62

GitLab Workhorse implementation: gitlab-org/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
...@@ -23,6 +23,7 @@ v 8.10.0 (unreleased) ...@@ -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.
......
...@@ -281,3 +281,21 @@ ...@@ -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;
}
}
...@@ -110,6 +110,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -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: []
......
...@@ -19,6 +19,8 @@ class Projects::GitHttpController < Projects::ApplicationController ...@@ -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
...@@ -154,6 +156,10 @@ class Projects::GitHttpController < Projects::ApplicationController ...@@ -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
...@@ -162,12 +168,28 @@ class Projects::GitHttpController < Projects::ApplicationController ...@@ -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
......
...@@ -31,6 +31,28 @@ module ApplicationSettingsHelper ...@@ -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)
......
...@@ -12,7 +12,7 @@ module BranchesHelper ...@@ -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
......
...@@ -40,33 +40,33 @@ module ButtonHelper ...@@ -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.'
} }
......
...@@ -206,10 +206,14 @@ module ProjectsHelper ...@@ -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
......
...@@ -59,6 +59,9 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -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|
......
...@@ -481,7 +481,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -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?
......
...@@ -23,7 +23,7 @@ module Commits ...@@ -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')
......
...@@ -43,7 +43,7 @@ module Files ...@@ -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")
......
...@@ -43,6 +43,12 @@ ...@@ -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
......
...@@ -2,15 +2,20 @@ ...@@ -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
......
# 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
...@@ -86,6 +86,7 @@ ActiveRecord::Schema.define(version: 20160705163108) do ...@@ -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|
......
...@@ -21,6 +21,7 @@ ...@@ -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.
......
# 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
...@@ -68,6 +68,7 @@ PUT /application/settings ...@@ -68,6 +68,7 @@ PUT /application/settings
| `after_sign_out_path` | string | no | Where to redirect users after logout | | `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 | | `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 | | `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_protocol` | string | no | Enabled protocols for Git access. Allowed values are: `ssh`, `http`, and `nil` to allow both protocols.
```bash ```bash
curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/application/settings?signup_enabled=false&default_project_visibility=1 curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/application/settings?signup_enabled=false&default_project_visibility=1
......
...@@ -13,6 +13,7 @@ module API ...@@ -13,6 +13,7 @@ module API
# action - git action (git-upload-pack or git-receive-pack) # action - git action (git-upload-pack or git-receive-pack)
# ref - branch name # ref - branch name
# forced_push - forced_push # forced_push - forced_push
# protocol - Git access protocol being used, e.g. HTTP or SSH
# #
helpers do helpers do
...@@ -46,11 +47,13 @@ module API ...@@ -46,11 +47,13 @@ module API
User.find_by(id: params[:user_id]) User.find_by(id: params[:user_id])
end end
protocol = params[:protocol]
access = access =
if wiki? if wiki?
Gitlab::GitAccessWiki.new(actor, project) Gitlab::GitAccessWiki.new(actor, project, protocol)
else else
Gitlab::GitAccess.new(actor, project) Gitlab::GitAccess.new(actor, project, protocol)
end end
access_status = access.check(params[:action], params[:changes]) access_status = access.check(params[:action], params[:changes])
......
module Gitlab module Gitlab
module Git module Git
class Hook class Hook
GL_PROTOCOL = 'web'.freeze
attr_reader :name, :repo_path, :path attr_reader :name, :repo_path, :path
def initialize(name, repo_path) def initialize(name, repo_path)
...@@ -34,7 +35,8 @@ module Gitlab ...@@ -34,7 +35,8 @@ module Gitlab
vars = { vars = {
'GL_ID' => gl_id, 'GL_ID' => gl_id,
'PWD' => repo_path 'PWD' => repo_path,
'GL_PROTOCOL' => GL_PROTOCOL
} }
options = { options = {
......
...@@ -3,11 +3,12 @@ module Gitlab ...@@ -3,11 +3,12 @@ module Gitlab
DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }
PUSH_COMMANDS = %w{ git-receive-pack } PUSH_COMMANDS = %w{ git-receive-pack }
attr_reader :actor, :project attr_reader :actor, :project, :protocol
def initialize(actor, project) def initialize(actor, project, protocol)
@actor = actor @actor = actor
@project = project @project = project
@protocol = protocol
end end
def user def user
...@@ -49,6 +50,8 @@ module Gitlab ...@@ -49,6 +50,8 @@ module Gitlab
end end
def check(cmd, changes = nil) def check(cmd, changes = nil)
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
unless actor unless actor
return build_status_object(false, "No user or key was provided.") return build_status_object(false, "No user or key was provided.")
end end
...@@ -164,6 +167,10 @@ module Gitlab ...@@ -164,6 +167,10 @@ module Gitlab
Gitlab::ForcePushCheck.force_push?(project, oldrev, newrev) Gitlab::ForcePushCheck.force_push?(project, oldrev, newrev)
end end
def protocol_allowed?
Gitlab::ProtocolAccess.allowed?(protocol)
end
private private
def protected_branch_action(oldrev, newrev, branch_name) def protected_branch_action(oldrev, newrev, branch_name)
......
module Gitlab
module ProtocolAccess
def self.allowed?(protocol)
if protocol == 'web'
true
elsif current_application_settings.enabled_git_access_protocol.blank?
true
else
protocol == current_application_settings.enabled_git_access_protocol
end
end
end
end
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_protocol').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_protocol').find(:xpath, 'option[3]').select_option
click_on 'Save'
end
end
require 'spec_helper' require 'spec_helper'
describe Gitlab::GitAccess, lib: true do describe Gitlab::GitAccess, lib: true do
let(:access) { Gitlab::GitAccess.new(actor, project) } let(:access) { Gitlab::GitAccess.new(actor, project, 'web') }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:actor) { user } let(:actor) { user }
...@@ -67,6 +67,43 @@ describe Gitlab::GitAccess, lib: true do ...@@ -67,6 +67,43 @@ describe Gitlab::GitAccess, lib: true do
end end
end end
describe '#check with single protocols allowed' do
def disable_protocol(protocol)
settings = ::ApplicationSetting.create_from_defaults
settings.update_attribute(:enabled_git_access_protocol, protocol)
end
context 'ssh disabled' do
before do
disable_protocol('ssh')
@acc = Gitlab::GitAccess.new(actor, project, 'ssh')
end
it 'blocks ssh git push' do
expect(@acc.check('git-receive-pack').allowed?).to be_falsey
end
it 'blocks ssh git pull' do
expect(@acc.check('git-upload-pack').allowed?).to be_falsey
end
end
context 'http disabled' do
before do
disable_protocol('http')
@acc = Gitlab::GitAccess.new(actor, project, 'http')
end
it 'blocks http push' do
expect(@acc.check('git-receive-pack').allowed?).to be_falsey
end
it 'blocks http git pull' do
expect(@acc.check('git-upload-pack').allowed?).to be_falsey
end
end
end
describe 'download_access_check' do describe 'download_access_check' do
describe 'master permissions' do describe 'master permissions' do
before { project.team << [user, :master] } before { project.team << [user, :master] }
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::GitAccessWiki, lib: true do describe Gitlab::GitAccessWiki, lib: true do
let(:access) { Gitlab::GitAccessWiki.new(user, project) } let(:access) { Gitlab::GitAccessWiki.new(user, project, 'web') }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:user) { create(:user) } let(:user) { create(:user) }
......
...@@ -207,26 +207,86 @@ describe API::API, api: true do ...@@ -207,26 +207,86 @@ describe API::API, api: true do
expect(json_response["status"]).to be_falsey expect(json_response["status"]).to be_falsey
end end
end end
context 'ssh access has been disabled' do
before do
settings = ::ApplicationSetting.create_from_defaults
settings.update_attribute(:enabled_git_access_protocol, 'http')
end
it 'rejects the SSH push' do
push(key, project)
expect(response.status).to eq(200)
expect(json_response['status']).to be_falsey
expect(json_response['message']).to eq 'Git access over SSH is not allowed'
end
it 'rejects the SSH pull' do
pull(key, project)
expect(response.status).to eq(200)
expect(json_response['status']).to be_falsey
expect(json_response['message']).to eq 'Git access over SSH is not allowed'
end
end
context 'http access has been disabled' do
before do
settings = ::ApplicationSetting.create_from_defaults
settings.update_attribute(:enabled_git_access_protocol, 'ssh')
end
it 'rejects the HTTP push' do
push(key, project, 'http')
expect(response.status).to eq(200)
expect(json_response['status']).to be_falsey
expect(json_response['message']).to eq 'Git access over HTTP is not allowed'
end
it 'rejects the HTTP pull' do
pull(key, project, 'http')
expect(response.status).to eq(200)
expect(json_response['status']).to be_falsey
expect(json_response['message']).to eq 'Git access over HTTP is not allowed'
end
end
context 'web actions are always allowed' do
it 'allows WEB push' do
settings = ::ApplicationSetting.create_from_defaults
settings.update_attribute(:enabled_git_access_protocol, 'ssh')
project.team << [user, :developer]
push(key, project, 'web')
expect(response.status).to eq(200)
expect(json_response['status']).to be_truthy
end
end
end end
def pull(key, project) def pull(key, project, protocol = 'ssh')
post( post(
api("/internal/allowed"), api("/internal/allowed"),
key_id: key.id, key_id: key.id,
project: project.path_with_namespace, project: project.path_with_namespace,
action: 'git-upload-pack', action: 'git-upload-pack',
secret_token: secret_token secret_token: secret_token,
protocol: protocol
) )
end end
def push(key, project) def push(key, project, protocol = 'ssh')
post( post(
api("/internal/allowed"), api("/internal/allowed"),
changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master', changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master',
key_id: key.id, key_id: key.id,
project: project.path_with_namespace, project: project.path_with_namespace,
action: 'git-receive-pack', action: 'git-receive-pack',
secret_token: secret_token secret_token: secret_token,
protocol: protocol
) )
end end
...@@ -237,7 +297,8 @@ describe API::API, api: true do ...@@ -237,7 +297,8 @@ describe API::API, api: true do
key_id: key.id, key_id: key.id,
project: project.path_with_namespace, project: project.path_with_namespace,
action: 'git-upload-archive', action: 'git-upload-archive',
secret_token: secret_token secret_token: secret_token,
protocol: 'ssh'
) )
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment