From 737f322e41a640194b3df1a4c6cd2b1019268221 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 31 Mar 2015 16:34:13 +0200 Subject: Import GitHub, Bitbucket or GitLab.com projects owned by authenticated user into current namespace. --- CHANGELOG | 1 + app/controllers/import/bitbucket_controller.rb | 5 ++++- app/controllers/import/github_controller.rb | 5 ++++- app/controllers/import/gitlab_controller.rb | 5 ++++- lib/gitlab/gitlab_import/client.rb | 4 ++++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 37054da46b8..23ceb350500 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -48,6 +48,7 @@ v 7.10.0 (unreleased) - Prevent note form from being cleared when submitting failed. - Improve file icons rendering on tree (Sullivan Sénéchal) - API: Add pagination to project events + - Import GitHub, Bitbucket or GitLab.com projects owned by authenticated user into current namespace. v 7.9.0 - Send EmailsOnPush email when branch or tag is created or deleted. diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index 83ebc5fddca..bb8d7e0235c 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -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) diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index 8650b6464dc..87b41454c77 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -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) diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb index e979dad4b11..bddbfded812 100644 --- a/app/controllers/import/gitlab_controller.rb +++ b/app/controllers/import/gitlab_controller.rb @@ -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) diff --git a/lib/gitlab/gitlab_import/client.rb b/lib/gitlab/gitlab_import/client.rb index f48ede9d067..9c00896c913 100644 --- a/lib/gitlab/gitlab_import/client.rb +++ b/lib/gitlab/gitlab_import/client.rb @@ -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 -- cgit v1.2.1 From d92e4ccc6eeff1c28ed55c4b27a4f97a76d78127 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 1 Apr 2015 17:17:18 +0200 Subject: Add tests. --- .../import/bitbucket_controller_spec.rb | 113 ++++++++++++++++++--- spec/controllers/import/github_controller_spec.rb | 96 +++++++++++++++-- spec/controllers/import/gitlab_controller_spec.rb | 106 ++++++++++++++++--- 3 files changed, 281 insertions(+), 34 deletions(-) diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index 5dd4124061c..c31563e6d77 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -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 diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index 5b967bfcc0c..3d3846b2e3a 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -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 diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index b6b86b1bcee..112e51d431e 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -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 -- cgit v1.2.1