Commit 4bfb98ddc90bcc6076e2819619fec7607e74358b
Exists in
master
and in
4 other branches
Merge pull request #2877 from former03/feature_groups_api
Add groups api
Showing
6 changed files
with
206 additions
and
1 deletions
Show diff stats
doc/api/README.md
| ... | ... | @@ -32,6 +32,7 @@ When listing resources you can pass the following parameters: |
| 32 | 32 | + [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md) |
| 33 | 33 | + [Session](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/session.md) |
| 34 | 34 | + [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md) |
| 35 | ++ [Groups](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/groups.md) | |
| 35 | 36 | + [Snippets](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/snippets.md) |
| 36 | 37 | + [Repositories](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/repositories.md) |
| 37 | 38 | + [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md) | ... | ... |
| ... | ... | @@ -0,0 +1,45 @@ |
| 1 | +## List project groups | |
| 2 | + | |
| 3 | +Get a list of groups. (As user: my groups, as admin: all groups) | |
| 4 | + | |
| 5 | +``` | |
| 6 | +GET /groups | |
| 7 | +``` | |
| 8 | + | |
| 9 | +```json | |
| 10 | +[ | |
| 11 | + { | |
| 12 | + "id": 1, | |
| 13 | + "name": "Foobar Group", | |
| 14 | + "path": "foo-bar", | |
| 15 | + "owner_id": 18 | |
| 16 | + } | |
| 17 | +] | |
| 18 | +``` | |
| 19 | + | |
| 20 | +## Details of group | |
| 21 | + | |
| 22 | +Get all details of a group. | |
| 23 | + | |
| 24 | +``` | |
| 25 | +GET /groups/:id | |
| 26 | +``` | |
| 27 | + | |
| 28 | +Parameters: | |
| 29 | + | |
| 30 | ++ `id` (required) - The ID of a group | |
| 31 | + | |
| 32 | +## New group | |
| 33 | + | |
| 34 | +Create a new project group. Available only for admin | |
| 35 | + | |
| 36 | +``` | |
| 37 | +POST /groups | |
| 38 | +``` | |
| 39 | + | |
| 40 | +Parameters: | |
| 41 | ++ `name` (required) - Email | |
| 42 | ++ `path` - Password | |
| 43 | + | |
| 44 | +Will return created group with status `201 Created` on success, or `404 Not found` on fail. | |
| 45 | + | ... | ... |
lib/api.rb
lib/api/entities.rb
| ... | ... | @@ -32,6 +32,15 @@ module Gitlab |
| 32 | 32 | end |
| 33 | 33 | end |
| 34 | 34 | |
| 35 | + class Group < Grape::Entity | |
| 36 | + expose :id, :name, :path, :owner_id | |
| 37 | + end | |
| 38 | + | |
| 39 | + class GroupDetail < Group | |
| 40 | + expose :projects, using: Entities::Project | |
| 41 | + end | |
| 42 | + | |
| 43 | + | |
| 35 | 44 | class RepoObject < Grape::Entity |
| 36 | 45 | expose :name, :commit |
| 37 | 46 | expose :protected do |repo, options| | ... | ... |
| ... | ... | @@ -0,0 +1,56 @@ |
| 1 | +module Gitlab | |
| 2 | + # groups API | |
| 3 | + class Groups < Grape::API | |
| 4 | + before { authenticate! } | |
| 5 | + | |
| 6 | + resource :groups do | |
| 7 | + # Get a groups list | |
| 8 | + # | |
| 9 | + # Example Request: | |
| 10 | + # GET /groups | |
| 11 | + get do | |
| 12 | + if current_user.admin | |
| 13 | + @groups = paginate Group | |
| 14 | + else | |
| 15 | + @groups = paginate current_user.groups | |
| 16 | + end | |
| 17 | + present @groups, with: Entities::Group | |
| 18 | + end | |
| 19 | + | |
| 20 | + # Create group. Available only for admin | |
| 21 | + # | |
| 22 | + # Parameters: | |
| 23 | + # name (required) - Name | |
| 24 | + # path (required) - Path | |
| 25 | + # Example Request: | |
| 26 | + # POST /groups | |
| 27 | + post do | |
| 28 | + authenticated_as_admin! | |
| 29 | + attrs = attributes_for_keys [:name, :path] | |
| 30 | + @group = Group.new(attrs) | |
| 31 | + @group.owner = current_user | |
| 32 | + | |
| 33 | + if @group.save | |
| 34 | + present @group, with: Entities::Group | |
| 35 | + else | |
| 36 | + not_found! | |
| 37 | + end | |
| 38 | + end | |
| 39 | + | |
| 40 | + # Get a single group, with containing projects | |
| 41 | + # | |
| 42 | + # Parameters: | |
| 43 | + # id (required) - The ID of a group | |
| 44 | + # Example Request: | |
| 45 | + # GET /groups/:id | |
| 46 | + get ":id" do | |
| 47 | + @group = Group.find(params[:id]) | |
| 48 | + if current_user.admin or current_user.groups.include? @group | |
| 49 | + present @group, with: Entities::GroupDetail | |
| 50 | + else | |
| 51 | + not_found! | |
| 52 | + end | |
| 53 | + end | |
| 54 | + end | |
| 55 | + end | |
| 56 | +end | ... | ... |
| ... | ... | @@ -0,0 +1,93 @@ |
| 1 | +require 'spec_helper' | |
| 2 | + | |
| 3 | +describe Gitlab::API do | |
| 4 | + include ApiHelpers | |
| 5 | + | |
| 6 | + let(:user1) { create(:user) } | |
| 7 | + let(:user2) { create(:user) } | |
| 8 | + let(:admin) { create(:admin) } | |
| 9 | + let!(:group1) { create(:group, owner: user1) } | |
| 10 | + let!(:group2) { create(:group, owner: user2) } | |
| 11 | + | |
| 12 | + describe "GET /groups" do | |
| 13 | + context "when unauthenticated" do | |
| 14 | + it "should return authentication error" do | |
| 15 | + get api("/groups") | |
| 16 | + response.status.should == 401 | |
| 17 | + end | |
| 18 | + end | |
| 19 | + | |
| 20 | + context "when authenticated as user" do | |
| 21 | + it "normal user: should return an array of groups of user1" do | |
| 22 | + get api("/groups", user1) | |
| 23 | + response.status.should == 200 | |
| 24 | + json_response.should be_an Array | |
| 25 | + json_response.length.should == 1 | |
| 26 | + json_response.first['name'].should == group1.name | |
| 27 | + end | |
| 28 | + end | |
| 29 | + | |
| 30 | + context "when authenticated as admin" do | |
| 31 | + it "admin: should return an array of all groups" do | |
| 32 | + get api("/groups", admin) | |
| 33 | + response.status.should == 200 | |
| 34 | + json_response.should be_an Array | |
| 35 | + json_response.length.should == 2 | |
| 36 | + end | |
| 37 | + end | |
| 38 | + end | |
| 39 | + | |
| 40 | + describe "GET /groups/:id" do | |
| 41 | + context "when authenticated as user" do | |
| 42 | + it "should return one of user1's groups" do | |
| 43 | + get api("/groups/#{group1.id}", user1) | |
| 44 | + response.status.should == 200 | |
| 45 | + json_response['name'] == group1.name | |
| 46 | + end | |
| 47 | + | |
| 48 | + it "should not return a non existing group" do | |
| 49 | + get api("/groups/1328", user1) | |
| 50 | + response.status.should == 404 | |
| 51 | + end | |
| 52 | + | |
| 53 | + it "should not return a group not attached to user1" do | |
| 54 | + get api("/groups/#{group2.id}", user1) | |
| 55 | + response.status.should == 404 | |
| 56 | + end | |
| 57 | + end | |
| 58 | + | |
| 59 | + context "when authenticated as admin" do | |
| 60 | + it "should return any existing group" do | |
| 61 | + get api("/groups/#{group2.id}", admin) | |
| 62 | + response.status.should == 200 | |
| 63 | + json_response['name'] == group2.name | |
| 64 | + end | |
| 65 | + | |
| 66 | + it "should not return a non existing group" do | |
| 67 | + get api("/groups/1328", admin) | |
| 68 | + response.status.should == 404 | |
| 69 | + end | |
| 70 | + end | |
| 71 | + end | |
| 72 | + | |
| 73 | + describe "POST /groups" do | |
| 74 | + context "when authenticated as user" do | |
| 75 | + it "should not create group" do | |
| 76 | + post api("/groups", user1), attributes_for(:group) | |
| 77 | + response.status.should == 403 | |
| 78 | + end | |
| 79 | + end | |
| 80 | + | |
| 81 | + context "when authenticated as admin" do | |
| 82 | + it "should create group" do | |
| 83 | + post api("/groups", admin), attributes_for(:group) | |
| 84 | + response.status.should == 201 | |
| 85 | + end | |
| 86 | + | |
| 87 | + it "should not create group, duplicate" do | |
| 88 | + post api("/groups", admin), {:name => "Duplicate Test", :path => group2.path} | |
| 89 | + response.status.should == 404 | |
| 90 | + end | |
| 91 | + end | |
| 92 | + end | |
| 93 | +end | ... | ... |