Commit 318350e34fcd0b0754526fdfb94c484b8bb88837

Authored by Dmitriy Zaporozhets
2 parents 9eb01904 84a3f8fc

Merge branch 'api' of https://github.com/NARKOZ/gitlabhq

Conflicts:
	Gemfile.lock
Gemfile
... ... @@ -18,6 +18,7 @@ gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git"
18 18 gem 'grack', :git => "https://github.com/gitlabhq/grack.git"
19 19 gem "linguist", "~> 1.0.0", :git => "https://github.com/gitlabhq/linguist.git"
20 20  
  21 +gem "grape"
21 22 gem "stamp"
22 23 gem "kaminari"
23 24 gem "haml-rails"
... ...
Gemfile.lock
... ... @@ -169,6 +169,12 @@ GEM
169 169 gherkin (2.11.0)
170 170 json (>= 1.4.6)
171 171 git (1.2.5)
  172 + grape (0.2.0)
  173 + hashie (~> 1.2)
  174 + multi_json
  175 + multi_xml
  176 + rack
  177 + rack-mount
172 178 haml (3.1.6)
173 179 haml-rails (0.3.4)
174 180 actionpack (~> 3.0)
... ... @@ -230,6 +236,8 @@ GEM
230 236 rack (1.4.1)
231 237 rack-cache (1.2)
232 238 rack (>= 0.4)
  239 + rack-mount (0.8.3)
  240 + rack (>= 1.0.0)
233 241 rack-protection (1.2.0)
234 242 rack
235 243 rack-ssl (1.3.2)
... ... @@ -381,6 +389,7 @@ DEPENDENCIES
381 389 git
382 390 gitolite!
383 391 grack!
  392 + grape
384 393 grit!
385 394 haml-rails
386 395 httparty
... ...
config/routes.rb
... ... @@ -4,6 +4,10 @@ Gitlab::Application.routes.draw do
4 4 #
5 5 get 'search' => "search#show"
6 6  
  7 + # API
  8 + require 'api'
  9 + mount Gitlab::API => '/api'
  10 +
7 11 # Optionally, enable Resque here
8 12 require 'resque/server'
9 13 mount Resque::Server.new, at: '/info/resque'
... ...
lib/api.rb 0 → 100644
... ... @@ -0,0 +1,61 @@
  1 +require 'api/entities'
  2 +require 'api/helpers'
  3 +
  4 +module Gitlab
  5 + class API < Grape::API
  6 + format :json
  7 + helpers APIHelpers
  8 +
  9 + # Users API
  10 + resource :users do
  11 + before { authenticate! }
  12 +
  13 + # GET /users
  14 + get do
  15 + @users = User.all
  16 + present @users, :with => Entities::User
  17 + end
  18 +
  19 + # GET /users/:id
  20 + get ":id" do
  21 + @user = User.find(params[:id])
  22 + present @user, :with => Entities::User
  23 + end
  24 + end
  25 +
  26 + # GET /user
  27 + get "/user" do
  28 + authenticate!
  29 + present @current_user, :with => Entities::User
  30 + end
  31 +
  32 + # Projects API
  33 + resource :projects do
  34 + before { authenticate! }
  35 +
  36 + # GET /projects
  37 + get do
  38 + @projects = current_user.projects
  39 + present @projects, :with => Entities::Project
  40 + end
  41 +
  42 + # GET /projects/:id
  43 + get ":id" do
  44 + @project = current_user.projects.find_by_code(params[:id])
  45 + present @project, :with => Entities::Project
  46 + end
  47 +
  48 + # GET /projects/:id/repository/branches
  49 + get ":id/repository/branches" do
  50 + @project = current_user.projects.find_by_code(params[:id])
  51 + present @project.repo.heads.sort_by(&:name), :with => Entities::ProjectRepositoryBranches
  52 + end
  53 +
  54 + # GET /projects/:id/repository/tags
  55 + get ":id/repository/tags" do
  56 + @project = current_user.projects.find_by_code(params[:id])
  57 + present @project.repo.tags.sort_by(&:name).reverse, :with => Entities::ProjectRepositoryTags
  58 + end
  59 + end
  60 + end
  61 +end
... ...
lib/api/entities.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +module Gitlab
  2 + module Entities
  3 + class User < Grape::Entity
  4 + expose :id, :email, :name, :bio, :skype, :linkedin, :twitter,
  5 + :dark_scheme, :theme_id, :blocked, :created_at
  6 + end
  7 +
  8 + class Project < Grape::Entity
  9 + expose :id, :code, :name, :description, :path, :default_branch
  10 + expose :owner, :using => Entities::User
  11 + expose :private_flag, :as => :private
  12 + expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at
  13 + end
  14 +
  15 + class ProjectRepositoryBranches < Grape::Entity
  16 + expose :name, :commit
  17 + end
  18 +
  19 + class ProjectRepositoryTags < Grape::Entity
  20 + expose :name, :commit
  21 + end
  22 + end
  23 +end
