From e8b3b92ddebc47595fe4b69dc5b5a3a6dd1365ab Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Sun, 13 Mar 2016 11:46:16 +0100
Subject: [PATCH] Bring share project with group API from EE

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 doc/api/projects.md                | 14 ++++++++++++
 lib/api/entities.rb                |  4 ++++
 lib/api/projects.rb                | 27 ++++++++++++++++++++++
 spec/requests/api/projects_spec.rb | 36 ++++++++++++++++++++++++++++++
 4 files changed, 81 insertions(+)

diff --git a/doc/api/projects.md b/doc/api/projects.md
index 9e9486cd87a..3703f4b327a 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -619,6 +619,20 @@ Revoking team membership for a user who is not currently a team member is consid
 Please note that the returned JSON currently differs slightly. Thus you should not
 rely on the returned JSON structure.
 
+### Share project with group
+
+Allow to share project with group.
+
+```
+POST /projects/:id/share
+```
+
+Parameters:
+
+- `id` (required) - The ID of a project
+- `group_id` (required) - The ID of a group
+- `group_access` (required) - Level of permissions for sharing
+
 ## Hooks
 
 Also called Project Hooks and Webhooks.
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 5b5b8bd044b..d96eaef7c0a 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -243,6 +243,10 @@ module API
       end
     end
 
+    class ProjectGroupLink < Grape::Entity
+      expose :id, :project_id, :group_id, :group_access
+    end
+
     class Namespace < Grape::Entity
       expose :id, :path, :kind
     end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 6067c8b4a5e..6fcb5261e40 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -290,6 +290,33 @@ module API
         end
       end
 
+      # Share project with group
+      #
+      # Parameters:
+      #   id (required) - The ID of a project
+      #   group_id (required) - The ID of a group
+      #   group_access (required) - Level of permissions for sharing
+      #
+      # Example Request:
+      #   POST /projects/:id/share
+      post ":id/share" do
+        authorize! :admin_project, user_project
+        required_attributes! [:group_id, :group_access]
+
+        unless user_project.allowed_to_share_with_group?
+          return render_api_error!("The project sharing with group is disabled", 400)
+        end
+
+        link = user_project.project_group_links.new
+        link.group_id = params[:group_id]
+        link.group_access = params[:group_access]
+        if link.save
+          present link, with: Entities::ProjectGroupLink
+        else
+          render_api_error!(link.errors.full_messages.first, 409)
+        end
+      end
+
       # Upload a file
       #
       # Parameters:
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 9f2365a4832..a6699cdc81c 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -747,6 +747,42 @@ describe API::API, api: true  do
     end
   end
 
+  describe "POST /projects/:id/share" do
+    let(:group) { create(:group) }
+
+    it "should share project with group" do
+      expect do
+        post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER
+      end.to change { ProjectGroupLink.count }.by(1)
+
+      expect(response.status).to eq 201
+      expect(json_response['group_id']).to eq group.id
+      expect(json_response['group_access']).to eq Gitlab::Access::DEVELOPER
+    end
+
+    it "should return a 400 error when group id is not given" do
+      post api("/projects/#{project.id}/share", user), group_access: Gitlab::Access::DEVELOPER
+      expect(response.status).to eq 400
+    end
+
+    it "should return a 400 error when access level is not given" do
+      post api("/projects/#{project.id}/share", user), group_id: group.id
+      expect(response.status).to eq 400
+    end
+
+    it "should return a 400 error when sharing is disabled" do
+      project.namespace.update(share_with_group_lock: true)
+      post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER
+      expect(response.status).to eq 400
+    end
+
+    it "should return a 409 error when wrong params passed" do
+      post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: 1234
+      expect(response.status).to eq 409
+      expect(json_response['message']).to eq 'Group access is not included in the list'
+    end
+  end
+
   describe 'GET /projects/search/:query' do
     let!(:query) { 'query'}
     let!(:search)           { create(:empty_project, name: query, creator_id: user.id, namespace: user.namespace) }
-- 
GitLab