Commit 5fd18ea7 authored by Illya Klymov's avatar Illya Klymov Committed by Mark Chao

Default to the current group when importing from GitHub

* respect auth via token and via session

Changelog: added
parent fc416b60
......@@ -16,12 +16,13 @@ export function initStoreFromElement(element) {
jobsPath,
importPath,
namespacesPath,
defaultTargetNamespace,
paginatable,
} = element.dataset;
return createStore({
initialState: {
defaultTargetNamespace: gon.current_username,
defaultTargetNamespace,
ciCdOnly: parseBoolean(ciCdOnly),
canSelectNamespace: parseBoolean(canSelectNamespace),
provider,
......
......@@ -13,7 +13,13 @@ class Import::BaseController < ApplicationController
provider_repos: serialized_provider_repos,
incompatible_repos: serialized_incompatible_repos }
end
format.html
format.html do
if params[:namespace_id]&.present?
@namespace = Namespace.find_by_id(params[:namespace_id])
render_404 unless current_user.can?(:create_projects, @namespace)
end
end
end
end
......
......@@ -23,24 +23,25 @@ class Import::GithubController < Import::BaseController
if !ci_cd_only? && github_import_configured? && logged_in_with_provider?
go_to_provider_for_permissions
elsif session[access_token_key]
redirect_to status_import_url
redirect_to status_import_url(namespace_id: params[:namespace_id])
end
end
def callback
auth_state = session[auth_state_key]
session[auth_state_key] = nil
auth_state = session.delete(auth_state_key)
namespace_id = session.delete(:namespace_id)
if auth_state.blank? || !ActiveSupport::SecurityUtils.secure_compare(auth_state, params[:state])
provider_unauthorized
else
session[access_token_key] = get_token(params[:code])
redirect_to status_import_url
redirect_to status_import_url(namespace_id: namespace_id)
end
end
def personal_access_token
session[access_token_key] = params[:personal_access_token]&.strip
redirect_to status_import_url
redirect_to status_import_url(namespace_id: params[:namespace_id].presence)
end
def status
......@@ -209,8 +210,8 @@ class Import::GithubController < Import::BaseController
public_send("new_import_#{provider_name}_url", extra_import_params) # rubocop:disable GitlabSecurity/PublicSend
end
def status_import_url
public_send("status_import_#{provider_name}_url", extra_import_params) # rubocop:disable GitlabSecurity/PublicSend
def status_import_url(namespace_id: nil)
public_send("status_import_#{provider_name}_url", extra_import_params.merge({ namespace_id: namespace_id })) # rubocop:disable GitlabSecurity/PublicSend
end
def callback_import_url
......@@ -256,6 +257,7 @@ class Import::GithubController < Import::BaseController
def provider_auth
if !ci_cd_only? && session[access_token_key].blank?
session[:namespace_id] = params[:namespace_id]
go_to_provider_for_permissions
end
end
......
......@@ -3,6 +3,7 @@
- extra_data = local_assigns.fetch(:extra_data, {})
- filterable = local_assigns.fetch(:filterable, true)
- paginatable = local_assigns.fetch(:paginatable, false)
- default_namespace_path = (local_assigns[:default_namespace] || current_user.namespace).full_path
- provider_title = Gitlab::ImportSources.title(provider)
- header_title _("New project"), new_project_path
......@@ -14,6 +15,7 @@
namespaces_path: import_available_namespaces_path,
repos_path: url_for([:status, :import, provider, format: :json]),
jobs_path: url_for([:realtime_changes, :import, provider, format: :json]),
default_target_namespace: default_namespace_path,
import_path: url_for([:import, provider, format: :json]),
filterable: filterable.to_s,
paginatable: paginatable.to_s }.merge(extra_data) }
......@@ -10,7 +10,7 @@
= import_github_authorize_message
- if github_import_configured? && !has_ci_cd_only_params?
= link_to status_import_github_path, class: 'gl-button btn btn-confirm' do
= link_to status_import_github_path(namespace_id: params[:namespace_id]), class: 'gl-button btn btn-confirm' do
= sprite_icon('github', css_class: 'gl-mr-2')
= title
......@@ -23,6 +23,7 @@
= form_tag personal_access_token_import_github_path, method: :post do
.form-group
%label.label-bold= _('Personal Access Token')
= hidden_field_tag(:namespace_id, params[:namespace_id])
= text_field_tag :personal_access_token, '', class: 'form-control gl-form-input', placeholder: _('e.g. %{token}') % { token: '8d3f016698e...' }, data: { qa_selector: 'personal_access_token_field' }
%span.form-text.text-muted
= import_github_personal_access_token_message
......
......@@ -7,4 +7,4 @@
- paginatable = Feature.enabled?(:remove_legacy_github_client)
= render 'import/githubish_status', provider: 'github', paginatable: paginatable
= render 'import/githubish_status', provider: 'github', paginatable: paginatable, default_namespace: @namespace
- active_tab = local_assigns.fetch(:active_tab, 'blank')
- track_label = local_assigns.fetch(:track_label, 'import_project')
- namespace_id = local_assigns.fetch(:destination_namespace_id, nil)
.project-import
.form-group.import-btn-container.clearfix
......@@ -16,7 +17,7 @@
- if github_import_enabled?
%div
= link_to new_import_github_path, class: 'gl-button btn-default btn js-import-github js-import-project-btn', data: { platform: 'github', **tracking_attrs_data(track_label, 'click_button', 'github') } do
= link_to new_import_github_path(namespace_id: namespace_id), class: 'gl-button btn-default btn js-import-github js-import-project-btn', data: { platform: 'github', **tracking_attrs_data(track_label, 'click_button', 'github') } do
.gl-button-icon
= sprite_icon('github')
GitHub
......
......@@ -110,7 +110,7 @@
= _('You can always change your URL later')
.js-import-project-buttons
= render 'projects/import_project_pane'
= render 'projects/import_project_pane', destination_namespace_id: @namespace&.id
- else
.nothing-here-block
%h4= s_('ProjectsNew|No import options available')
......
......@@ -82,11 +82,33 @@ RSpec.describe Import::GithubController do
expect(controller).to redirect_to(new_import_url)
expect(flash[:alert]).to eq('Access denied to your GitHub account.')
end
it "includes namespace_id from session if it is present" do
namespace_id = 1
session[:namespace_id] = 1
get :callback, params: { state: valid_auth_state }
expect(controller).to redirect_to(status_import_github_url(namespace_id: namespace_id))
end
end
end
describe "POST personal_access_token" do
it_behaves_like 'a GitHub-ish import controller: POST personal_access_token'
it 'passes namespace_id param as query param if it was present' do
namespace_id = 5
status_import_url = public_send("status_import_#{provider}_url", { namespace_id: namespace_id })
allow_next_instance_of(Gitlab::LegacyGithubImport::Client) do |client|
allow(client).to receive(:user).and_return(true)
end
post :personal_access_token, params: { personal_access_token: 'some-token', namespace_id: 5 }
expect(controller).to redirect_to(status_import_url)
end
end
describe "GET status" do
......
......@@ -184,6 +184,41 @@ RSpec.shared_examples 'a GitHub-ish import controller: GET status' do
expect(json_response.dig("provider_repos").count).to eq(1)
end
end
context 'when namespace_id query param is provided' do
let_it_be(:current_user) { create(:user) }
let(:namespace) { create(:namespace) }
before do
allow(controller).to receive(:current_user).and_return(current_user)
end
context 'when user is allowed to create projects in this namespace' do
before do
allow(current_user).to receive(:can?).and_return(true)
end
it 'provides namespace to the template' do
get :status, params: { namespace_id: namespace.id }, format: :html
expect(response).to have_gitlab_http_status :ok
expect(assigns(:namespace)).to eq(namespace)
end
end
context 'when user is not allowed to create projects in this namespace' do
before do
allow(current_user).to receive(:can?).and_return(false)
end
it 'renders 404' do
get :status, params: { namespace_id: namespace.id }, format: :html
expect(response).to have_gitlab_http_status :not_found
end
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