... ...
lib/api/helpers.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +module Gitlab
  2 + module APIHelpers
  3 + def current_user
  4 + @current_user ||= User.find_by_authentication_token(params[:private_token])
  5 + end
  6 +
  7 + def authenticate!
  8 + error!('401 Unauthorized', 401) unless current_user
  9 + end
  10 + end
  11 +end
... ...
spec/api/projects_spec.rb 0 → 100644
... ... @@ -0,0 +1,55 @@
  1 +require 'spec_helper'
  2 +
  3 +describe Gitlab::API do
  4 + let(:user) { Factory :user }
  5 + let!(:project) { Factory :project, :owner => user }
  6 + before { project.add_access(user, :read) }
  7 +
  8 + describe "GET /projects" do
  9 + it "should return authentication error" do
  10 + get "/api/projects"
  11 + response.status.should == 401
  12 + end
  13 +
  14 + describe "authenticated GET /projects" do
  15 + it "should return an array of projects" do
  16 + get "/api/projects?private_token=#{user.private_token}"
  17 + response.status.should == 200
  18 + json = JSON.parse(response.body)
  19 + json.should be_an Array
  20 + json.first['name'].should == project.name
  21 + json.first['owner']['email'].should == user.email
  22 + end
  23 + end
  24 + end
  25 +
  26 + describe "GET /projects/:id" do
  27 + it "should return a project by id" do
  28 + get "/api/projects/#{project.code}?private_token=#{user.private_token}"
  29 + response.status.should == 200
  30 + json = JSON.parse(response.body)
  31 + json['name'].should == project.name
  32 + json['owner']['email'].should == user.email
  33 + end
  34 + end
  35 +
  36 + describe "GET /projects/:id/repository/branches" do
  37 + it "should return an array of project branches" do
  38 + get "/api/projects/#{project.code}/repository/branches?private_token=#{user.private_token}"
  39 + response.status.should == 200
  40 + json = JSON.parse(response.body)
  41 + json.should be_an Array
  42 + json.first['name'].should == project.repo.heads.sort_by(&:name).first.name
  43 + end
  44 + end
  45 +
  46 + describe "GET /projects/:id/repository/tags" do
  47 + it "should return an array of project tags" do
  48 + get "/api/projects/#{project.code}/repository/tags?private_token=#{user.private_token}"
  49 + response.status.should == 200
  50 + json = JSON.parse(response.body)
  51 + json.should be_an Array
  52 + json.first['name'].should == project.repo.tags.sort_by(&:name).reverse.first.name
  53 + end
  54 + end
  55 +end
... ...
spec/api/users_spec.rb 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +require 'spec_helper'
  2 +
  3 +describe Gitlab::API do
  4 + let(:user) { Factory :user }
  5 +
  6 + describe "GET /users" do
  7 + it "should return authentication error" do
  8 + get "/api/users"
  9 + response.status.should == 401
  10 + end
  11 +
  12 + describe "authenticated GET /users" do
  13 + it "should return an array of users" do
  14 + get "/api/users?private_token=#{user.private_token}"
  15 + response.status.should == 200
  16 + json = JSON.parse(response.body)
  17 + json.should be_an Array
  18 + json.first['email'].should == user.email
  19 + end
  20 + end
  21 + end
  22 +
  23 + describe "GET /users/:id" do
  24 + it "should return a user by id" do
  25 + get "/api/users/#{user.id}?private_token=#{user.private_token}"
  26 + response.status.should == 200
  27 + JSON.parse(response.body)['email'].should == user.email
  28 + end
  29 + end
  30 +
  31 + describe "GET /user" do
  32 + it "should return current user" do
  33 + get "/api/user?private_token=#{user.private_token}"
  34 + response.status.should == 200
  35 + JSON.parse(response.body)['email'].should == user.email
  36 + end
  37 + end
  38 +end
... ...
spec/spec_helper.rb
... ... @@ -58,4 +58,8 @@ RSpec.configure do |config|
58 58 config.after do
59 59 DatabaseCleaner.clean
60 60 end
  61 +
  62 + config.include RSpec::Rails::RequestExampleGroup, :type => :request, :example_group => {
  63 + :file_path => /spec\/api/
  64 + }
61 65 end
... ...