summaryrefslogtreecommitdiff
path: root/lib/api
diff options
context:
space:
mode:
authorTimothy Andrew <mail@timothyandrew.net>2016-06-03 09:31:16 +0530
committerTimothy Andrew <mail@timothyandrew.net>2016-06-03 09:31:16 +0530
commitae0d8222afe1c2482765c92240d35f41d54a73db (patch)
treef3ef7e7fd87f21bae33a595d848c18fd56df8b75 /lib/api
parentffe111c1e22b0cce827c297fea62dfb0bd91326a (diff)
parent07b46517cc940b429515374e4e102ff04405e804 (diff)
downloadgitlab-ce-ae0d8222afe1c2482765c92240d35f41d54a73db.tar.gz
Merge remote-tracking branch 'origin/master' into 2979-personal-access-tokens
Diffstat (limited to 'lib/api')
-rw-r--r--lib/api/api.rb2
-rw-r--r--lib/api/commits.rb2
-rw-r--r--lib/api/entities.rb23
-rw-r--r--lib/api/gitignores.rb29
-rw-r--r--lib/api/groups.rb3
-rw-r--r--lib/api/helpers.rb15
-rw-r--r--lib/api/issues.rb39
-rw-r--r--lib/api/labels.rb6
-rw-r--r--lib/api/licenses.rb14
-rw-r--r--lib/api/merge_requests.rb36
-rw-r--r--lib/api/notes.rb47
-rw-r--r--lib/api/projects.rb7
-rw-r--r--lib/api/runners.rb2
-rw-r--r--lib/api/subscriptions.rb60
-rw-r--r--lib/api/users.rb2
15 files changed, 174 insertions, 113 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 5fd9c30cb42..6cd909f6115 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -57,5 +57,7 @@ module API
mount ::API::Variables
mount ::API::Runners
mount ::API::Licenses
+ mount ::API::Subscriptions
+ mount ::API::Gitignores
end
end
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 93a3a5ce089..4a11c8e3620 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -107,6 +107,8 @@ module API
break if opts[:line_code]
end
+
+ opts[:type] = LegacyDiffNote.name if opts[:line_code]
end
note = ::Notes::CreateService.new(user_project, current_user, opts).execute
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 2870a6a40ef..790a1869f73 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -66,7 +66,8 @@ module API
expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group }
expose :name, :name_with_namespace
expose :path, :path_with_namespace
- expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, :created_at, :last_activity_at
+ expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, :container_registry_enabled
+ expose :created_at, :last_activity_at
expose :shared_runners_enabled
expose :creator_id
expose :namespace
@@ -227,9 +228,9 @@ module API
class CommitNote < Grape::Entity
expose :note
- expose(:path) { |note| note.diff_file_name }
- expose(:line) { |note| note.diff_new_line }
- expose(:line_type) { |note| note.diff_line_type }
+ expose(:path) { |note| note.diff_file_path if note.legacy_diff_note? }
+ expose(:line) { |note| note.diff_new_line if note.legacy_diff_note? }
+ expose(:line_type) { |note| note.diff_line_type if note.legacy_diff_note? }
expose :author, using: Entities::UserBasic
expose :created_at
end
@@ -307,6 +308,10 @@ module API
class Label < Grape::Entity
expose :name, :color, :description
expose :open_issues_count, :closed_issues_count, :open_merge_requests_count
+
+ expose :subscribed do |label, options|
+ label.subscribed?(options[:current_user])
+ end
end
class Compare < Grape::Entity
@@ -357,6 +362,7 @@ module API
expose :restricted_signup_domains
expose :user_oauth_applications
expose :after_sign_out_path
+ expose :container_registry_token_expire_delay
end
class Release < Grape::Entity
@@ -403,6 +409,7 @@ module API
class RunnerDetails < Runner
expose :tag_list
+ expose :run_untagged
expose :version, :revision, :platform, :architecture
expose :contacted_at
expose :token, if: lambda { |runner, options| options[:current_user].is_admin? || !runner.is_shared? }
@@ -451,5 +458,13 @@ module API
expose(:limitations) { |license| license.meta['limitations'] }
expose :content
end
+
+ class GitignoresList < Grape::Entity
+ expose :name
+ end
+
+ class Gitignore < Grape::Entity
+ expose :name, :content
+ end
end
end
diff --git a/lib/api/gitignores.rb b/lib/api/gitignores.rb
new file mode 100644
index 00000000000..270c9501dd2
--- /dev/null
+++ b/lib/api/gitignores.rb
@@ -0,0 +1,29 @@
+module API
+ class Gitignores < Grape::API
+
+ # Get the list of the available gitignore templates
+ #
+ # Example Request:
+ # GET /gitignores
+ get 'gitignores' do
+ present Gitlab::Gitignore.all, with: Entities::GitignoresList
+ end
+
+ # Get the text for a specific gitignore
+ #
+ # Parameters:
+ # name (required) - The name of a license
+ #
+ # Example Request:
+ # GET /gitignores/Elixir
+ #
+ get 'gitignores/:name' do
+ required_attributes! [:name]
+
+ gitignore = Gitlab::Gitignore.find(params[:name])
+ not_found!('.gitignore') unless gitignore
+
+ present gitignore, with: Entities::Gitignore
+ end
+ end
+end
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index 91e420832f3..9d8b8d737a9 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -95,8 +95,7 @@ module API
# GET /groups/:id/projects
get ":id/projects" do
group = find_group(params[:id])
- projects = group.projects
- projects = filter_projects(projects)
+ projects = GroupProjectsFinder.new(group).execute(current_user)
projects = paginate projects
present projects, with: Entities::Project
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 68642e2d8a7..a179fe9f2f9 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -2,7 +2,7 @@ module API
module Helpers
PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN"
PRIVATE_TOKEN_PARAM = :private_token
- SUDO_HEADER ="HTTP_SUDO"
+ SUDO_HEADER = "HTTP_SUDO"
SUDO_PARAM = :sudo
PERSONAL_ACCESS_TOKEN_PARAM = PRIVATE_TOKEN_PARAM
PERSONAL_ACCESS_TOKEN_HEADER = PRIVATE_TOKEN_HEADER
@@ -41,7 +41,7 @@ module API
@current_user
end
- def sudo_identifier()
+ def sudo_identifier
identifier ||= params[SUDO_PARAM] || env[SUDO_HEADER]
# Regex for integers
@@ -107,6 +107,17 @@ module API
end
end
+ def find_project_label(id)
+ label = user_project.labels.find_by_id(id) || user_project.labels.find_by_title(id)
+ label || not_found!('Label')
+ end
+
+ def find_project_issue(id)
+ issue = user_project.issues.find(id)
+ not_found! unless can?(current_user, :read_issue, issue)
+ issue
+ end
+
def paginate(relation)
relation.page(params[:page]).per(params[:per_page].to_i).tap do |data|
add_pagination_headers(data)
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 40928749481..f59a4d6c012 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -103,8 +103,7 @@ module API
# Example Request:
# GET /projects/:id/issues/:issue_id
get ":id/issues/:issue_id" do
- @issue = user_project.issues.find(params[:issue_id])
- not_found! unless can?(current_user, :read_issue, @issue)
+ @issue = find_project_issue(params[:issue_id])
present @issue, with: Entities::Issue, current_user: current_user
end
@@ -234,42 +233,6 @@ module API
authorize!(:destroy_issue, issue)
issue.destroy
end
-
- # Subscribes to a project issue
- #
- # Parameters:
- # id (required) - The ID of a project
- # issue_id (required) - The ID of a project issue
- # Example Request:
- # POST /projects/:id/issues/:issue_id/subscription
- post ':id/issues/:issue_id/subscription' do
- issue = user_project.issues.find(params[:issue_id])
-
- if issue.subscribed?(current_user)
- not_modified!
- else
- issue.toggle_subscription(current_user)
- present issue, with: Entities::Issue, current_user: current_user
- end
- end
-
- # Unsubscribes from 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/subscription
- delete ':id/issues/:issue_id/subscription' do
- issue = user_project.issues.find(params[:issue_id])
-
- if issue.subscribed?(current_user)
- issue.unsubscribe(current_user)
- present issue, with: Entities::Issue, current_user: current_user
- else
- not_modified!
- end
- end
end
end
end
diff --git a/lib/api/labels.rb b/lib/api/labels.rb
index 4af6bef0fa7..c806829d69e 100644
--- a/lib/api/labels.rb
+++ b/lib/api/labels.rb
@@ -11,7 +11,7 @@ module API
# Example Request:
# GET /projects/:id/labels
get ':id/labels' do
- present user_project.labels, with: Entities::Label
+ present user_project.labels, with: Entities::Label, current_user: current_user
end
# Creates a new label
@@ -36,7 +36,7 @@ module API
label = user_project.labels.create(attrs)
if label.valid?
- present label, with: Entities::Label
+ present label, with: Entities::Label, current_user: current_user
else
render_validation_error!(label)
end
@@ -90,7 +90,7 @@ module API
attrs[:name] = attrs.delete(:new_name) if attrs.key?(:new_name)
if label.update(attrs)
- present label, with: Entities::Label
+ present label, with: Entities::Label, current_user: current_user
else
render_validation_error!(label)
end
diff --git a/lib/api/licenses.rb b/lib/api/licenses.rb
index 187d2c04703..be0e113fbcb 100644
--- a/lib/api/licenses.rb
+++ b/lib/api/licenses.rb
@@ -2,15 +2,15 @@ module API
# Licenses API
class Licenses < Grape::API
PROJECT_TEMPLATE_REGEX =
- /[\<\{\[]
- (project|description|
- one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here
- [\>\}\]]/xi.freeze
+ /[\<\{\[]
+ (project|description|
+ one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here
+ [\>\}\]]/xi.freeze
YEAR_TEMPLATE_REGEX = /[<{\[](year|yyyy)[>}\]]/i.freeze
FULLNAME_TEMPLATE_REGEX =
- /[\<\{\[]
- (fullname|name\sof\s(author|copyright\sowner))
- [\>\}\]]/xi.freeze
+ /[\<\{\[]
+ (fullname|name\sof\s(author|copyright\sowner))
+ [\>\}\]]/xi.freeze
# Get the list of the available license templates
#
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 7e78609ecb9..4e7de8867b4 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -327,42 +327,6 @@ module API
issues = ::Kaminari.paginate_array(merge_request.closes_issues(current_user))
present paginate(issues), with: Entities::Issue, current_user: current_user
end
-
- # Subscribes to a merge request
- #
- # Parameters:
- # id (required) - The ID of a project
- # merge_request_id (required) - The ID of a merge request
- # Example Request:
- # POST /projects/:id/issues/:merge_request_id/subscription
- post "#{path}/subscription" do
- merge_request = user_project.merge_requests.find(params[:merge_request_id])
-
- if merge_request.subscribed?(current_user)
- not_modified!
- else
- merge_request.toggle_subscription(current_user)
- present merge_request, with: Entities::MergeRequest, current_user: current_user
- end
- end
-
- # Unsubscribes from a merge request
- #
- # Parameters:
- # id (required) - The ID of a project
- # merge_request_id (required) - The ID of a merge request
- # Example Request:
- # DELETE /projects/:id/merge_requests/:merge_request_id/subscription
- delete "#{path}/subscription" do
- merge_request = user_project.merge_requests.find(params[:merge_request_id])
-
- if merge_request.subscribed?(current_user)
- merge_request.unsubscribe(current_user)
- present merge_request, with: Entities::MergeRequest, current_user: current_user
- else
- not_modified!
- end
- end
end
end
end
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 71a53e6f0d6..d4fcfd3d4d3 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -19,20 +19,24 @@ module API
# GET /projects/:id/issues/:noteable_id/notes
# GET /projects/:id/snippets/:noteable_id/notes
get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do
- @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"])
-
- # We exclude notes that are cross-references and that cannot be viewed
- # by the current user. By doing this exclusion at this level and not
- # at the DB query level (which we cannot in that case), the current
- # page can have less elements than :per_page even if
- # there's more than one page.
- notes =
- # paginate() only works with a relation. This could lead to a
- # mismatch between the pagination headers info and the actual notes
- # array returned, but this is really a edge-case.
- paginate(@noteable.notes).
- reject { |n| n.cross_reference_not_visible_for?(current_user) }
- present notes, with: Entities::Note
+ @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym])
+
+ if can?(current_user, noteable_read_ability_name(@noteable), @noteable)
+ # We exclude notes that are cross-references and that cannot be viewed
+ # by the current user. By doing this exclusion at this level and not
+ # at the DB query level (which we cannot in that case), the current
+ # page can have less elements than :per_page even if
+ # there's more than one page.
+ notes =
+ # paginate() only works with a relation. This could lead to a
+ # mismatch between the pagination headers info and the actual notes
+ # array returned, but this is really a edge-case.
+ paginate(@noteable.notes).
+ reject { |n| n.cross_reference_not_visible_for?(current_user) }
+ present notes, with: Entities::Note
+ else
+ not_found!("Notes")
+ end
end
# Get a single +noteable+ note
@@ -45,13 +49,14 @@ module API
# GET /projects/:id/issues/:noteable_id/notes/:note_id
# GET /projects/:id/snippets/:noteable_id/notes/:note_id
get ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do
- @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"])
+ @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym])
@note = @noteable.notes.find(params[:note_id])
+ can_read_note = can?(current_user, noteable_read_ability_name(@noteable), @noteable) && !@note.cross_reference_not_visible_for?(current_user)
- if @note.cross_reference_not_visible_for?(current_user)
- not_found!("Note")
- else
+ if can_read_note
present @note, with: Entities::Note
+ else
+ not_found!("Note")
end
end
@@ -136,5 +141,11 @@ module API
end
end
end
+
+ helpers do
+ def noteable_read_ability_name(noteable)
+ "read_#{noteable.class.to_s.underscore.downcase}".to_sym
+ end
+ end
end
end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index cc2c7a0c503..5a22d14988f 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -44,7 +44,7 @@ module API
# Example Request:
# GET /projects/starred
get '/starred' do
- @projects = current_user.starred_projects
+ @projects = current_user.viewable_starred_projects
@projects = filter_projects(@projects)
@projects = paginate @projects
present @projects, with: Entities::Project
@@ -94,6 +94,7 @@ module API
# builds_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
+ # container_registry_enabled (optional)
# shared_runners_enabled (optional)
# namespace_id (optional) - defaults to user namespace
# public (optional) - if true same as setting visibility_level = 20
@@ -112,6 +113,7 @@ module API
:builds_enabled,
:wiki_enabled,
:snippets_enabled,
+ :container_registry_enabled,
:shared_runners_enabled,
:namespace_id,
:public,
@@ -143,6 +145,7 @@ module API
# builds_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
+ # container_registry_enabled (optional)
# shared_runners_enabled (optional)
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional)
@@ -206,6 +209,7 @@ module API
# builds_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
+ # container_registry_enabled (optional)
# shared_runners_enabled (optional)
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - visibility level of a project
@@ -222,6 +226,7 @@ module API
:builds_enabled,
:wiki_enabled,
:snippets_enabled,
+ :container_registry_enabled,
:shared_runners_enabled,
:public,
:visibility_level,
diff --git a/lib/api/runners.rb b/lib/api/runners.rb
index 8ec91485b26..4faba9dc87b 100644
--- a/lib/api/runners.rb
+++ b/lib/api/runners.rb
@@ -49,7 +49,7 @@ module API
runner = get_runner(params[:id])
authenticate_update_runner!(runner)
- attrs = attributes_for_keys [:description, :active, :tag_list]
+ attrs = attributes_for_keys [:description, :active, :tag_list, :run_untagged]
if runner.update(attrs)
present runner, with: Entities::RunnerDetails, current_user: current_user
else
diff --git a/lib/api/subscriptions.rb b/lib/api/subscriptions.rb
new file mode 100644
index 00000000000..c49e2a21b82
--- /dev/null
+++ b/lib/api/subscriptions.rb
@@ -0,0 +1,60 @@
+module API
+ class Subscriptions < Grape::API
+ before { authenticate! }
+
+ subscribable_types = {
+ 'merge_request' => proc { |id| user_project.merge_requests.find(id) },
+ 'merge_requests' => proc { |id| user_project.merge_requests.find(id) },
+ 'issues' => proc { |id| find_project_issue(id) },
+ 'labels' => proc { |id| find_project_label(id) },
+ }
+
+ resource :projects do
+ subscribable_types.each do |type, finder|
+ type_singularized = type.singularize
+ type_id_str = :"#{type_singularized}_id"
+ entity_class = Entities.const_get(type_singularized.camelcase)
+
+ # Subscribe to a resource
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # subscribable_id (required) - The ID of a resource
+ # Example Request:
+ # POST /projects/:id/labels/:subscribable_id/subscription
+ # POST /projects/:id/issues/:subscribable_id/subscription
+ # POST /projects/:id/merge_requests/:subscribable_id/subscription
+ post ":id/#{type}/:#{type_id_str}/subscription" do
+ resource = instance_exec(params[type_id_str], &finder)
+
+ if resource.subscribed?(current_user)
+ not_modified!
+ else
+ resource.subscribe(current_user)
+ present resource, with: entity_class, current_user: current_user
+ end
+ end
+
+ # Unsubscribe from a resource
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # subscribable_id (required) - The ID of a resource
+ # Example Request:
+ # DELETE /projects/:id/labels/:subscribable_id/subscription
+ # DELETE /projects/:id/issues/:subscribable_id/subscription
+ # DELETE /projects/:id/merge_requests/:subscribable_id/subscription
+ delete ":id/#{type}/:#{type_id_str}/subscription" do
+ resource = instance_exec(params[type_id_str], &finder)
+
+ if !resource.subscribed?(current_user)
+ not_modified!
+ else
+ resource.unsubscribe(current_user)
+ present resource, with: entity_class, current_user: current_user
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/users.rb b/lib/api/users.rb
index ea6fa2dc8a8..8a376d3c2a3 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -76,7 +76,7 @@ module API
required_attributes! [:email, :password, :name, :username]
attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :bio, :location, :can_create_group, :admin, :confirm, :external]
admin = attrs.delete(:admin)
- confirm = !(attrs.delete(:confirm) =~ (/(false|f|no|0)$/i))
+ confirm = !(attrs.delete(:confirm) =~ /(false|f|no|0)$/i)
user = User.build_user(attrs)
user.admin = admin unless admin.nil?
user.skip_confirmation! unless confirm