Commit 10d3a30b255cd85b2cf7af39814fd7418eecd838
1 parent
4cc169d3
Exists in
master
and in
4 other branches
APi for commits. Better api docs
Showing
10 changed files
with
199 additions
and
79 deletions
Show diff stats
Guardfile
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | guard 'rspec', :version => 2, :all_on_start => false, :all_after_pass => false do |
| 5 | 5 | watch(%r{^spec/.+_spec\.rb$}) |
| 6 | 6 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } |
| 7 | + watch(%r{^lib/api/(.+)\.rb$}) { |m| "spec/requests/api/#{m[1]}_spec.rb" } | |
| 7 | 8 | watch('spec/spec_helper.rb') { "spec" } |
| 8 | 9 | |
| 9 | 10 | # Rails example | ... | ... |
app/views/help/api.html.haml
| 1 | -%h3 API | |
| 1 | +%h3.page_title API | |
| 2 | 2 | .back_link |
| 3 | 3 | = link_to help_path do |
| 4 | 4 | ← to index |
| 5 | -%hr | |
| 5 | +%br | |
| 6 | 6 | |
| 7 | -%ol | |
| 7 | +%ul.nav.nav-tabs.log-tabs | |
| 8 | + %li.active | |
| 9 | + = link_to "README", "#README", 'data-toggle' => 'tab' | |
| 8 | 10 | %li |
| 9 | - %a{href: "#README"} README | |
| 11 | + = link_to "Projects", "#projects", 'data-toggle' => 'tab' | |
| 10 | 12 | %li |
| 11 | - %a{href: "#projects"} Projects | |
| 13 | + = link_to "Snippets", "#snippets", 'data-toggle' => 'tab' | |
| 12 | 14 | %li |
| 13 | - %a{href: "#snippets"} Snippets | |
| 15 | + = link_to "Users", "#users", 'data-toggle' => 'tab' | |
| 14 | 16 | %li |
| 15 | - %a{href: "#users"} Users | |
| 17 | + = link_to "Session", "#session", 'data-toggle' => 'tab' | |
| 16 | 18 | %li |
| 17 | - %a{href: "#session"} Session | |
| 19 | + = link_to "Issues", "#issues", 'data-toggle' => 'tab' | |
| 18 | 20 | %li |
| 19 | - %a{href: "#issues"} Issues | |
| 21 | + = link_to "Milestones", "#milestones", 'data-toggle' => 'tab' | |
| 20 | 22 | %li |
| 21 | - %a{href: "#milestones"} Milestones | |
| 22 | - | |
| 23 | -.file_holder#README | |
| 24 | - .file_title | |
| 25 | - %i.icon-file | |
| 26 | - README | |
| 27 | - .file_content.wiki | |
| 28 | - = preserve do | |
| 29 | - = markdown File.read(Rails.root.join("doc", "api", "README.md")) | |
| 30 | - | |
| 31 | -%br | |
| 32 | - | |
| 33 | -.file_holder#projects | |
| 34 | - .file_title | |
| 35 | - %i.icon-file | |
| 36 | - Projects | |
| 37 | - .file_content.wiki | |
| 38 | - = preserve do | |
| 39 | - = markdown File.read(Rails.root.join("doc", "api", "projects.md")) | |
| 40 | - | |
| 41 | -%br | |
| 42 | - | |
| 43 | -.file_holder#snippets | |
| 44 | - .file_title | |
| 45 | - %i.icon-file | |
| 46 | - Projects Snippets | |
| 47 | - .file_content.wiki | |
| 48 | - = preserve do | |
| 49 | - = markdown File.read(Rails.root.join("doc", "api", "snippets.md")) | |
| 23 | + = link_to "Commits", "#commits", 'data-toggle' => 'tab' | |
| 50 | 24 | |
| 51 | -%br | |
| 25 | +.tab-content | |
| 26 | + .tab-pane.active#README | |
| 27 | + .file_holder | |
| 28 | + .file_title | |
| 29 | + %i.icon-file | |
| 30 | + README | |
| 31 | + .file_content.wiki | |
| 32 | + = preserve do | |
| 33 | + = markdown File.read(Rails.root.join("doc", "api", "README.md")) | |
| 52 | 34 | |
| 53 | -.file_holder#users | |
| 54 | - .file_title | |
| 55 | - %i.icon-file | |
| 56 | - Users | |
| 57 | - .file_content.wiki | |
| 58 | - = preserve do | |
| 59 | - = markdown File.read(Rails.root.join("doc", "api", "users.md")) | |
| 35 | + .tab-pane#projects | |
| 36 | + .file_holder | |
| 37 | + .file_title | |
| 38 | + %i.icon-file | |
| 39 | + Projects | |
| 40 | + .file_content.wiki | |
| 41 | + = preserve do | |
| 42 | + = markdown File.read(Rails.root.join("doc", "api", "projects.md")) | |
| 60 | 43 | |
| 61 | -%br | |
| 44 | + .tab-pane#snippets | |
| 45 | + .file_holder | |
| 46 | + .file_title | |
| 47 | + %i.icon-file | |
| 48 | + Projects Snippets | |
| 49 | + .file_content.wiki | |
| 50 | + = preserve do | |
| 51 | + = markdown File.read(Rails.root.join("doc", "api", "snippets.md")) | |
| 62 | 52 | |
| 63 | -.file_holder#session | |
| 64 | - .file_title | |
| 65 | - %i.icon-file | |
| 66 | - Session | |
| 67 | - .file_content.wiki | |
| 68 | - = preserve do | |
| 69 | - = markdown File.read(Rails.root.join("doc", "api", "session.md")) | |
| 53 | + .tab-pane#users | |
| 54 | + .file_holder | |
| 55 | + .file_title | |
| 56 | + %i.icon-file | |
| 57 | + Users | |
| 58 | + .file_content.wiki | |
| 59 | + = preserve do | |
| 60 | + = markdown File.read(Rails.root.join("doc", "api", "users.md")) | |
| 70 | 61 | |
| 71 | -%br | |
| 62 | + .tab-pane#session | |
| 63 | + .file_holder | |
| 64 | + .file_title | |
| 65 | + %i.icon-file | |
| 66 | + Session | |
| 67 | + .file_content.wiki | |
| 68 | + = preserve do | |
| 69 | + = markdown File.read(Rails.root.join("doc", "api", "session.md")) | |
| 72 | 70 | |
| 73 | -.file_holder#issues | |
| 74 | - .file_title | |
| 75 | - %i.icon-file | |
| 76 | - Issues | |
| 77 | - .file_content.wiki | |
| 78 | - = preserve do | |
| 79 | - = markdown File.read(Rails.root.join("doc", "api", "issues.md")) | |
| 71 | + .tab-pane#issues | |
| 72 | + .file_holder | |
| 73 | + .file_title | |
| 74 | + %i.icon-file | |
| 75 | + Issues | |
| 76 | + .file_content.wiki | |
| 77 | + = preserve do | |
| 78 | + = markdown File.read(Rails.root.join("doc", "api", "issues.md")) | |
| 80 | 79 | |
| 81 | -%br | |
| 80 | + .tab-pane#milestones | |
| 81 | + .file_holder | |
| 82 | + .file_title | |
| 83 | + %i.icon-file | |
| 84 | + Milestones | |
| 85 | + .file_content.wiki | |
| 86 | + = preserve do | |
| 87 | + = markdown File.read(Rails.root.join("doc", "api", "milestones.md")) | |
| 82 | 88 | |
| 83 | -.file_holder#milestones | |
| 84 | - .file_title | |
| 85 | - %i.icon-file | |
| 86 | - Milestones | |
| 87 | - .file_content.wiki | |
| 88 | - = preserve do | |
| 89 | - = markdown File.read(Rails.root.join("doc", "api", "milestones.md")) | |
| 89 | + .tab-pane#commits | |
| 90 | + .file_holder | |
| 91 | + .file_title | |
| 92 | + %i.icon-file | |
| 93 | + Commits | |
| 94 | + .file_content.wiki | |
| 95 | + = preserve do | |
| 96 | + = markdown File.read(Rails.root.join("doc", "api", "commits.md")) | ... | ... |
| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | +## List Commits | |
| 2 | + | |
| 3 | +Get a list of project commits. | |
| 4 | + | |
| 5 | +``` | |
| 6 | +GET /projects/:id/commits | |
| 7 | +``` | |
| 8 | + | |
| 9 | +Parameters: | |
| 10 | + | |
| 11 | ++ `id` (required) - The ID or code name of a project | |
| 12 | ++ `ref_name` (optional) - branch/tag name | |
| 13 | ++ `page` (optional) | |
| 14 | ++ `per_page` (optional) | |
| 15 | + | |
| 16 | + | |
| 17 | +```json | |
| 18 | + | |
| 19 | +[ | |
| 20 | + { | |
| 21 | + "id": "ed899a2f4b50b4370feeea94676502b42383c746", | |
| 22 | + "short_id": "ed899a2f4b5", | |
| 23 | + "title": "Replace sanitize with escape once", | |
| 24 | + "author_name": "Dmitriy Zaporozhets", | |
| 25 | + "author_email": "dzaporozhets@sphereconsultinginc.com", | |
| 26 | + "created_at": "2012-09-20T11:50:22+03:00" | |
| 27 | + }, | |
| 28 | + { | |
| 29 | + "id": "6104942438c14ec7bd21c6cd5bd995272b3faff6", | |
| 30 | + "short_id": "6104942438c", | |
| 31 | + "title": "Sanitize for network graph", | |
| 32 | + "author_name": "randx", | |
| 33 | + "author_email": "dmitriy.zaporozhets@gmail.com", | |
| 34 | + "created_at": "2012-09-20T09:06:12+03:00" | |
| 35 | + } | |
| 36 | +] | |
| 37 | + | |
| 38 | +``` | ... | ... |
lib/api.rb
| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | +module Gitlab | |
| 2 | + # Commits API | |
| 3 | + class Commits < Grape::API | |
| 4 | + before { authenticate! } | |
| 5 | + | |
| 6 | + resource :projects do | |
| 7 | + # Get a list of project commits | |
| 8 | + # | |
| 9 | + # Parameters: | |
| 10 | + # id (required) - The ID or code name of a project | |
| 11 | + # ref_name (optional) - Name of branch or tag | |
| 12 | + # page (optional) - default is 0 | |
| 13 | + # per_page (optional) - default is 20 | |
| 14 | + # Example Request: | |
| 15 | + # GET /projects/:id/commits | |
| 16 | + get ":id/commits" do | |
| 17 | + authorize! :download_code, user_project | |
| 18 | + | |
| 19 | + page = params[:page] || 0 | |
| 20 | + per_page = params[:per_page] || 20 | |
| 21 | + ref = params[:ref_name] || user_project.try(:default_branch) || 'master' | |
| 22 | + | |
| 23 | + commits = user_project.commits(ref, nil, per_page, page * per_page) | |
| 24 | + | |
| 25 | + present CommitDecorator.decorate(commits), with: Entities::Commit | |
| 26 | + end | |
| 27 | + end | |
| 28 | + end | |
| 29 | +end | ... | ... |
lib/api/entities.rb
| ... | ... | @@ -17,6 +17,11 @@ module Gitlab |
| 17 | 17 | expose :id, :url |
| 18 | 18 | end |
| 19 | 19 | |
| 20 | + class Commit < Grape::Entity | |
| 21 | + expose :id, :short_id, :title, | |
| 22 | + :author_name, :author_email, :created_at | |
| 23 | + end | |
| 24 | + | |
| 20 | 25 | class Project < Grape::Entity |
| 21 | 26 | expose :id, :code, :name, :description, :path, :default_branch |
| 22 | 27 | expose :owner, using: Entities::UserBasic | ... | ... |
lib/api/helpers.rb
lib/api/milestones.rb
| ... | ... | @@ -11,6 +11,8 @@ module Gitlab |
| 11 | 11 | # Example Request: |
| 12 | 12 | # GET /projects/:id/milestones |
| 13 | 13 | get ":id/milestones" do |
| 14 | + authorize! :read_milestone, user_project | |
| 15 | + | |
| 14 | 16 | present paginate(user_project.milestones), with: Entities::Milestone |
| 15 | 17 | end |
| 16 | 18 | |
| ... | ... | @@ -22,6 +24,8 @@ module Gitlab |
| 22 | 24 | # Example Request: |
| 23 | 25 | # GET /projects/:id/milestones/:milestone_id |
| 24 | 26 | get ":id/milestones/:milestone_id" do |
| 27 | + authorize! :read_milestone, user_project | |
| 28 | + | |
| 25 | 29 | @milestone = user_project.milestones.find(params[:milestone_id]) |
| 26 | 30 | present @milestone, with: Entities::Milestone |
| 27 | 31 | end |
| ... | ... | @@ -36,6 +40,8 @@ module Gitlab |
| 36 | 40 | # Example Request: |
| 37 | 41 | # POST /projects/:id/milestones |
| 38 | 42 | post ":id/milestones" do |
| 43 | + authorize! :admin_milestone, user_project | |
| 44 | + | |
| 39 | 45 | attrs = attributes_for_keys [:title, :description, :due_date] |
| 40 | 46 | @milestone = user_project.milestones.new attrs |
| 41 | 47 | if @milestone.save | ... | ... |
lib/api/projects.rb
| ... | ... | @@ -40,14 +40,14 @@ module Gitlab |
| 40 | 40 | post do |
| 41 | 41 | params[:code] ||= params[:name] |
| 42 | 42 | params[:path] ||= params[:name] |
| 43 | - attrs = attributes_for_keys [:code, | |
| 44 | - :path, | |
| 45 | - :name, | |
| 46 | - :description, | |
| 47 | - :default_branch, | |
| 48 | - :issues_enabled, | |
| 49 | - :wall_enabled, | |
| 50 | - :merge_requests_enabled, | |
| 43 | + attrs = attributes_for_keys [:code, | |
| 44 | + :path, | |
| 45 | + :name, | |
| 46 | + :description, | |
| 47 | + :default_branch, | |
| 48 | + :issues_enabled, | |
| 49 | + :wall_enabled, | |
| 50 | + :merge_requests_enabled, | |
| 51 | 51 | :wiki_enabled] |
| 52 | 52 | @project = Project.create_by_user(attrs, current_user) |
| 53 | 53 | if @project.saved? |
| ... | ... | @@ -207,6 +207,8 @@ module Gitlab |
| 207 | 207 | # Example Request: |
| 208 | 208 | # POST /projects/:id/snippets |
| 209 | 209 | post ":id/snippets" do |
| 210 | + authorize! :write_snippet, user_project | |
| 211 | + | |
| 210 | 212 | attrs = attributes_for_keys [:title, :file_name] |
| 211 | 213 | attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? |
| 212 | 214 | attrs[:content] = params[:code] if params[:code].present? |
| ... | ... | @@ -282,6 +284,8 @@ module Gitlab |
| 282 | 284 | # Example Request: |
| 283 | 285 | # GET /projects/:id/repository/commits/:sha/blob |
| 284 | 286 | get ":id/repository/commits/:sha/blob" do |
| 287 | + authorize! :download_code, user_project | |
| 288 | + | |
| 285 | 289 | ref = params[:sha] |
| 286 | 290 | |
| 287 | 291 | commit = user_project.commit ref | ... | ... |
| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | +require 'spec_helper' | |
| 2 | + | |
| 3 | +describe Gitlab::API do | |
| 4 | + include ApiHelpers | |
| 5 | + | |
| 6 | + let(:user) { Factory :user } | |
| 7 | + let!(:project) { Factory :project, owner: user } | |
| 8 | + | |
| 9 | + describe "GET /projects/:id/commits" do | |
| 10 | + context "authorized user" do | |
| 11 | + before { project.add_access(user, :read) } | |
| 12 | + | |
| 13 | + it "should return project commits" do | |
| 14 | + get api("/projects/#{project.code}/commits", user) | |
| 15 | + response.status.should == 200 | |
| 16 | + | |
| 17 | + json_response.should be_an Array | |
| 18 | + json_response.first['id'].should == project.commit.id | |
| 19 | + end | |
| 20 | + end | |
| 21 | + | |
| 22 | + context "unauthorized user" do | |
| 23 | + it "should return project commits" do | |
| 24 | + get api("/projects/#{project.code}/commits") | |
| 25 | + response.status.should == 401 | |
| 26 | + end | |
| 27 | + end | |
| 28 | + end | |
| 29 | +end | ... | ... |