Commit 0d0042d2 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'import-current-user' into 'master'

Import GitHub, Bitbucket or GitLab.com projects owned by authenticated user into current namespace.

Addresses #1347.

Untested since I'm in a bit of a hurry. Will definitely have time to test and add unit tests before the 7.10 release :)

See merge request !481
parents 424cbf46 d92e4ccc
......@@ -55,6 +55,7 @@ v 7.10.0 (unreleased)
- Ability to skip some items from backup (database, respositories or uploads)
- Fix "Hello @username." references not working by no longer allowing usernames to end in period.
- Archive repositories in background worker.
- Import GitHub, Bitbucket or GitLab.com projects owned by authenticated user into current namespace.
v 7.9.2
......
......@@ -36,8 +36,11 @@ class Import::BitbucketController < Import::BaseController
def create
@repo_id = params[:repo_id] || ""
repo = client.project(@repo_id.gsub("___", "/"))
@target_namespace = params[:new_namespace].presence || repo["owner"]
@project_name = repo["slug"]
repo_owner = repo["owner"]
repo_owner = current_user.username if repo_owner == client.user["user"]["username"]
@target_namespace = params[:new_namespace].presence || repo_owner
namespace = get_or_create_namespace || (render and return)
......
......@@ -31,8 +31,11 @@ class Import::GithubController < Import::BaseController
def create
@repo_id = params[:repo_id].to_i
repo = client.repo(@repo_id)
@target_namespace = params[:new_namespace].presence || repo.owner.login
@project_name = repo.name
repo_owner = repo.owner.login
repo_owner = current_user.username if repo_owner == client.user.login
@target_namespace = params[:new_namespace].presence || repo_owner
namespace = get_or_create_namespace || (render and return)
......
......@@ -28,8 +28,11 @@ class Import::GitlabController < Import::BaseController
def create
@repo_id = params[:repo_id].to_i
repo = client.project(@repo_id)
@target_namespace = params[:new_namespace].presence || repo["namespace"]["path"]
@project_name = repo["name"]
repo_owner = repo["namespace"]["path"]
repo_owner = current_user.username if repo_owner == client.user["username"]
@target_namespace = params[:new_namespace].presence || repo_owner
namespace = get_or_create_namespace || (render and return)
......
......@@ -28,6 +28,10 @@ module Gitlab
client.auth_code.get_token(code, redirect_uri: redirect_uri).token
end
def user
api.get("/api/v3/user").parsed
end
def issues(project_identifier)
lazy_page_iterator(PER_PAGE) do |page|
api.get("/api/v3/projects/#{project_identifier}/issues?per_page=#{PER_PAGE}&page=#{page}").parsed
......
......@@ -55,24 +55,109 @@ describe Import::BitbucketController do
end
describe "POST create" do
before do
@repo = {
slug: 'vim',
owner: "john"
let(:bitbucket_username) { user.username }
let(:bitbucket_user) {
{
user: {
username: bitbucket_username
}
}.with_indifferent_access
end
}
it "takes already existing namespace" do
namespace = create(:namespace, name: "john", owner: user)
expect(Gitlab::BitbucketImport::KeyAdder).
to receive(:new).with(@repo, user).
and_return(double(execute: true))
expect(Gitlab::BitbucketImport::ProjectCreator).
to receive(:new).with(@repo, namespace, user).
let(:bitbucket_repo) {
{
slug: "vim",
owner: bitbucket_username
}.with_indifferent_access
}
before do
allow(Gitlab::BitbucketImport::KeyAdder).
to receive(:new).with(bitbucket_repo, user).
and_return(double(execute: true))
controller.stub_chain(:client, :project).and_return(@repo)
post :create, format: :js
controller.stub_chain(:client, :user).and_return(bitbucket_user)
controller.stub_chain(:client, :project).and_return(bitbucket_repo)
end
context "when the repository owner is the Bitbucket user" do
context "when the Bitbucket user and GitLab user's usernames match" do
it "takes the current user's namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator).
to receive(:new).with(bitbucket_repo, user.namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
context "when the Bitbucket user and GitLab user's usernames don't match" do
let(:bitbucket_username) { "someone_else" }
it "takes the current user's namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator).
to receive(:new).with(bitbucket_repo, user.namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
end
context "when the repository owner is not the Bitbucket user" do
let(:other_username) { "someone_else" }
before do
bitbucket_repo["owner"] = other_username
end
context "when a namespace with the Bitbucket user's username already exists" do
let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) }
context "when the namespace is owned by the GitLab user" do
it "takes the existing namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator).
to receive(:new).with(bitbucket_repo, existing_namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
context "when the namespace is not owned by the GitLab user" do
before do
existing_namespace.owner = create(:user)
existing_namespace.save
end
it "doesn't create a project" do
expect(Gitlab::BitbucketImport::ProjectCreator).
not_to receive(:new)
post :create, format: :js
end
end
end
context "when a namespace with the Bitbucket user's username doesn't exist" do
it "creates the namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator).
to receive(:new).and_return(double(execute: true))
post :create, format: :js
expect(Namespace.where(name: other_username).first).not_to be_nil
end
it "takes the new namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator).
to receive(:new).with(bitbucket_repo, an_instance_of(Group), user).
and_return(double(execute: true))
post :create, format: :js
end
end
end
end
end
......@@ -56,18 +56,98 @@ describe Import::GithubController do
end
describe "POST create" do
let(:github_username) { user.username }
let(:github_user) {
OpenStruct.new(login: github_username)
}
let(:github_repo) {
OpenStruct.new(name: 'vim', full_name: "#{github_username}/vim", owner: OpenStruct.new(login: github_username))
}
before do
@repo = OpenStruct.new(login: 'vim', full_name: 'asd/vim', owner: OpenStruct.new(login: "john"))
controller.stub_chain(:client, :user).and_return(github_user)
controller.stub_chain(:client, :repo).and_return(github_repo)
end
context "when the repository owner is the GitHub user" do
context "when the GitHub user and GitLab user's usernames match" do
it "takes the current user's namespace" do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, user.namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
context "when the GitHub user and GitLab user's usernames don't match" do
let(:github_username) { "someone_else" }
it "takes the current user's namespace" do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, user.namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
end
it "takes already existing namespace" do
namespace = create(:namespace, name: "john", owner: user)
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(@repo, namespace, user).
and_return(double(execute: true))
controller.stub_chain(:client, :repo).and_return(@repo)
context "when the repository owner is not the GitHub user" do
let(:other_username) { "someone_else" }
before do
github_repo.owner = OpenStruct.new(login: other_username)
end
context "when a namespace with the GitHub user's username already exists" do
let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) }
context "when the namespace is owned by the GitLab user" do
it "takes the existing namespace" do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, existing_namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
context "when the namespace is not owned by the GitLab user" do
before do
existing_namespace.owner = create(:user)
existing_namespace.save
end
it "doesn't create a project" do
expect(Gitlab::GithubImport::ProjectCreator).
not_to receive(:new)
post :create, format: :js
end
end
end
context "when a namespace with the GitHub user's username doesn't exist" do
it "creates the namespace" do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).and_return(double(execute: true))
post :create, format: :js
expect(Namespace.where(name: other_username).first).not_to be_nil
end
it "takes the new namespace" do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, an_instance_of(Group), user).
and_return(double(execute: true))
post :create, format: :js
post :create, format: :js
end
end
end
end
end
......@@ -48,23 +48,105 @@ describe Import::GitlabController do
end
describe "POST create" do
before do
@repo = {
let(:gitlab_username) { user.username }
let(:gitlab_user) {
{
username: gitlab_username
}.with_indifferent_access
}
let(:gitlab_repo) {
{
path: 'vim',
path_with_namespace: 'asd/vim',
owner: {name: "john"},
namespace: {path: "john"}
path_with_namespace: "#{gitlab_username}/vim",
owner: { name: gitlab_username },
namespace: { path: gitlab_username }
}.with_indifferent_access
}
before do
controller.stub_chain(:client, :user).and_return(gitlab_user)
controller.stub_chain(:client, :project).and_return(gitlab_repo)
end
context "when the repository owner is the GitLab.com user" do
context "when the GitLab.com user and GitLab server user's usernames match" do
it "takes the current user's namespace" do
expect(Gitlab::GitlabImport::ProjectCreator).
to receive(:new).with(gitlab_repo, user.namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
context "when the GitLab.com user and GitLab server user's usernames don't match" do
let(:gitlab_username) { "someone_else" }
it "takes the current user's namespace" do
expect(Gitlab::GitlabImport::ProjectCreator).
to receive(:new).with(gitlab_repo, user.namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
end
it "takes already existing namespace" do
namespace = create(:namespace, name: "john", owner: user)
expect(Gitlab::GitlabImport::ProjectCreator).
to receive(:new).with(@repo, namespace, user).
and_return(double(execute: true))
controller.stub_chain(:client, :project).and_return(@repo)
context "when the repository owner is not the GitLab.com user" do
let(:other_username) { "someone_else" }
before do
gitlab_repo["namespace"]["path"] = other_username
end
context "when a namespace with the GitLab.com user's username already exists" do
let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) }
context "when the namespace is owned by the GitLab server user" do
it "takes the existing namespace" do
expect(Gitlab::GitlabImport::ProjectCreator).
to receive(:new).with(gitlab_repo, existing_namespace, user).
and_return(double(execute: true))
post :create, format: :js
end
end
context "when the namespace is not owned by the GitLab server user" do
before do
existing_namespace.owner = create(:user)
existing_namespace.save
end
it "doesn't create a project" do
expect(Gitlab::GitlabImport::ProjectCreator).
not_to receive(:new)
post :create, format: :js
end
end
end
context "when a namespace with the GitLab.com user's username doesn't exist" do
it "creates the namespace" do
expect(Gitlab::GitlabImport::ProjectCreator).
to receive(:new).and_return(double(execute: true))
post :create, format: :js
expect(Namespace.where(name: other_username).first).not_to be_nil
end
it "takes the new namespace" do
expect(Gitlab::GitlabImport::ProjectCreator).
to receive(:new).with(gitlab_repo, an_instance_of(Group), user).
and_return(double(execute: true))
post :create, format: :js
post :create, format: :js
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