Commit eb057209 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge pull request #9563 from Telekom-PD/feature/control-import-options

Feature/control import options
parents 55fc58bd bdae9bbe
...@@ -6,6 +6,7 @@ v 8.0.0 (unreleased) ...@@ -6,6 +6,7 @@ v 8.0.0 (unreleased)
- Faster merge - Faster merge
- Ability to fetch merge requests from refs/merge-requests/:id - Ability to fetch merge requests from refs/merge-requests/:id
- Allow displaying of archived projects in the admin interface (Artem Sidorenko) - Allow displaying of archived projects in the admin interface (Artem Sidorenko)
- Allow configuration of import sources for new projects (Artem Sidorenko)
v 7.14.0 (unreleased) v 7.14.0 (unreleased)
- Update default robots.txt rules to disallow crawling of irrelevant pages (Ben Bodenmiller) - Update default robots.txt rules to disallow crawling of irrelevant pages (Ben Bodenmiller)
......
...@@ -29,6 +29,15 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -29,6 +29,15 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
end end
end end
import_sources = params[:application_setting][:import_sources]
if import_sources.nil?
params[:application_setting][:import_sources] = []
else
import_sources.map! do |source|
source.to_str
end
end
params.require(:application_setting).permit( params.require(:application_setting).permit(
:default_projects_limit, :default_projects_limit,
:default_branch_protection, :default_branch_protection,
...@@ -47,6 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -47,6 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:version_check_enabled, :version_check_enabled,
:user_oauth_applications, :user_oauth_applications,
restricted_visibility_levels: [], restricted_visibility_levels: [],
import_sources: []
) )
end end
end end
...@@ -20,7 +20,7 @@ class ApplicationController < ActionController::Base ...@@ -20,7 +20,7 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception protect_from_forgery with: :exception
helper_method :abilities, :can?, :current_application_settings helper_method :abilities, :can?, :current_application_settings
helper_method :github_import_enabled?, :gitlab_import_enabled?, :bitbucket_import_enabled? helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :git_import_enabled?
rescue_from Encoding::CompatibilityError do |exception| rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception) log_exception(exception)
...@@ -298,15 +298,43 @@ class ApplicationController < ActionController::Base ...@@ -298,15 +298,43 @@ class ApplicationController < ActionController::Base
@issuable_finder.execute @issuable_finder.execute
end end
def import_sources_enabled?
!current_application_settings.import_sources.empty?
end
def github_import_enabled? def github_import_enabled?
current_application_settings.import_sources.include?('github')
end
def github_import_configured?
Gitlab::OAuth::Provider.enabled?(:github) Gitlab::OAuth::Provider.enabled?(:github)
end end
def gitlab_import_enabled? def gitlab_import_enabled?
request.host != 'gitlab.com' && current_application_settings.import_sources.include?('gitlab')
end
def gitlab_import_configured?
Gitlab::OAuth::Provider.enabled?(:gitlab) Gitlab::OAuth::Provider.enabled?(:gitlab)
end end
def bitbucket_import_enabled? def bitbucket_import_enabled?
current_application_settings.import_sources.include?('bitbucket')
end
def bitbucket_import_configured?
Gitlab::OAuth::Provider.enabled?(:bitbucket) && Gitlab::BitbucketImport.public_key.present? Gitlab::OAuth::Provider.enabled?(:bitbucket) && Gitlab::BitbucketImport.public_key.present?
end end
def gitorious_import_enabled?
current_application_settings.import_sources.include?('gitorious')
end
def google_code_import_enabled?
current_application_settings.import_sources.include?('google_code')
end
def git_import_enabled?
current_application_settings.import_sources.include?('git')
end
end end
class Import::GitoriousController < Import::BaseController class Import::GitoriousController < Import::BaseController
before_action :verify_gitorious_import_enabled
def new def new
redirect_to client.authorize_url(callback_import_gitorious_url) redirect_to client.authorize_url(callback_import_gitorious_url)
...@@ -40,4 +41,8 @@ class Import::GitoriousController < Import::BaseController ...@@ -40,4 +41,8 @@ class Import::GitoriousController < Import::BaseController
@client ||= Gitlab::GitoriousImport::Client.new(session[:gitorious_repos]) @client ||= Gitlab::GitoriousImport::Client.new(session[:gitorious_repos])
end end
def verify_gitorious_import_enabled
not_found! unless gitorious_import_enabled?
end
end end
class Import::GoogleCodeController < Import::BaseController class Import::GoogleCodeController < Import::BaseController
before_action :verify_google_code_import_enabled
before_action :user_map, only: [:new_user_map, :create_user_map] before_action :user_map, only: [:new_user_map, :create_user_map]
def new def new
...@@ -104,6 +105,10 @@ class Import::GoogleCodeController < Import::BaseController ...@@ -104,6 +105,10 @@ class Import::GoogleCodeController < Import::BaseController
@client ||= Gitlab::GoogleCodeImport::Client.new(session[:google_code_dump]) @client ||= Gitlab::GoogleCodeImport::Client.new(session[:google_code_dump])
end end
def verify_google_code_import_enabled
not_found! unless google_code_import_enabled?
end
def user_map def user_map
@user_map ||= begin @user_map ||= begin
user_map = client.user_map user_map = client.user_map
......
...@@ -39,4 +39,21 @@ module ApplicationSettingsHelper ...@@ -39,4 +39,21 @@ module ApplicationSettingsHelper
end end
end end
end end
# Return a group of checkboxes that use Bootstrap's button plugin for a
# toggle button effect.
def import_sources_checkboxes(help_block_id)
Gitlab::ImportSources.options.map do |name, source|
checked = current_application_settings.import_sources.include?(source)
css_class = 'btn'
css_class += ' active' if checked
checkbox_name = 'application_setting[import_sources][]'
label_tag(checkbox_name, class: css_class) do
check_box_tag(checkbox_name, source, checked,
autocomplete: 'off',
'aria-describedby' => help_block_id) + name
end
end
end
end end
...@@ -22,10 +22,12 @@ ...@@ -22,10 +22,12 @@
# user_oauth_applications :boolean default(TRUE) # user_oauth_applications :boolean default(TRUE)
# after_sign_out_path :string(255) # after_sign_out_path :string(255)
# session_expire_delay :integer default(10080), not null # session_expire_delay :integer default(10080), not null
# import_sources :text
# #
class ApplicationSetting < ActiveRecord::Base class ApplicationSetting < ActiveRecord::Base
serialize :restricted_visibility_levels serialize :restricted_visibility_levels
serialize :import_sources
serialize :restricted_signup_domains, Array serialize :restricted_signup_domains, Array
attr_accessor :restricted_signup_domains_raw attr_accessor :restricted_signup_domains_raw
...@@ -52,6 +54,16 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -52,6 +54,16 @@ class ApplicationSetting < ActiveRecord::Base
end end
end end
validates_each :import_sources do |record, attr, value|
unless value.nil?
value.each do |source|
unless Gitlab::ImportSources.options.has_value?(source)
record.errors.add(attr, "'#{source}' is not a import source")
end
end
end
end
def self.current def self.current
ApplicationSetting.last ApplicationSetting.last
end end
...@@ -70,7 +82,8 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -70,7 +82,8 @@ class ApplicationSetting < ActiveRecord::Base
session_expire_delay: Settings.gitlab['session_expire_delay'], session_expire_delay: Settings.gitlab['session_expire_delay'],
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
restricted_signup_domains: Settings.gitlab['restricted_signup_domains'] restricted_signup_domains: Settings.gitlab['restricted_signup_domains'],
import_sources: ['github','bitbucket','gitlab','gitorious','google_code','git']
) )
end end
......
...@@ -27,6 +27,20 @@ ...@@ -27,6 +27,20 @@
- restricted_level_checkboxes('restricted-visibility-help').each do |level| - restricted_level_checkboxes('restricted-visibility-help').each do |level|
= level = level
%span.help-block#restricted-visibility-help Selected levels cannot be used by non-admin users for projects or snippets %span.help-block#restricted-visibility-help Selected levels cannot be used by non-admin users for projects or snippets
.form-group
= f.label :import_sources, class: 'control-label col-sm-2'
.col-sm-10
- data_attrs = { toggle: 'buttons' }
.btn-group{ data: data_attrs }
- import_sources_checkboxes('import-sources-help').each do |source|
= source
%span.help-block#import-sources-help
Enabled sources for code import during project creation. OmniAuth must be configured for GitHub
= link_to "(?)", help_page_path("integration", "github")
, Bitbucket
= link_to "(?)", help_page_path("integration", "bitbucket")
and GitLab.com
= link_to "(?)", help_page_path("integration", "gitlab")
.form-group .form-group
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
.checkbox .checkbox
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
.modal-body .modal-body
To enable importing projects from Bitbucket, To enable importing projects from Bitbucket,
- if current_user.admin? - if current_user.admin?
you need to as administrator you need to configure
- else - else
your GitLab administrator needs to ask your GitLab administrator to configure
== #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/bitbucket.md'}. == #{link_to 'OAuth integration', help_page_path("integration", "bitbucket")}.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
.modal-body .modal-body
To enable importing projects from GitHub, To enable importing projects from GitHub,
- if current_user.admin? - if current_user.admin?
you need to as administrator you need to configure
- else - else
your GitLab administrator needs to ask your Gitlab administrator to configure
== #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/github.md'}. == #{link_to 'OAuth integration', help_page_path("integration", "github")}.
\ No newline at end of file
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
.modal-body .modal-body
To enable importing projects from GitLab.com, To enable importing projects from GitLab.com,
- if current_user.admin? - if current_user.admin?
you need to as administrator you need to configure
- else - else
your GitLab administrator needs to ask your GitLab administrator to configure
== #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/gitlab.md'}. == #{link_to 'OAuth integration', help_page_path("integration", "gitlab")}.
\ No newline at end of file
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
.col-sm-10 .col-sm-10
= f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2} = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2}
- if import_sources_enabled?
%hr %hr
.project-import.js-toggle-container .project-import.js-toggle-container
...@@ -29,46 +30,50 @@ ...@@ -29,46 +30,50 @@
%label.control-label Import project from %label.control-label Import project from
.col-sm-10 .col-sm-10
- if github_import_enabled? - if github_import_enabled?
= link_to status_import_github_path, class: 'btn' do - if github_import_configured?
= link_to status_import_github_path, class: 'btn import_github' do
%i.fa.fa-github %i.fa.fa-github
GitHub GitHub
- else - else
= link_to '#', class: 'how_to_import_link light btn' do = link_to '#', class: 'how_to_import_link light btn import_github' do
%i.fa.fa-github %i.fa.fa-github
GitHub GitHub
= render 'github_import_modal' = render 'github_import_modal'
- if bitbucket_import_enabled? - if bitbucket_import_enabled?
= link_to status_import_bitbucket_path, class: 'btn', "data-no-turbolink" => "true" do - if bitbucket_import_configured?
= link_to status_import_bitbucket_path, class: 'btn import_bitbucket', "data-no-turbolink" => "true" do
%i.fa.fa-bitbucket %i.fa.fa-bitbucket
Bitbucket Bitbucket
- else - else
= link_to '#', class: 'how_to_import_link light btn' do = link_to status_import_bitbucket_path, class: 'how_to_import_link light btn import_bitbucket', "data-no-turbolink" => "true" do
%i.fa.fa-bitbucket %i.fa.fa-bitbucket
Bitbucket Bitbucket
= render 'bitbucket_import_modal' = render 'bitbucket_import_modal'
- unless request.host == 'gitlab.com'
- if gitlab_import_enabled? - if gitlab_import_enabled?
= link_to status_import_gitlab_path, class: 'btn' do - if gitlab_import_configured?
= link_to status_import_gitlab_path, class: 'btn import_gitlab' do
%i.fa.fa-heart %i.fa.fa-heart
GitLab.com GitLab.com
- else - else
= link_to '#', class: 'how_to_import_link light btn' do = link_to status_import_gitlab_path, class: 'how_to_import_link light btn import_gitlab' do
%i.fa.fa-heart %i.fa.fa-heart
GitLab.com GitLab.com
= render 'gitlab_import_modal' = render 'gitlab_import_modal'
= link_to new_import_gitorious_path, class: 'btn' do - if gitorious_import_enabled?
= link_to new_import_gitorious_path, class: 'btn import_gitorious' do
%i.icon-gitorious.icon-gitorious-small %i.icon-gitorious.icon-gitorious-small
Gitorious.org Gitorious.org
= link_to new_import_google_code_path, class: 'btn' do - if google_code_import_enabled?
= link_to new_import_google_code_path, class: 'btn import_google_code' do
%i.fa.fa-google %i.fa.fa-google
Google Code Google Code
= link_to "#", class: 'btn js-toggle-button' do - if git_import_enabled?
= link_to "#", class: 'btn js-toggle-button import_git' do
%i.fa.fa-git %i.fa.fa-git
%span Any repo by URL %span Any repo by URL
......
...@@ -148,6 +148,7 @@ Settings.gitlab.default_projects_features['snippets'] = false if Settings. ...@@ -148,6 +148,7 @@ Settings.gitlab.default_projects_features['snippets'] = false if Settings.
Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE) Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE)
Settings.gitlab['repository_downloads_path'] = File.absolute_path(Settings.gitlab['repository_downloads_path'] || 'tmp/repositories', Rails.root) Settings.gitlab['repository_downloads_path'] = File.absolute_path(Settings.gitlab['repository_downloads_path'] || 'tmp/repositories', Rails.root)
Settings.gitlab['restricted_signup_domains'] ||= [] Settings.gitlab['restricted_signup_domains'] ||= []
Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious','google_code','git']
# #
# Gravatar # Gravatar
......
require 'yaml'
class AddSettingsImportSources < ActiveRecord::Migration
def change
unless column_exists?(:application_settings, :import_sources)
add_column :application_settings, :import_sources, :text
import_sources = YAML::dump(Settings.gitlab['import_sources'])
execute("update application_settings set import_sources = '#{import_sources}'")
end
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150806104937) do ActiveRecord::Schema.define(version: 20150812080800) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -44,6 +44,7 @@ ActiveRecord::Schema.define(version: 20150806104937) do ...@@ -44,6 +44,7 @@ ActiveRecord::Schema.define(version: 20150806104937) do
t.boolean "user_oauth_applications", default: true t.boolean "user_oauth_applications", default: true
t.string "after_sign_out_path" t.string "after_sign_out_path"
t.integer "session_expire_delay", default: 10080, null: false t.integer "session_expire_delay", default: 10080, null: false
t.text "import_sources"
end end
create_table "audit_events", force: true do |t| create_table "audit_events", force: true do |t|
......
...@@ -4,10 +4,27 @@ Background: ...@@ -4,10 +4,27 @@ Background:
Given I sign in as a user Given I sign in as a user
And I own project "Shop" And I own project "Shop"
And I visit dashboard page And I visit dashboard page
And I click "New project" link
@javascript @javascript
Scenario: I should see New projects page Scenario: I should see New projects page
Given I click "New project" link
Then I see "New project" page Then I see "New project" page
Then I see all possible import optios
@javascript
Scenario: I should see instructions on how to import from Git URL
Given I see "New project" page
When I click on "Any repo by URL"
Then I see instructions on how to import from Git URL
@javascript
Scenario: I should see instructions on how to import from GitHub
Given I see "New project" page
When I click on "Import project from GitHub" When I click on "Import project from GitHub"
Then I see instructions on how to import from GitHub Then I see instructions on how to import from GitHub
@javascript
Scenario: I should see Google Code import page
Given I see "New project" page
When I click on "Google Code"
Then I redirected to Google Code import page
...@@ -13,8 +13,17 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps ...@@ -13,8 +13,17 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
expect(page).to have_content('Project path') expect(page).to have_content('Project path')
end end
step 'I see all possible import optios' do
expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket')
expect(page).to have_link('GitLab.com')
expect(page).to have_link('Gitorious.org')
expect(page).to have_link('Google Code')
expect(page).to have_link('Any repo by URL')
end
step 'I click on "Import project from GitHub"' do step 'I click on "Import project from GitHub"' do
first('.how_to_import_link').click first('.import_github').click
end end
step 'I see instructions on how to import from GitHub' do step 'I see instructions on how to import from GitHub' do
...@@ -26,4 +35,24 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps ...@@ -26,4 +35,24 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
expect(element).not_to be_visible unless element == github_modal expect(element).not_to be_visible unless element == github_modal
end end
end end
step 'I click on "Any repo by URL"' do
first('.import_git').click
end
step 'I see instructions on how to import from Git URL' do
git_import_instructions = first('.js-toggle-content')
expect(git_import_instructions).to be_visible
expect(git_import_instructions).to have_content "Git repository URL"
expect(git_import_instructions).to have_content "The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL:"
end
step 'I click on "Google Code"' do
first('.import_google_code').click
end
step 'I redirected to Google Code import page' do
expect(current_path).to eq new_import_google_code_path
end
end end
...@@ -22,7 +22,8 @@ module Gitlab ...@@ -22,7 +22,8 @@ module Gitlab
sign_in_text: Settings.extra['sign_in_text'], sign_in_text: Settings.extra['sign_in_text'],
restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'], restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'],
max_attachment_size: Settings.gitlab['max_attachment_size'], max_attachment_size: Settings.gitlab['max_attachment_size'],
session_expire_delay: Settings.gitlab['session_expire_delay'] session_expire_delay: Settings.gitlab['session_expire_delay'],
import_sources: Settings.gitlab['import_sources']
) )
end end
end end
......
# Gitlab::ImportSources module
#
# Define import sources that can be used
# during the creation of new project
#
module Gitlab
module ImportSources
extend CurrentSettings
class << self
def values
options.values
end
def options
{
'GitHub' => 'github',
'Bitbucket' => 'bitbucket',
'GitLab.com' => 'gitlab',
'Gitorious.org' => 'gitorious',
'Google Code' => 'google_code',
'Any repo by URL' => 'git',
}
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