Commit bad3fb89 authored by Olaf Tomalka's avatar Olaf Tomalka

Added fork API paremeter for a specific namespace

Browser interface allows forking to an owned grup.
This commit brings API up to speed by providing optional namespace
parameter to fork API. This allows forking to users and groups under
forker's control using their id or unique name.

Fixes #21591
parent 7d2bd6b9
Please view this file on the master branch, on stable branches it's out of date.
v 8.12.0 (unreleased)
- Add abillity to fork to a specific namespace using API. @ritave <olaf@tomalka.me>
- Prepend blank line to `Closes` message on merge request linked to issue (lukehowell)
- Filter tags by name !6121
- Make push events have equal vertical spacing.
......
......@@ -514,7 +514,7 @@ invalid, 400 is returned.
### Fork project
Forks a project into the user namespace of the authenticated user.
Forks a project into the user namespace of the authenticated user or the one provided.
```
POST /projects/fork/:id
......@@ -523,6 +523,7 @@ POST /projects/fork/:id
Parameters:
- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of the project to be forked
- `namespace` (optional) - The ID or path of the namespace that the project will be forked to
### Star a project
......
......@@ -189,16 +189,28 @@ module API
end
end
# Fork new project for the current user.
# Fork new project for the current user or provided namespace.
#
# Parameters:
# id (required) - The ID of a project
# namespace (optional) - The ID or name of the namespace that the project will be forked into.
# Example Request
# POST /projects/fork/:id
post 'fork/:id' do
attrs = {}
namespace_id = params[:namespace]
if namespace_id.present?
namespace = Namespace.find_by(id: namespace_id) || Namespace.find_by_path_or_name(namespace_id)
if namespace.nil?
not_found!('Target Namespace')
end
authorize! :create_projects, namespace
attrs[:namespace] = namespace
end
@forked_project =
::Projects::ForkService.new(user_project,
current_user).execute
current_user,
attrs).execute
if @forked_project.errors.any?
conflict!(@forked_project.errors.messages)
else
......
......@@ -3,9 +3,15 @@ require 'spec_helper'
describe API::API, api: true do
include ApiHelpers
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:user2) { create(:user, username: 'user2_name') }
let(:user3) { create(:user) }
let(:admin) { create(:admin) }
let(:group) { create(:group, name: 'group_name') }
let(:group2) do
group = create(:group, name: 'group2_name')
group.add_owner(user2)
group
end
let(:project) do
create(:project, creator_id: user.id, namespace: user.namespace)
......@@ -58,6 +64,52 @@ describe API::API, api: true do
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
it 'forks with explicit own user namespace id' do
post api("/projects/fork/#{project.id}?namespace=#{user2.namespace.id}", user2)
expect(response).to have_http_status(201)
expect(json_response['owner']['id']).to eq(user2.id)
end
it 'forks with explicit own user name as namespace' do
post api("/projects/fork/#{project.id}?namespace=#{user2.username}", user2)
expect(response).to have_http_status(201)
expect(json_response['owner']['id']).to eq(user2.id)
end
it 'forks to another user when admin' do
post api("/projects/fork/#{project.id}?namespace=#{user2.username}", admin)
expect(response).to have_http_status(201)
expect(json_response['owner']['id']).to eq(user2.id)
end
it 'fails if trying to fork to another user when not admin' do
post api("/projects/fork/#{project.id}?namespace=#{admin.namespace.id}", user2)
expect(response).to have_http_status(403)
end
it 'fails if trying to fork to non-existent namespace' do
post api("/projects/fork/#{project.id}?namespace=42424242", user2)
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Target Namespace Not Found')
end
it 'forks to owned group' do
post api("/projects/fork/#{project.id}?namespace=#{group2.name}", user2)
expect(response).to have_http_status(201)
expect(json_response['namespace']['name']).to eq(group2.name)
end
it 'fails to fork to not owned group' do
post api("/projects/fork/#{project.id}?namespace=#{group.name}", user2)
expect(response).to have_http_status(403)
end
it 'forks to not owned group when admin' do
post api("/projects/fork/#{project.id}?namespace=#{group.name}", admin)
expect(response).to have_http_status(201)
expect(json_response['namespace']['name']).to eq(group.name)
end
end
context 'when unauthenticated' do
......
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