summaryrefslogtreecommitdiff
path: root/lib/api
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2016-12-12 17:44:56 +0000
committerFilipa Lacerda <filipa@gitlab.com>2016-12-12 17:52:06 +0000
commiteb839b9af51d411a6a35786a1c1c58954da1a650 (patch)
tree88a8ff1084be1a7bacf2b1557e04c5aa48434b6f /lib/api
parentce867db6b8b1b317ebe864d36d50fde5aad787d4 (diff)
parent3445136b9b0b8367b151170509fabe613389a50d (diff)
downloadgitlab-ce-eb839b9af51d411a6a35786a1c1c58954da1a650.tar.gz
Merge CSS
Diffstat (limited to 'lib/api')
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/branches.rb16
-rw-r--r--lib/api/entities.rb19
-rw-r--r--lib/api/groups.rb11
-rw-r--r--lib/api/helpers.rb31
-rw-r--r--lib/api/issues.rb262
-rw-r--r--lib/api/merge_requests.rb8
-rw-r--r--lib/api/session.rb4
-rw-r--r--lib/api/snippets.rb137
-rw-r--r--lib/api/tags.rb1
-rw-r--r--lib/api/users.rb16
11 files changed, 315 insertions, 191 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 67109ceeef9..cec2702e44d 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -64,6 +64,7 @@ module API
mount ::API::Session
mount ::API::Settings
mount ::API::SidekiqMetrics
+ mount ::API::Snippets
mount ::API::Subscriptions
mount ::API::SystemHooks
mount ::API::Tags
diff --git a/lib/api/branches.rb b/lib/api/branches.rb
index 73aed624ea7..0950c3d2e88 100644
--- a/lib/api/branches.rb
+++ b/lib/api/branches.rb
@@ -23,9 +23,9 @@ module API
success Entities::RepoBranch
end
params do
- requires :branch, type: String, regexp: /.+/, desc: 'The name of the branch'
+ requires :branch, type: String, desc: 'The name of the branch'
end
- get ':id/repository/branches/:branch' do
+ get ':id/repository/branches/:branch', requirements: { branch: /.+/ } do
branch = user_project.repository.find_branch(params[:branch])
not_found!("Branch") unless branch
@@ -39,11 +39,11 @@ module API
success Entities::RepoBranch
end
params do
- requires :branch, type: String, regexp: /.+/, desc: 'The name of the branch'
+ requires :branch, type: String, desc: 'The name of the branch'
optional :developers_can_push, type: Boolean, desc: 'Flag if developers can push to that branch'
optional :developers_can_merge, type: Boolean, desc: 'Flag if developers can merge to that branch'
end
- put ':id/repository/branches/:branch/protect' do
+ put ':id/repository/branches/:branch/protect', requirements: { branch: /.+/ } do
authorize_admin_project
branch = user_project.repository.find_branch(params[:branch])
@@ -76,9 +76,9 @@ module API
success Entities::RepoBranch
end
params do
- requires :branch, type: String, regexp: /.+/, desc: 'The name of the branch'
+ requires :branch, type: String, desc: 'The name of the branch'
end
- put ':id/repository/branches/:branch/unprotect' do
+ put ':id/repository/branches/:branch/unprotect', requirements: { branch: /.+/ } do
authorize_admin_project
branch = user_project.repository.find_branch(params[:branch])
@@ -112,9 +112,9 @@ module API
desc 'Delete a branch'
params do
- requires :branch, type: String, regexp: /.+/, desc: 'The name of the branch'
+ requires :branch, type: String, desc: 'The name of the branch'
end
- delete ":id/repository/branches/:branch" do
+ delete ":id/repository/branches/:branch", requirements: { branch: /.+/ } do
authorize_push_project
result = DeleteBranchService.new(user_project, current_user).
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 66ef4792222..bb8d740532d 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -22,7 +22,7 @@ module API
expose :provider, :extern_uid
end
- class UserFull < User
+ class UserPublic < User
expose :last_sign_in_at
expose :confirmed_at
expose :email
@@ -34,7 +34,7 @@ module API
expose :external
end
- class UserLogin < UserFull
+ class UserWithPrivateToken < UserPublic
expose :private_token
end
@@ -201,6 +201,19 @@ module API
end
end
+ class PersonalSnippet < Grape::Entity
+ expose :id, :title, :file_name
+ expose :author, using: Entities::UserBasic
+ expose :updated_at, :created_at
+
+ expose :web_url do |snippet|
+ Gitlab::UrlBuilder.build(snippet)
+ end
+ expose :raw_url do |snippet|
+ Gitlab::UrlBuilder.build(snippet) + "/raw"
+ end
+ end
+
class ProjectEntity < Grape::Entity
expose :id, :iid
expose(:project_id) { |entity| entity.project.id }
@@ -289,7 +302,7 @@ module API
end
class SSHKeyWithUser < SSHKey
- expose :user, using: Entities::UserFull
+ expose :user, using: Entities::UserPublic
end
class Note < Grape::Entity
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index fbf7513302b..105d3ee342e 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -1,7 +1,7 @@
module API
class Groups < Grape::API
include PaginationParams
-
+
before { authenticate! }
helpers do
@@ -117,11 +117,20 @@ module API
success Entities::Project
end
params do
+ optional :archived, type: Boolean, default: false, desc: 'Limit by archived status'
+ optional :visibility, type: String, values: %w[public internal private],
+ desc: 'Limit by visibility'
+ optional :search, type: String, desc: 'Return list of authorized projects matching the search criteria'
+ optional :order_by, type: String, values: %w[id name path created_at updated_at last_activity_at],
+ default: 'created_at', desc: 'Return projects ordered by field'
+ optional :sort, type: String, values: %w[asc desc], default: 'desc',
+ desc: 'Return projects sorted in ascending and descending order'
use :pagination
end
get ":id/projects" do
group = find_group!(params[:id])
projects = GroupProjectsFinder.new(group).execute(current_user)
+ projects = filter_projects(projects)
present paginate(projects), with: Entities::Project, user: current_user
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 7f94ede7940..8b0f8deadfa 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -44,11 +44,14 @@ module API
return nil
end
- identifier = sudo_identifier()
+ identifier = sudo_identifier
- # If the sudo is the current user do nothing
- if identifier && !(@current_user.id == identifier || @current_user.username == identifier)
+ if identifier
+ # We check for private_token because we cannot allow PAT to be used
forbidden!('Must be admin to use sudo') unless @current_user.is_admin?
+ forbidden!('Private token must be specified in order to use sudo') unless private_token_used?
+
+ @impersonator = @current_user
@current_user = User.by_username_or_id(identifier)
not_found!("No user id or username for: #{identifier}") if @current_user.nil?
end
@@ -108,7 +111,7 @@ module API
if id =~ /^\d+$/
Group.find_by(id: id)
else
- Group.find_by(path: id)
+ Group.find_by_full_path(id)
end
end
@@ -217,22 +220,6 @@ module API
end
end
- def issuable_order_by
- if params["order_by"] == 'updated_at'
- 'updated_at'
- else
- 'created_at'
- end
- end
-
- def issuable_sort
- if params["sort"] == 'asc'
- :asc
- else
- :desc
- end
- end
-
def filter_by_iid(items, iid)
items.where(iid: iid)
end
@@ -399,6 +386,10 @@ module API
links.join(', ')
end
+ def private_token_used?
+ private_token == @current_user.private_token
+ end
+
def secret_token
Gitlab::Shell.secret_token
end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 049b4fb214c..c9124649cbb 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -1,6 +1,7 @@
module API
- # Issues API
class Issues < Grape::API
+ include PaginationParams
+
before { authenticate! }
helpers do
@@ -20,77 +21,68 @@ module API
issues.includes(:milestone).where('milestones.title' => milestone)
end
- def issue_params
- new_params = declared(params, include_parent_namespace: false, include_missing: false).to_h
- new_params = new_params.with_indifferent_access
- new_params.delete(:id)
- new_params.delete(:issue_id)
+ params :issues_params do
+ optional :labels, type: String, desc: 'Comma-separated list of label names'
+ optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at',
+ desc: 'Return issues ordered by `created_at` or `updated_at` fields.'
+ optional :sort, type: String, values: %w[asc desc], default: 'desc',
+ desc: 'Return issues sorted in `asc` or `desc` order.'
+ use :pagination
+ end
- new_params
+ params :issue_params do
+ optional :description, type: String, desc: 'The description of an issue'
+ optional :assignee_id, type: Integer, desc: 'The ID of a user to assign issue'
+ optional :milestone_id, type: Integer, desc: 'The ID of a milestone to assign issue'
+ optional :labels, type: String, desc: 'Comma-separated list of label names'
+ optional :due_date, type: String, desc: 'Date time string in the format YEAR-MONTH-DAY'
+ optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential'
+ optional :state_event, type: String, values: %w[open close],
+ desc: 'State of the issue'
end
end
resource :issues do
- # Get currently authenticated user's issues
- #
- # Parameters:
- # state (optional) - Return "opened" or "closed" issues
- # labels (optional) - Comma-separated list of label names
- # order_by (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at`
- # sort (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
- #
- # Example Requests:
- # GET /issues
- # GET /issues?state=opened
- # GET /issues?state=closed
- # GET /issues?labels=foo
- # GET /issues?labels=foo,bar
- # GET /issues?labels=foo,bar&state=opened
+ desc "Get currently authenticated user's issues" do
+ success Entities::Issue
+ end
+ params do
+ optional :state, type: String, values: %w[opened closed all], default: 'all',
+ desc: 'Return opened, closed, or all issues'
+ use :issues_params
+ end
get do
issues = current_user.issues.inc_notes_with_associations
- issues = filter_issues_state(issues, params[:state]) unless params[:state].nil?
+ issues = filter_issues_state(issues, params[:state])
issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil?
- issues = issues.reorder(issuable_order_by => issuable_sort)
+ issues = issues.reorder(params[:order_by] => params[:sort])
present paginate(issues), with: Entities::Issue, current_user: current_user
end
end
+ params do
+ requires :id, type: String, desc: 'The ID of a group'
+ end
resource :groups do
- # Get a list of group issues
- #
- # Parameters:
- # id (required) - The ID of a group
- # state (optional) - Return "opened" or "closed" issues
- # labels (optional) - Comma-separated list of label names
- # milestone (optional) - Milestone title
- # order_by (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at`
- # sort (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
- #
- # Example Requests:
- # GET /groups/:id/issues
- # GET /groups/:id/issues?state=opened
- # GET /groups/:id/issues?state=closed
- # GET /groups/:id/issues?labels=foo
- # GET /groups/:id/issues?labels=foo,bar
- # GET /groups/:id/issues?labels=foo,bar&state=opened
- # GET /groups/:id/issues?milestone=1.0.0
- # GET /groups/:id/issues?milestone=1.0.0&state=closed
+ desc 'Get a list of group issues' do
+ success Entities::Issue
+ end
+ params do
+ optional :state, type: String, values: %w[opened closed all], default: 'opened',
+ desc: 'Return opened, closed, or all issues'
+ use :issues_params
+ end
get ":id/issues" do
- group = find_group!(params[:id])
+ group = find_group!(params.delete(:id))
- params[:state] ||= 'opened'
params[:group_id] = group.id
params[:milestone_title] = params.delete(:milestone)
params[:label_name] = params.delete(:labels)
- if params[:order_by] || params[:sort]
- # The Sortable concern takes 'created_desc', not 'created_at_desc' (for example)
- params[:sort] = "#{issuable_order_by.sub('_at', '')}_#{issuable_sort}"
- end
-
issues = IssuesFinder.new(current_user, params).execute
+ issues = issues.reorder(params[:order_by] => params[:sort])
present paginate(issues), with: Entities::Issue, current_user: current_user
end
end
@@ -98,32 +90,19 @@ module API
params do
requires :id, type: String, desc: 'The ID of a project'
end
-
resource :projects do
- # Get a list of project issues
- #
- # Parameters:
- # id (required) - The ID of a project
- # iid (optional) - Return the project issue having the given `iid`
- # state (optional) - Return "opened" or "closed" issues
- # labels (optional) - Comma-separated list of label names
- # milestone (optional) - Milestone title
- # order_by (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at`
- # sort (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
- #
- # Example Requests:
- # GET /projects/:id/issues
- # GET /projects/:id/issues?state=opened
- # GET /projects/:id/issues?state=closed
- # GET /projects/:id/issues?labels=foo
- # GET /projects/:id/issues?labels=foo,bar
- # GET /projects/:id/issues?labels=foo,bar&state=opened
- # GET /projects/:id/issues?milestone=1.0.0
- # GET /projects/:id/issues?milestone=1.0.0&state=closed
- # GET /issues?iid=42
+ desc 'Get a list of project issues' do
+ success Entities::Issue
+ end
+ params do
+ optional :state, type: String, values: %w[opened closed all], default: 'all',
+ desc: 'Return opened, closed, or all issues'
+ optional :iid, type: Integer, desc: 'The IID of the issue'
+ use :issues_params
+ end
get ":id/issues" do
issues = IssuesFinder.new(current_user, project_id: user_project.id).execute.inc_notes_with_associations
- issues = filter_issues_state(issues, params[:state]) unless params[:state].nil?
+ issues = filter_issues_state(issues, params[:state])
issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil?
issues = filter_by_iid(issues, params[:iid]) unless params[:iid].nil?
@@ -131,50 +110,49 @@ module API
issues = filter_issues_milestone(issues, params[:milestone])
end
- issues = issues.reorder(issuable_order_by => issuable_sort)
-
+ issues = issues.reorder(params[:order_by] => params[:sort])
present paginate(issues), with: Entities::Issue, current_user: current_user, project: user_project
end
- # Get a single project issue
- #
- # Parameters:
- # id (required) - The ID of a project
- # issue_id (required) - The ID of a project issue
- # Example Request:
- # GET /projects/:id/issues/:issue_id
+ desc 'Get a single project issue' do
+ success Entities::Issue
+ end
+ params do
+ requires :issue_id, type: Integer, desc: 'The ID of a project issue'
+ end
get ":id/issues/:issue_id" do
- @issue = find_project_issue(params[:issue_id])
- present @issue, with: Entities::Issue, current_user: current_user, project: user_project
+ issue = find_project_issue(params[:issue_id])
+ present issue, with: Entities::Issue, current_user: current_user, project: user_project
end
- # Create a new project issue
- #
- # Parameters:
- # id (required) - The ID of a project
- # title (required) - The title of an issue
- # description (optional) - The description of an issue
- # assignee_id (optional) - The ID of a user to assign issue
- # milestone_id (optional) - The ID of a milestone to assign issue
- # labels (optional) - The labels of an issue
- # created_at (optional) - Date time string, ISO 8601 formatted
- # due_date (optional) - Date time string in the format YEAR-MONTH-DAY
- # confidential (optional) - Boolean parameter if the issue should be confidential
- # Example Request:
- # POST /projects/:id/issues
+ desc 'Create a new project issue' do
+ success Entities::Issue
+ end
+ params do
+ requires :title, type: String, desc: 'The title of an issue'
+ optional :created_at, type: DateTime,
+ desc: 'Date time when the issue was created. Available only for admins and project owners.'
+ optional :merge_request_for_resolving_discussions, type: Integer,
+ desc: 'The IID of a merge request for which to resolve discussions'
+ use :issue_params
+ end
post ':id/issues' do
- required_attributes! [:title]
-
- keys = [:title, :description, :assignee_id, :milestone_id, :due_date, :confidential, :labels]
- keys << :created_at if current_user.admin? || user_project.owner == current_user
- attrs = attributes_for_keys(keys)
+ # Setting created_at time only allowed for admins and project owners
+ unless current_user.admin? || user_project.owner == current_user
+ params.delete(:created_at)
+ end
- # Convert and filter out invalid confidential flags
- attrs['confidential'] = to_boolean(attrs['confidential'])
- attrs.delete('confidential') if attrs['confidential'].nil?
+ issue_params = declared_params(include_missing: false)
- issue = ::Issues::CreateService.new(user_project, current_user, attrs.merge(request: request, api: true)).execute
+ if merge_request_iid = params[:merge_request_for_resolving_discussions]
+ issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id).
+ execute.
+ find_by(iid: merge_request_iid)
+ end
+ issue = ::Issues::CreateService.new(user_project,
+ current_user,
+ issue_params.merge(request: request, api: true)).execute
if issue.spam?
render_api_error!({ error: 'Spam detected' }, 400)
end
@@ -190,31 +168,26 @@ module API
success Entities::Issue
end
params do
- requires :id, type: String, desc: 'The ID of a project'
- requires :issue_id, type: Integer, desc: "The ID of a project issue"
- optional :title, type: String, desc: 'The new title of the issue'
- optional :description, type: String, desc: 'The description of an issue'
- optional :assignee_id, type: Integer, desc: 'The ID of a user to assign issue'
- optional :milestone_id, type: Integer, desc: 'The ID of a milestone to assign issue'
- optional :labels, type: String, desc: 'The labels of an issue'
- optional :state_event, type: String, values: ['close', 'reopen'], desc: 'The state event of an issue'
- # TODO 9.0, use the Grape DateTime type here
- optional :updated_at, type: String, desc: 'Date time string, ISO 8601 formatted'
- optional :due_date, type: String, desc: 'Date time string in the format YEAR-MONTH-DAY'
- # TODO 9.0, use the Grape boolean type here
- optional :confidential, type: String, desc: 'Boolean parameter if the issue should be confidential'
+ requires :issue_id, type: Integer, desc: 'The ID of a project issue'
+ optional :title, type: String, desc: 'The title of an issue'
+ optional :updated_at, type: DateTime,
+ desc: 'Date time when the issue was updated. Available only for admins and project owners.'
+ use :issue_params
+ at_least_one_of :title, :description, :assignee_id, :milestone_id,
+ :labels, :created_at, :due_date, :confidential, :state_event
end
put ':id/issues/:issue_id' do
- issue = user_project.issues.find(params[:issue_id])
+ issue = user_project.issues.find(params.delete(:issue_id))
authorize! :update_issue, issue
- # Convert and filter out invalid confidential flags
- params[:confidential] = to_boolean(params[:confidential])
- params.delete(:confidential) if params[:confidential].nil?
-
- params.delete(:updated_at) unless current_user.admin? || user_project.owner == current_user
+ # Setting created_at time only allowed for admins and project owners
+ unless current_user.admin? || user_project.owner == current_user
+ params.delete(:updated_at)
+ end
- issue = ::Issues::UpdateService.new(user_project, current_user, issue_params).execute(issue)
+ issue = ::Issues::UpdateService.new(user_project,
+ current_user,
+ declared_params(include_missing: false)).execute(issue)
if issue.valid?
present issue, with: Entities::Issue, current_user: current_user, project: user_project
@@ -223,19 +196,19 @@ module API
end
end
- # Move an existing issue
- #
- # Parameters:
- # id (required) - The ID of a project
- # issue_id (required) - The ID of a project issue
- # to_project_id (required) - The ID of the new project
- # Example Request:
- # POST /projects/:id/issues/:issue_id/move
+ desc 'Move an existing issue' do
+ success Entities::Issue
+ end
+ params do
+ requires :issue_id, type: Integer, desc: 'The ID of a project issue'
+ requires :to_project_id, type: Integer, desc: 'The ID of the new project'
+ end
post ':id/issues/:issue_id/move' do
- required_attributes! [:to_project_id]
+ issue = user_project.issues.find_by(id: params[:issue_id])
+ not_found!('Issue') unless issue
- issue = user_project.issues.find(params[:issue_id])
- new_project = Project.find(params[:to_project_id])
+ new_project = Project.find_by(id: params[:to_project_id])
+ not_found!('Project') unless new_project
begin
issue = ::Issues::MoveService.new(user_project, current_user).execute(issue, new_project)
@@ -245,16 +218,13 @@ module API
end
end
- #
- # Delete a project issue
- #
- # Parameters:
- # id (required) - The ID of a project
- # issue_id (required) - The ID of a project issue
- # Example Request:
- # DELETE /projects/:id/issues/:issue_id
+ desc 'Delete a project issue'
+ params do
+ requires :issue_id, type: Integer, desc: 'The ID of a project issue'
+ end
delete ":id/issues/:issue_id" do
issue = user_project.issues.find_by(id: params[:issue_id])
+ not_found!('Issue') unless issue
authorize!(:destroy_issue, issue)
issue.destroy
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 253460830ff..55bdbc6a47c 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -30,6 +30,7 @@ module API
optional :assignee_id, type: Integer, desc: 'The ID of a user to assign the merge request'
optional :milestone_id, type: Integer, desc: 'The ID of a milestone to assign the merge request'
optional :labels, type: String, desc: 'Comma-separated list of label names'
+ optional :remove_source_branch, type: Boolean, desc: 'Remove source branch when merging'
end
end
@@ -78,7 +79,8 @@ module API
post ":id/merge_requests" do
authorize! :create_merge_request, user_project
- mr_params = declared_params
+ mr_params = declared_params(include_missing: false)
+ mr_params[:force_remove_source_branch] = mr_params.delete(:remove_source_branch) if mr_params[:remove_source_branch].present?
merge_request = ::MergeRequests::CreateService.new(user_project, current_user, mr_params).execute
@@ -147,13 +149,15 @@ module API
desc: 'Status of the merge request'
use :optional_params
at_least_one_of :title, :target_branch, :description, :assignee_id,
- :milestone_id, :labels, :state_event
+ :milestone_id, :labels, :state_event,
+ :remove_source_branch
end
put path do
merge_request = user_project.merge_requests.find(params.delete(:merge_request_id))
authorize! :update_merge_request, merge_request
mr_params = declared_params(include_missing: false)
+ mr_params[:force_remove_source_branch] = mr_params.delete(:remove_source_branch) if mr_params[:remove_source_branch].present?
merge_request = ::MergeRequests::UpdateService.new(user_project, current_user, mr_params).execute(merge_request)
diff --git a/lib/api/session.rb b/lib/api/session.rb
index d09400b81f5..002ffd1d154 100644
--- a/lib/api/session.rb
+++ b/lib/api/session.rb
@@ -1,7 +1,7 @@
module API
class Session < Grape::API
desc 'Login to get token' do
- success Entities::UserLogin
+ success Entities::UserWithPrivateToken
end
params do
optional :login, type: String, desc: 'The username'
@@ -14,7 +14,7 @@ module API
return unauthorized! unless user
return render_api_error!('401 Unauthorized. You have 2FA enabled. Please use a personal access token to access the API', 401) if user.two_factor_enabled?
- present user, with: Entities::UserLogin
+ present user, with: Entities::UserWithPrivateToken
end
end
end
diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb
new file mode 100644
index 00000000000..e096e636806
--- /dev/null
+++ b/lib/api/snippets.rb
@@ -0,0 +1,137 @@
+module API
+ # Snippets API
+ class Snippets < Grape::API
+ include PaginationParams
+
+ before { authenticate! }
+
+ resource :snippets do
+ helpers do
+ def snippets_for_current_user
+ SnippetsFinder.new.execute(current_user, filter: :by_user, user: current_user)
+ end
+
+ def public_snippets
+ SnippetsFinder.new.execute(current_user, filter: :public)
+ end
+ end
+
+ desc 'Get a snippets list for authenticated user' do
+ detail 'This feature was introduced in GitLab 8.15.'
+ success Entities::PersonalSnippet
+ end
+ params do
+ use :pagination
+ end
+ get do
+ present paginate(snippets_for_current_user), with: Entities::PersonalSnippet
+ end
+
+ desc 'List all public snippets current_user has access to' do
+ detail 'This feature was introduced in GitLab 8.15.'
+ success Entities::PersonalSnippet
+ end
+ params do
+ use :pagination
+ end
+ get 'public' do
+ present paginate(public_snippets), with: Entities::PersonalSnippet
+ end
+
+ desc 'Get a single snippet' do
+ detail 'This feature was introduced in GitLab 8.15.'
+ success Entities::PersonalSnippet
+ end
+ params do
+ requires :id, type: Integer, desc: 'The ID of a snippet'
+ end
+ get ':id' do
+ snippet = snippets_for_current_user.find(params[:id])
+ present snippet, with: Entities::PersonalSnippet
+ end
+
+ desc 'Create new snippet' do
+ detail 'This feature was introduced in GitLab 8.15.'
+ success Entities::PersonalSnippet
+ end
+ params do
+ requires :title, type: String, desc: 'The title of a snippet'
+ requires :file_name, type: String, desc: 'The name of a snippet file'
+ requires :content, type: String, desc: 'The content of a snippet'
+ optional :visibility_level, type: Integer,
+ values: Gitlab::VisibilityLevel.values,
+ default: Gitlab::VisibilityLevel::INTERNAL,
+ desc: 'The visibility level of the snippet'
+ end
+ post do
+ attrs = declared_params(include_missing: false)
+ snippet = CreateSnippetService.new(nil, current_user, attrs).execute
+
+ if snippet.persisted?
+ present snippet, with: Entities::PersonalSnippet
+ else
+ render_validation_error!(snippet)
+ end
+ end
+
+ desc 'Update an existing snippet' do
+ detail 'This feature was introduced in GitLab 8.15.'
+ success Entities::PersonalSnippet
+ end
+ params do
+ requires :id, type: Integer, desc: 'The ID of a snippet'
+ optional :title, type: String, desc: 'The title of a snippet'
+ optional :file_name, type: String, desc: 'The name of a snippet file'
+ optional :content, type: String, desc: 'The content of a snippet'
+ optional :visibility_level, type: Integer,
+ values: Gitlab::VisibilityLevel.values,
+ desc: 'The visibility level of the snippet'
+ at_least_one_of :title, :file_name, :content, :visibility_level
+ end
+ put ':id' do
+ snippet = snippets_for_current_user.find_by(id: params.delete(:id))
+ return not_found!('Snippet') unless snippet
+ authorize! :update_personal_snippet, snippet
+
+ attrs = declared_params(include_missing: false)
+
+ UpdateSnippetService.new(nil, current_user, snippet, attrs).execute
+ if snippet.persisted?
+ present snippet, with: Entities::PersonalSnippet
+ else
+ render_validation_error!(snippet)
+ end
+ end
+
+ desc 'Remove snippet' do
+ detail 'This feature was introduced in GitLab 8.15.'
+ success Entities::PersonalSnippet
+ end
+ params do
+ requires :id, type: Integer, desc: 'The ID of a snippet'
+ end
+ delete ':id' do
+ snippet = snippets_for_current_user.find_by(id: params.delete(:id))
+ return not_found!('Snippet') unless snippet
+ authorize! :destroy_personal_snippet, snippet
+ snippet.destroy
+ no_content!
+ end
+
+ desc 'Get a raw snippet' do
+ detail 'This feature was introduced in GitLab 8.15.'
+ end
+ params do
+ requires :id, type: Integer, desc: 'The ID of a snippet'
+ end
+ get ":id/raw" do
+ snippet = snippets_for_current_user.find_by(id: params.delete(:id))
+ return not_found!('Snippet') unless snippet
+
+ env['api.format'] = :txt
+ content_type 'text/plain'
+ present snippet.content
+ end
+ end
+ end
+end
diff --git a/lib/api/tags.rb b/lib/api/tags.rb
index cd33f9a9903..5b345db3a41 100644
--- a/lib/api/tags.rb
+++ b/lib/api/tags.rb
@@ -1,7 +1,6 @@
module API
# Git Tags API
class Tags < Grape::API
- before { authenticate! }
before { authorize! :download_code, user_project }
params do
diff --git a/lib/api/users.rb b/lib/api/users.rb
index bc2362aa72e..1dab799dd61 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -51,7 +51,7 @@ module API
users = users.external if params[:external] && current_user.is_admin?
end
- entity = current_user.is_admin? ? Entities::UserFull : Entities::UserBasic
+ entity = current_user.is_admin? ? Entities::UserPublic : Entities::UserBasic
present paginate(users), with: entity
end
@@ -66,7 +66,7 @@ module API
not_found!('User') unless user
if current_user && current_user.is_admin?
- present user, with: Entities::UserFull
+ present user, with: Entities::UserPublic
elsif can?(current_user, :read_user, user)
present user, with: Entities::User
else
@@ -75,7 +75,7 @@ module API
end
desc 'Create a user. Available only for admins.' do
- success Entities::UserFull
+ success Entities::UserPublic
end
params do
requires :email, type: String, desc: 'The email of the user'
@@ -99,7 +99,7 @@ module API
end
if user.save
- present user, with: Entities::UserFull
+ present user, with: Entities::UserPublic
else
conflict!('Email has already been taken') if User.
where(email: user.email).
@@ -114,7 +114,7 @@ module API
end
desc 'Update a user. Available only for admins.' do
- success Entities::UserFull
+ success Entities::UserPublic
end
params do
requires :id, type: Integer, desc: 'The ID of the user'
@@ -161,7 +161,7 @@ module API
user_params.delete(:provider)
if user.update_attributes(user_params)
- present user, with: Entities::UserFull
+ present user, with: Entities::UserPublic
else
render_validation_error!(user)
end
@@ -350,10 +350,10 @@ module API
resource :user do
desc 'Get the currently authenticated user' do
- success Entities::UserFull
+ success Entities::UserPublic
end
get do
- present current_user, with: Entities::UserFull
+ present current_user, with: @impersonator ? Entities::UserWithPrivateToken : Entities::UserPublic
end
desc "Get the currently authenticated user's SSH keys" do