commit
a7055be1fd
31 changed files with 1138 additions and 291 deletions
13
lib/api.rb
13
lib/api.rb
|
@ -8,6 +8,19 @@ module Gitlab
|
|||
rack_response({'message' => '404 Not found'}.to_json, 404)
|
||||
end
|
||||
|
||||
rescue_from :all do |exception|
|
||||
# lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60
|
||||
# why is this not wrapped in something reusable?
|
||||
trace = exception.backtrace
|
||||
|
||||
message = "\n#{exception.class} (#{exception.message}):\n"
|
||||
message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
|
||||
message << " " << trace.join("\n ")
|
||||
|
||||
API.logger.add Logger::FATAL, message
|
||||
rack_response({'message' => '500 Internal Server Error'}, 500)
|
||||
end
|
||||
|
||||
format :json
|
||||
helpers APIHelpers
|
||||
|
||||
|
|
|
@ -20,12 +20,14 @@ module Gitlab
|
|||
# Create group. Available only for admin
|
||||
#
|
||||
# Parameters:
|
||||
# name (required) - Name
|
||||
# path (required) - Path
|
||||
# name (required) - The name of the group
|
||||
# path (required) - The path of the group
|
||||
# Example Request:
|
||||
# POST /groups
|
||||
post do
|
||||
authenticated_as_admin!
|
||||
required_attributes! [:name, :path]
|
||||
|
||||
attrs = attributes_for_keys [:name, :path]
|
||||
@group = Group.new(attrs)
|
||||
@group.owner = current_user
|
||||
|
|
|
@ -41,6 +41,17 @@ module Gitlab
|
|||
abilities.allowed?(object, action, subject)
|
||||
end
|
||||
|
||||
# Checks the occurrences of required attributes, each attribute must be present in the params hash
|
||||
# or a Bad Request error is invoked.
|
||||
#
|
||||
# Parameters:
|
||||
# keys (required) - A hash consisting of keys that must be present
|
||||
def required_attributes!(keys)
|
||||
keys.each do |key|
|
||||
bad_request!(key) unless params[key].present?
|
||||
end
|
||||
end
|
||||
|
||||
def attributes_for_keys(keys)
|
||||
attrs = {}
|
||||
keys.each do |key|
|
||||
|
@ -55,6 +66,12 @@ module Gitlab
|
|||
render_api_error!('403 Forbidden', 403)
|
||||
end
|
||||
|
||||
def bad_request!(attribute)
|
||||
message = ["400 (Bad request)"]
|
||||
message << "\"" + attribute.to_s + "\" not given"
|
||||
render_api_error!(message.join(' '), 400)
|
||||
end
|
||||
|
||||
def not_found!(resource = nil)
|
||||
message = ["404"]
|
||||
message << resource if resource
|
||||
|
|
|
@ -48,6 +48,7 @@ module Gitlab
|
|||
# Example Request:
|
||||
# POST /projects/:id/issues
|
||||
post ":id/issues" do
|
||||
required_attributes! [:title]
|
||||
attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id]
|
||||
attrs[:label_list] = params[:labels] if params[:labels].present?
|
||||
@issue = user_project.issues.new attrs
|
||||
|
|
|
@ -4,6 +4,16 @@ module Gitlab
|
|||
before { authenticate! }
|
||||
|
||||
resource :projects do
|
||||
helpers do
|
||||
def handle_merge_request_errors!(errors)
|
||||
if errors[:project_access].any?
|
||||
error!(errors[:project_access], 422)
|
||||
elsif errors[:branch_conflict].any?
|
||||
error!(errors[:branch_conflict], 422)
|
||||
end
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
# List merge requests
|
||||
#
|
||||
|
@ -51,6 +61,7 @@ module Gitlab
|
|||
#
|
||||
post ":id/merge_requests" do
|
||||
authorize! :write_merge_request, user_project
|
||||
required_attributes! [:source_branch, :target_branch, :title]
|
||||
|
||||
attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title]
|
||||
merge_request = user_project.merge_requests.new(attrs)
|
||||
|
@ -60,7 +71,7 @@ module Gitlab
|
|||
merge_request.reload_code
|
||||
present merge_request, with: Entities::MergeRequest
|
||||
else
|
||||
not_found!
|
||||
handle_merge_request_errors! merge_request.errors
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -88,7 +99,7 @@ module Gitlab
|
|||
merge_request.mark_as_unchecked
|
||||
present merge_request, with: Entities::MergeRequest
|
||||
else
|
||||
not_found!
|
||||
handle_merge_request_errors! merge_request.errors
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -102,6 +113,8 @@ module Gitlab
|
|||
# POST /projects/:id/merge_request/:merge_request_id/comments
|
||||
#
|
||||
post ":id/merge_request/:merge_request_id/comments" do
|
||||
required_attributes! [:note]
|
||||
|
||||
merge_request = user_project.merge_requests.find(params[:merge_request_id])
|
||||
note = merge_request.notes.new(note: params[:note], project_id: user_project.id)
|
||||
note.author = current_user
|
||||
|
|
|
@ -41,6 +41,7 @@ module Gitlab
|
|||
# POST /projects/:id/milestones
|
||||
post ":id/milestones" do
|
||||
authorize! :admin_milestone, user_project
|
||||
required_attributes! [:title]
|
||||
|
||||
attrs = attributes_for_keys [:title, :description, :due_date]
|
||||
@milestone = user_project.milestones.new attrs
|
||||
|
|
|
@ -37,12 +37,16 @@ module Gitlab
|
|||
# Example Request:
|
||||
# POST /projects/:id/notes
|
||||
post ":id/notes" do
|
||||
required_attributes! [:body]
|
||||
|
||||
@note = user_project.notes.new(note: params[:body])
|
||||
@note.author = current_user
|
||||
|
||||
if @note.save
|
||||
present @note, with: Entities::Note
|
||||
else
|
||||
# :note is exposed as :body, but :note is set on error
|
||||
bad_request!(:note) if @note.errors[:note].any?
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
@ -89,6 +93,8 @@ module Gitlab
|
|||
# POST /projects/:id/issues/:noteable_id/notes
|
||||
# POST /projects/:id/snippets/:noteable_id/notes
|
||||
post ":id/#{noteables_str}/:#{noteable_id_str}/notes" do
|
||||
required_attributes! [:body]
|
||||
|
||||
@noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"])
|
||||
@note = @noteable.notes.new(note: params[:body])
|
||||
@note.author = current_user
|
||||
|
|
|
@ -4,6 +4,15 @@ module Gitlab
|
|||
before { authenticate! }
|
||||
|
||||
resource :projects do
|
||||
helpers do
|
||||
def handle_project_member_errors(errors)
|
||||
if errors[:project_access].any?
|
||||
error!(errors[:project_access], 422)
|
||||
end
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
# Get a projects list for authenticated user
|
||||
#
|
||||
# Example Request:
|
||||
|
@ -33,9 +42,11 @@ module Gitlab
|
|||
# wall_enabled (optional) - enabled by default
|
||||
# merge_requests_enabled (optional) - enabled by default
|
||||
# wiki_enabled (optional) - enabled by default
|
||||
# namespace_id (optional) - defaults to user namespace
|
||||
# Example Request
|
||||
# POST /projects
|
||||
post do
|
||||
required_attributes! [:name]
|
||||
attrs = attributes_for_keys [:name,
|
||||
:description,
|
||||
:default_branch,
|
||||
|
@ -48,6 +59,9 @@ module Gitlab
|
|||
if @project.saved?
|
||||
present @project, with: Entities::Project
|
||||
else
|
||||
if @project.errors[:limit_reached].present?
|
||||
error!(@project.errors[:limit_reached], 403)
|
||||
end
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
@ -122,16 +136,22 @@ module Gitlab
|
|||
# POST /projects/:id/members
|
||||
post ":id/members" do
|
||||
authorize! :admin_project, user_project
|
||||
users_project = user_project.users_projects.new(
|
||||
user_id: params[:user_id],
|
||||
project_access: params[:access_level]
|
||||
)
|
||||
required_attributes! [:user_id, :access_level]
|
||||
|
||||
if users_project.save
|
||||
@member = users_project.user
|
||||
# either the user is already a team member or a new one
|
||||
team_member = user_project.team_member_by_id(params[:user_id])
|
||||
if team_member.nil?
|
||||
team_member = user_project.users_projects.new(
|
||||
user_id: params[:user_id],
|
||||
project_access: params[:access_level]
|
||||
)
|
||||
end
|
||||
|
||||
if team_member.save
|
||||
@member = team_member.user
|
||||
present @member, with: Entities::ProjectMember, project: user_project
|
||||
else
|
||||
not_found!
|
||||
handle_project_member_errors team_member.errors
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -145,13 +165,16 @@ module Gitlab
|
|||
# PUT /projects/:id/members/:user_id
|
||||
put ":id/members/:user_id" do
|
||||
authorize! :admin_project, user_project
|
||||
users_project = user_project.users_projects.find_by_user_id params[:user_id]
|
||||
required_attributes! [:access_level]
|
||||
|
||||
if users_project.update_attributes(project_access: params[:access_level])
|
||||
@member = users_project.user
|
||||
team_member = user_project.users_projects.find_by_user_id(params[:user_id])
|
||||
not_found!("User can not be found") if team_member.nil?
|
||||
|
||||
if team_member.update_attributes(project_access: params[:access_level])
|
||||
@member = team_member.user
|
||||
present @member, with: Entities::ProjectMember, project: user_project
|
||||
else
|
||||
not_found!
|
||||
handle_project_member_errors team_member.errors
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -164,8 +187,12 @@ module Gitlab
|
|||
# DELETE /projects/:id/members/:user_id
|
||||
delete ":id/members/:user_id" do
|
||||
authorize! :admin_project, user_project
|
||||
users_project = user_project.users_projects.find_by_user_id params[:user_id]
|
||||
users_project.destroy
|
||||
team_member = user_project.users_projects.find_by_user_id(params[:user_id])
|
||||
unless team_member.nil?
|
||||
team_member.destroy
|
||||
else
|
||||
{:message => "Access revoked", :id => params[:user_id].to_i}
|
||||
end
|
||||
end
|
||||
|
||||
# Get project hooks
|
||||
|
@ -203,11 +230,16 @@ module Gitlab
|
|||
# POST /projects/:id/hooks
|
||||
post ":id/hooks" do
|
||||
authorize! :admin_project, user_project
|
||||
required_attributes! [:url]
|
||||
|
||||
@hook = user_project.hooks.new({"url" => params[:url]})
|
||||
if @hook.save
|
||||
present @hook, with: Entities::Hook
|
||||
else
|
||||
error!({'message' => '404 Not found'}, 404)
|
||||
if @hook.errors[:url].present?
|
||||
error!("Invalid url given", 422)
|
||||
end
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -222,27 +254,36 @@ module Gitlab
|
|||
put ":id/hooks/:hook_id" do
|
||||
@hook = user_project.hooks.find(params[:hook_id])
|
||||
authorize! :admin_project, user_project
|
||||
required_attributes! [:url]
|
||||
|
||||
attrs = attributes_for_keys [:url]
|
||||
|
||||
if @hook.update_attributes attrs
|
||||
present @hook, with: Entities::Hook
|
||||
else
|
||||
if @hook.errors[:url].present?
|
||||
error!("Invalid url given", 422)
|
||||
end
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
# Delete project hook
|
||||
# Deletes project hook. This is an idempotent function.
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a project
|
||||
# hook_id (required) - The ID of hook to delete
|
||||
# Example Request:
|
||||
# DELETE /projects/:id/hooks/:hook_id
|
||||
delete ":id/hooks/:hook_id" do
|
||||
delete ":id/hooks" do
|
||||
authorize! :admin_project, user_project
|
||||
@hook = user_project.hooks.find(params[:hook_id])
|
||||
@hook.destroy
|
||||
required_attributes! [:hook_id]
|
||||
|
||||
begin
|
||||
@hook = ProjectHook.find(params[:hook_id])
|
||||
@hook.destroy
|
||||
rescue
|
||||
# ProjectHook can raise Error if hook_id not found
|
||||
end
|
||||
end
|
||||
|
||||
# Get a project repository branches
|
||||
|
@ -277,6 +318,7 @@ module Gitlab
|
|||
# PUT /projects/:id/repository/branches/:branch/protect
|
||||
put ":id/repository/branches/:branch/protect" do
|
||||
@branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
|
||||
not_found! unless @branch
|
||||
protected = user_project.protected_branches.find_by_name(@branch.name)
|
||||
|
||||
unless protected
|
||||
|
@ -295,6 +337,7 @@ module Gitlab
|
|||
# PUT /projects/:id/repository/branches/:branch/unprotect
|
||||
put ":id/repository/branches/:branch/unprotect" do
|
||||
@branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
|
||||
not_found! unless @branch
|
||||
protected = user_project.protected_branches.find_by_name(@branch.name)
|
||||
|
||||
if protected
|
||||
|
@ -318,7 +361,7 @@ module Gitlab
|
|||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a project
|
||||
# ref_name (optional) - The name of a repository branch or tag
|
||||
# ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used
|
||||
# Example Request:
|
||||
# GET /projects/:id/repository/commits
|
||||
get ":id/repository/commits" do
|
||||
|
@ -366,6 +409,7 @@ module Gitlab
|
|||
# POST /projects/:id/snippets
|
||||
post ":id/snippets" do
|
||||
authorize! :write_snippet, user_project
|
||||
required_attributes! [:title, :file_name, :code]
|
||||
|
||||
attrs = attributes_for_keys [:title, :file_name]
|
||||
attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?
|
||||
|
@ -414,10 +458,12 @@ module Gitlab
|
|||
# Example Request:
|
||||
# DELETE /projects/:id/snippets/:snippet_id
|
||||
delete ":id/snippets/:snippet_id" do
|
||||
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||
authorize! :modify_snippet, @snippet
|
||||
|
||||
@snippet.destroy
|
||||
begin
|
||||
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||
authorize! :modify_snippet, user_project
|
||||
@snippet.destroy
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
# Get a raw project snippet
|
||||
|
@ -443,6 +489,7 @@ module Gitlab
|
|||
# GET /projects/:id/repository/commits/:sha/blob
|
||||
get ":id/repository/commits/:sha/blob" do
|
||||
authorize! :download_code, user_project
|
||||
required_attributes! [:filepath]
|
||||
|
||||
ref = params[:sha]
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ module Gitlab
|
|||
# POST /users
|
||||
post do
|
||||
authenticated_as_admin!
|
||||
required_attributes! [:email, :password, :name, :username]
|
||||
|
||||
attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio]
|
||||
user = User.new attrs, as: :admin
|
||||
if user.save
|
||||
|
@ -67,10 +69,12 @@ module Gitlab
|
|||
# PUT /users/:id
|
||||
put ":id" do
|
||||
authenticated_as_admin!
|
||||
attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio]
|
||||
user = User.find_by_id(params[:id])
|
||||
|
||||
if user && user.update_attributes(attrs)
|
||||
attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio]
|
||||
user = User.find(params[:id])
|
||||
not_found!("User not found") unless user
|
||||
|
||||
if user.update_attributes(attrs)
|
||||
present user, with: Entities::User
|
||||
else
|
||||
not_found!
|
||||
|
@ -147,6 +151,8 @@ module Gitlab
|
|||
# Example Request:
|
||||
# POST /user/keys
|
||||
post "keys" do
|
||||
required_attributes! [:title, :key]
|
||||
|
||||
attrs = attributes_for_keys [:title, :key]
|
||||
key = current_user.keys.new attrs
|
||||
if key.save
|
||||
|
@ -156,15 +162,18 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
# Delete existed ssh key of currently authenticated user
|
||||
# Delete existing ssh key of currently authenticated user
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - SSH Key ID
|
||||
# Example Request:
|
||||
# DELETE /user/keys/:id
|
||||
delete "keys/:id" do
|
||||
key = current_user.keys.find params[:id]
|
||||
key.delete
|
||||
begin
|
||||
key = current_user.keys.find params[:id]
|
||||
key.delete
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue