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