summaryrefslogtreecommitdiff
path: root/lib/api
diff options
context:
space:
mode:
Diffstat (limited to 'lib/api')
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/deploy_keys.rb10
-rw-r--r--lib/api/entities.rb25
-rw-r--r--lib/api/groups.rb17
-rw-r--r--lib/api/helpers.rb24
-rw-r--r--lib/api/internal.rb1
-rw-r--r--lib/api/issues.rb39
-rw-r--r--lib/api/merge_requests.rb79
-rw-r--r--lib/api/milestones.rb34
-rw-r--r--lib/api/notes.rb40
-rw-r--r--lib/api/projects.rb12
-rw-r--r--lib/api/repositories.rb30
-rw-r--r--lib/api/services.rb44
13 files changed, 234 insertions, 122 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb
index c4c9f166db1..4db81f42b4c 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -38,5 +38,6 @@ module API
mount ProjectSnippets
mount DeployKeys
mount ProjectHooks
+ mount Services
end
end
diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb
index 218b3d8eee2..b5997608997 100644
--- a/lib/api/deploy_keys.rb
+++ b/lib/api/deploy_keys.rb
@@ -5,16 +5,6 @@ module API
before { authorize_admin_project }
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 specific project's keys
#
# Example Request:
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index ab949f530ab..429083d75be 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -91,15 +91,16 @@ module API
expose :expires_at, :updated_at, :created_at
end
- class Milestone < Grape::Entity
- expose :id
- expose (:project_id) {|milestone| milestone.project.id}
+ class ProjectEntity < Grape::Entity
+ expose :id, :iid
+ expose (:project_id) { |entity| entity.project.id }
+ end
+
+ class Milestone < ProjectEntity
expose :title, :description, :due_date, :state, :updated_at, :created_at
end
- class Issue < Grape::Entity
- expose :id
- expose (:project_id) {|issue| issue.project.id}
+ class Issue < ProjectEntity
expose :title, :description
expose :label_list, as: :labels
expose :milestone, using: Entities::Milestone
@@ -107,14 +108,14 @@ module API
expose :state, :updated_at, :created_at
end
- class SSHKey < Grape::Entity
- expose :id, :title, :key, :created_at
+ class MergeRequest < ProjectEntity
+ expose :target_branch, :source_branch, :title, :state, :upvotes, :downvotes
+ expose :author, :assignee, using: Entities::UserBasic
+ expose :source_project_id, :target_project_id
end
- class MergeRequest < Grape::Entity
- expose :id, :target_branch, :source_branch, :title, :state
- expose :target_project_id, as: :project_id
- expose :author, :assignee, using: Entities::UserBasic
+ class SSHKey < Grape::Entity
+ expose :id, :title, :key, :created_at
end
class Note < Grape::Entity
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index 396554404af..290b78d8017 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -7,12 +7,14 @@ module API
helpers do
def find_group(id)
group = Group.find(id)
- if current_user.admin or current_user.groups.include? group
+
+ if can?(current_user, :read_group, group)
group
else
render_api_error!("403 Forbidden - #{current_user.username} lacks sufficient access to #{group.name}", 403)
end
end
+
def validate_access_level?(level)
Gitlab::Access.options_with_owner.values.include? level.to_i
end
@@ -64,6 +66,18 @@ module API
present group, with: Entities::GroupDetail
end
+ # Remove group
+ #
+ # Parameters:
+ # id (required) - The ID of a group
+ # Example Request:
+ # DELETE /groups/:id
+ delete ":id" do
+ group = find_group(params[:id])
+ authorize! :manage_group, group
+ group.destroy
+ end
+
# Transfer a project to the Group namespace
#
# Parameters:
@@ -132,7 +146,6 @@ module API
member.destroy
end
end
-
end
end
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 2b0c672c7fa..b0f8d5a6da9 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -6,23 +6,23 @@ module API
SUDO_PARAM = :sudo
def current_user
- @current_user ||= User.find_by_authentication_token(params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER])
+ private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s
+ @current_user ||= User.find_by_authentication_token(private_token)
identifier = sudo_identifier()
+
# If the sudo is the current user do nothing
if (identifier && !(@current_user.id == identifier || @current_user.username == identifier))
render_api_error!('403 Forbidden: Must be admin to use sudo', 403) unless @current_user.is_admin?
- begin
- @current_user = User.by_username_or_id(identifier)
- rescue => ex
- not_found!("No user id or username for: #{identifier}")
- end
- not_found!("No user id or username for: #{identifier}") if current_user.nil?
+ @current_user = User.by_username_or_id(identifier)
+ not_found!("No user id or username for: #{identifier}") if @current_user.nil?
end
+
@current_user
end
def sudo_identifier()
identifier ||= params[SUDO_PARAM] ||= env[SUDO_HEADER]
+
# Regex for integers
if (!!(identifier =~ /^[0-9]+$/))
identifier.to_i
@@ -31,6 +31,16 @@ module API
end
end
+ def set_current_user_for_thread
+ Thread.current[:current_user] = current_user
+
+ begin
+ yield
+ ensure
+ Thread.current[:current_user] = nil
+ end
+ end
+
def user_project
@project ||= find_project(params[:id])
@project || not_found!
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index 79f8eb3a543..ed6b50c3a6a 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -35,6 +35,7 @@ module API
user = key.user
return false if user.blocked?
+ return false if user.ldap_user? && Gitlab::LDAP::User.blocked?(user.extern_uid)
action = case git_cmd
when *DOWNLOAD_COMMANDS
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index a15203d1563..3d15c35b8cc 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -2,7 +2,6 @@ module API
# Issues API
class Issues < Grape::API
before { authenticate! }
- before { Thread.current[:current_user] = current_user }
resource :issues do
# Get currently authenticated user's issues
@@ -49,15 +48,17 @@ module API
# 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
- @issue.author = current_user
- if @issue.save
- present @issue, with: Entities::Issue
- else
- not_found!
+ set_current_user_for_thread 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
+ @issue.author = current_user
+ if @issue.save
+ present @issue, with: Entities::Issue
+ else
+ not_found!
+ end
end
end
@@ -75,16 +76,18 @@ module API
# Example Request:
# PUT /projects/:id/issues/:issue_id
put ":id/issues/:issue_id" do
- @issue = user_project.issues.find(params[:issue_id])
- authorize! :modify_issue, @issue
+ set_current_user_for_thread do
+ @issue = user_project.issues.find(params[:issue_id])
+ authorize! :modify_issue, @issue
- attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event]
- attrs[:label_list] = params[:labels] if params[:labels].present?
+ attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event]
+ attrs[:label_list] = params[:labels] if params[:labels].present?
- if @issue.update_attributes attrs
- present @issue, with: Entities::Issue
- else
- not_found!
+ if @issue.update_attributes attrs
+ present @issue, with: Entities::Issue
+ else
+ not_found!
+ end
end
end
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index d690f1d07e7..3f4bec895bf 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -2,7 +2,6 @@ module API
# MergeRequest API
class MergeRequests < Grape::API
before { authenticate! }
- before { Thread.current[:current_user] = current_user }
resource :projects do
helpers do
@@ -70,28 +69,30 @@ module API
# POST /projects/:id/merge_requests
#
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, :target_project_id]
- merge_request = user_project.merge_requests.new(attrs)
- merge_request.author = current_user
- merge_request.source_project = user_project
- target_project_id = attrs[:target_project_id]
- if not_fork?(target_project_id, user_project)
- merge_request.target_project = user_project
- else
- if target_matches_fork(target_project_id,user_project)
- merge_request.target_project = Project.find_by_id(attrs[:target_project_id])
+ set_current_user_for_thread 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, :target_project_id]
+ merge_request = user_project.merge_requests.new(attrs)
+ merge_request.author = current_user
+ merge_request.source_project = user_project
+ target_project_id = attrs[:target_project_id]
+ if not_fork?(target_project_id, user_project)
+ merge_request.target_project = user_project
else
- render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400)
+ if target_matches_fork(target_project_id,user_project)
+ merge_request.target_project = Project.find_by_id(attrs[:target_project_id])
+ else
+ render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400)
+ end
end
- end
- if merge_request.save
- merge_request.reload_code
- present merge_request, with: Entities::MergeRequest
- else
- handle_merge_request_errors! merge_request.errors
+ if merge_request.save
+ merge_request.reload_code
+ present merge_request, with: Entities::MergeRequest
+ else
+ handle_merge_request_errors! merge_request.errors
+ end
end
end
@@ -109,17 +110,19 @@ module API
# PUT /projects/:id/merge_request/:merge_request_id
#
put ":id/merge_request/:merge_request_id" do
- attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event]
- merge_request = user_project.merge_requests.find(params[:merge_request_id])
+ set_current_user_for_thread do
+ attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event]
+ merge_request = user_project.merge_requests.find(params[:merge_request_id])
- authorize! :modify_merge_request, merge_request
+ authorize! :modify_merge_request, merge_request
- if merge_request.update_attributes attrs
- merge_request.reload_code
- merge_request.mark_as_unchecked
- present merge_request, with: Entities::MergeRequest
- else
- handle_merge_request_errors! merge_request.errors
+ if merge_request.update_attributes attrs
+ merge_request.reload_code
+ merge_request.mark_as_unchecked
+ present merge_request, with: Entities::MergeRequest
+ else
+ handle_merge_request_errors! merge_request.errors
+ end
end
end
@@ -133,16 +136,18 @@ module API
# POST /projects/:id/merge_request/:merge_request_id/comments
#
post ":id/merge_request/:merge_request_id/comments" do
- required_attributes! [:note]
+ set_current_user_for_thread 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
+ 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
- if note.save
- present note, with: Entities::MRNote
- else
- not_found!
+ if note.save
+ present note, with: Entities::MRNote
+ else
+ not_found!
+ end
end
end
diff --git a/lib/api/milestones.rb b/lib/api/milestones.rb
index aee12e7dc40..f7e63b23093 100644
--- a/lib/api/milestones.rb
+++ b/lib/api/milestones.rb
@@ -40,15 +40,17 @@ module API
# Example Request:
# POST /projects/:id/milestones
post ":id/milestones" do
- authorize! :admin_milestone, user_project
- required_attributes! [:title]
+ set_current_user_for_thread do
+ authorize! :admin_milestone, user_project
+ required_attributes! [:title]
- attrs = attributes_for_keys [:title, :description, :due_date]
- @milestone = user_project.milestones.new attrs
- if @milestone.save
- present @milestone, with: Entities::Milestone
- else
- not_found!
+ attrs = attributes_for_keys [:title, :description, :due_date]
+ @milestone = user_project.milestones.new attrs
+ if @milestone.save
+ present @milestone, with: Entities::Milestone
+ else
+ not_found!
+ end
end
end
@@ -64,14 +66,16 @@ module API
# Example Request:
# PUT /projects/:id/milestones/:milestone_id
put ":id/milestones/:milestone_id" do
- authorize! :admin_milestone, user_project
+ set_current_user_for_thread do
+ authorize! :admin_milestone, user_project
- @milestone = user_project.milestones.find(params[:milestone_id])
- attrs = attributes_for_keys [:title, :description, :due_date, :state_event]
- if @milestone.update_attributes attrs
- present @milestone, with: Entities::Milestone
- else
- not_found!
+ @milestone = user_project.milestones.find(params[:milestone_id])
+ attrs = attributes_for_keys [:title, :description, :due_date, :state_event]
+ if @milestone.update_attributes attrs
+ present @milestone, with: Entities::Milestone
+ else
+ not_found!
+ end
end
end
end
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index cb2bc764476..f21907b1ffc 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -41,17 +41,19 @@ module API
# Example Request:
# POST /projects/:id/notes
post ":id/notes" do
- required_attributes! [:body]
+ set_current_user_for_thread do
+ required_attributes! [:body]
- @note = user_project.notes.new(note: params[:body])
- @note.author = current_user
+ @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!
+ 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
end
@@ -97,17 +99,19 @@ module API
# 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]
+ set_current_user_for_thread 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
- @note.project = user_project
+ @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"])
+ @note = @noteable.notes.new(note: params[:body])
+ @note.author = current_user
+ @note.project = user_project
- if @note.save
- present @note, with: Entities::Note
- else
- not_found!
+ if @note.save
+ present @note, with: Entities::Note
+ else
+ not_found!
+ end
end
end
end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index cf357b23c40..42560572046 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -60,7 +60,6 @@ module API
# Parameters:
# name (required) - name for new project
# description (optional) - short project description
- # default_branch (optional) - 'master' by default
# issues_enabled (optional)
# wall_enabled (optional)
# merge_requests_enabled (optional)
@@ -75,7 +74,6 @@ module API
attrs = attributes_for_keys [:name,
:path,
:description,
- :default_branch,
:issues_enabled,
:wall_enabled,
:merge_requests_enabled,
@@ -129,6 +127,16 @@ module API
end
end
+ # Remove project
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # Example Request:
+ # DELETE /projects/:id
+ delete ":id" do
+ authorize! :remove_project, user_project
+ user_project.destroy
+ end
# Mark this project as forked from another
#
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index 1a911eae2bb..c9422fdb165 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -144,7 +144,7 @@ module API
trees = []
%w(trees blobs submodules).each do |type|
- trees += tree.send(type).map { |t| { name: t.name, type: type.singularize, mode: t.mode, id: t.id } }
+ trees += tree.send(type).map { |t| {name: t.name, type: type.singularize, mode: t.mode, id: t.id} }
end
trees
@@ -176,6 +176,34 @@ module API
content_type blob.mime_type
present blob.data
end
+
+ # Get a an archive of the repository
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # sha (optional) - the commit sha to download defaults to the tip of the default branch
+ # Example Request:
+ # GET /projects/:id/repository/archive
+ get ":id/repository/archive" do
+ authorize! :download_code, user_project
+ repo = user_project.repository
+ ref = params[:sha]
+ storage_path = Rails.root.join("tmp", "repositories")
+
+ file_path = repo.archive_repo(ref, storage_path)
+ if file_path && File.exists?(file_path)
+ data = File.open(file_path, 'rb').read
+
+ header "Content-Disposition:", " infile; filename=\"#{File.basename(file_path)}\""
+ content_type 'application/x-gzip'
+
+ env['api.format'] = :binary
+
+ present data
+ else
+ not_found!
+ end
+ end
end
end
end
diff --git a/lib/api/services.rb b/lib/api/services.rb
new file mode 100644
index 00000000000..bde502e32e1
--- /dev/null
+++ b/lib/api/services.rb
@@ -0,0 +1,44 @@
+module API
+ # Projects API
+ class Services < Grape::API
+ before { authenticate! }
+ before { authorize_admin_project }
+
+ resource :projects do
+ # Set GitLab CI service for project
+ #
+ # Parameters:
+ # token (required) - CI project token
+ # project_url (required) - CI project url
+ #
+ # Example Request:
+ # PUT /projects/:id/services/gitlab-ci
+ put ":id/services/gitlab-ci" do
+ required_attributes! [:token, :project_url]
+ attrs = attributes_for_keys [:token, :project_url]
+ user_project.build_missing_services
+
+ if user_project.gitlab_ci_service.update_attributes(attrs.merge(active: true))
+ true
+ else
+ not_found!
+ end
+ end
+
+ # Delete GitLab CI service settings
+ #
+ # Example Request:
+ # DELETE /projects/:id/keys/:id
+ delete ":id/services/gitlab-ci" do
+ if user_project.gitlab_ci_service
+ user_project.gitlab_ci_service.update_attributes(
+ active: false,
+ token: nil,
+ project_url: nil
+ )
+ end
+ end
+ end
+ end
+end
+