From 61ffcab60fef2efcd54b8496aa09de79ee999a2c Mon Sep 17 00:00:00 2001
From: Angus MacArthur <amacarthur@rim.com>
Date: Wed, 14 Nov 2012 15:37:52 -0500
Subject: [PATCH] Additional Admin APIs

---
 lib/api/groups.rb                  | 18 +++++++++++++
 lib/api/projects.rb                | 32 +++++++++++++++++++++++
 lib/api/users.rb                   | 20 +++++++++++++++
 spec/requests/api/groups_spec.rb   | 23 +++++++++++++++++
 spec/requests/api/projects_spec.rb | 41 ++++++++++++++++++++++++++++++
 spec/requests/api/users_spec.rb    | 16 ++++++++++++
 6 files changed, 150 insertions(+)

diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index a67caef0bc..464a2d1566 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -51,6 +51,24 @@ module Gitlab
           not_found!
         end
       end
+
+      # Transfer a project to the Group namespace
+      #
+      # Parameters:
+      #   id - group id
+      #   project_id  - project id
+      # Example Request:
+      #   POST /groups/:id/projects/:project_id
+      post ":id/projects/:project_id" do
+        authenticated_as_admin!
+        @group = Group.find(params[:id])
+        project = Project.find(params[:project_id])
+        if project.transfer(@group)
+          present @group
+        else
+          not_found!
+        end
+      end 
     end
   end
 end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 8f57e5ac79..a39aff9900 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -52,6 +52,38 @@ module Gitlab
         end
       end
 
+      # Create new project for a specified user.  Only available to admin users.
+      #
+      # Parameters:
+      #   user_id (required) - The ID of a user
+      #   name (required) - name for new project
+      #   description (optional) - short project description
+      #   default_branch (optional) - 'master' by default
+      #   issues_enabled (optional) - enabled by default
+      #   wall_enabled (optional) - enabled by default
+      #   merge_requests_enabled (optional) - enabled by default
+      #   wiki_enabled (optional) - enabled by default
+      # Example Request
+      #   POST /projects/user/:user_id
+      post "user/:user_id" do
+        authenticated_as_admin!
+        user = User.find(params[:user_id])
+        attrs = attributes_for_keys [:name,
+                                    :description,
+                                    :default_branch,
+                                    :issues_enabled,
+                                    :wall_enabled,
+                                    :merge_requests_enabled,
+                                    :wiki_enabled]
+        @project = ::Projects::CreateContext.new(user, attrs).execute
+        if @project.saved?
+          present @project, with: Entities::Project
+        else
+          not_found!
+        end
+      end
+
+
       # Get a project team members
       #
       # Parameters:
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 7ea90c75e9..7399d1a503 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -77,6 +77,26 @@ module Gitlab
         end
       end
 
+      # Add ssh key to a specified user. Only available to admin users.
+      #
+      # Parameters:
+      # id (required) - The ID of a user
+      # key (required) - New SSH Key
+      # title (required) - New SSH Key's title
+      # Example Request:
+      # POST /users/:id/keys
+      post ":id/keys" do
+        authenticated_as_admin!
+        user = User.find(params[:id])
+        attrs = attributes_for_keys [:title, :key]
+        key = user.keys.new attrs
+        if key.save
+          present key, with: Entities::SSHKey
+        else
+          not_found!
+        end
+      end
+
       # Delete user. Available only for admin
       #
       # Example Request:
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index c39a422840..63616eef1b 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -90,4 +90,27 @@ describe Gitlab::API do
       end
     end
   end
+
+  describe "POST /groups/:id/projects/:project_id" do
+    let(:project) { create(:project) }
+    before(:each) do
+       project.stub!(:transfer).and_return(true) 
+       Project.stub(:find).and_return(project) 
+    end
+
+
+    context "when authenticated as user" do
+      it "should not transfer project to group" do
+        post api("/groups/#{group1.id}/projects/#{project.id}", user2)
+        response.status.should == 403
+      end
+    end
+
+    context "when authenticated as admin" do
+      it "should transfer project to group" do
+        project.should_receive(:transfer)
+        post api("/groups/#{group1.id}/projects/#{project.id}", admin)
+      end
+    end
+  end
 end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index d410885bd2..d64ed58348 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -6,6 +6,7 @@ describe Gitlab::API do
   let(:user) { create(:user) }
   let(:user2) { create(:user) }
   let(:user3) { create(:user) }
+  let(:admin) { create(:admin) }
   let!(:hook) { create(:project_hook, project: project, url: "http://example.com") }
   let!(:project) { create(:project, namespace: user.namespace ) }
   let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') }
@@ -90,6 +91,46 @@ describe Gitlab::API do
     end
   end
 
+  describe "POST /projects/user/:id" do
+    before { admin }
+
+    it "should create new project without path" do
+      expect { post api("/projects/user/#{user.id}", admin), name: 'foo' }.to change {Project.count}.by(1)
+    end
+
+    it "should not create new project without name" do
+      expect { post api("/projects/user/#{user.id}", admin) }.to_not change {Project.count}
+    end
+
+    it "should respond with 201 on success" do
+      post api("/projects/user/#{user.id}", admin), name: 'foo'
+      response.status.should == 201
+    end
+
+    it "should respond with 404 on failure" do
+      post api("/projects/user/#{user.id}", admin)
+      response.status.should == 404
+    end
+
+    it "should assign attributes to project" do
+      project = attributes_for(:project, {
+        description: Faker::Lorem.sentence,
+        default_branch: 'stable',
+        issues_enabled: false,
+        wall_enabled: false,
+        merge_requests_enabled: false,
+        wiki_enabled: false
+      })
+
+      post api("/projects/user/#{user.id}", admin), project
+
+      project.each_pair do |k,v|
+        next if k == :path
+        json_response[k.to_s].should == v
+      end
+    end
+  end
+
   describe "GET /projects/:id" do
     it "should return a project by id" do
       get api("/projects/#{project.id}", user)
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 33254eed31..e6ac892dfc 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -105,6 +105,22 @@ describe Gitlab::API do
     end
   end
 
+  describe "POST /users/:id/keys" do
+    before { admin }
+
+    it "should not create invalid ssh key" do
+      post api("/users/#{user.id}/keys", admin), { title: "invalid key" }
+      response.status.should == 404
+    end
+
+    it "should create ssh key" do
+      key_attrs = attributes_for :key
+      expect {
+        post api("/users/#{user.id}/keys", admin), key_attrs
+      }.to change{ user.keys.count }.by(1)
+    end
+  end
+
   describe "DELETE /users/:id" do
     before { admin }
 
-- 
2.30.9