diff options
Diffstat (limited to 'lib')
93 files changed, 365 insertions, 191 deletions
diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb index 789f45489eb..a5c9f0b509c 100644 --- a/lib/api/access_requests.rb +++ b/lib/api/access_requests.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: "The #{source_type} ID" end - resource source_type.pluralize do + resource source_type.pluralize, requirements: { id: %r{[^/]+} } do desc "Gets a list of access requests for a #{source_type}." do detail 'This feature was introduced in GitLab 8.11.' success Entities::AccessRequester diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index f9e0c2c4e16..56f19f89642 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -9,13 +9,15 @@ module API { type: 'snippet', find_by: :id } ].freeze - resource :projects do + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: { id: %r{[^/]+} } do AWARDABLES.each do |awardable_params| awardable_string = awardable_params[:type].pluralize awardable_id_string = "#{awardable_params[:type]}_#{awardable_params[:find_by]}" params do - requires :id, type: String, desc: 'The ID of a project' requires :"#{awardable_id_string}", type: Integer, desc: "The ID of an Issue, Merge Request or Snippet" end diff --git a/lib/api/boards.rb b/lib/api/boards.rb index b6843c1b6af..5a2d7a681e3 100644 --- a/lib/api/boards.rb +++ b/lib/api/boards.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all project boards' do detail 'This feature was introduced in 8.13' success Entities::Board diff --git a/lib/api/branches.rb b/lib/api/branches.rb index 73a7e939627..f35084a582a 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -4,13 +4,12 @@ module API class Branches < Grape::API include PaginationParams - before { authenticate! } before { authorize! :download_code, user_project } params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a project repository branches' do success Entities::RepoBranch end @@ -102,6 +101,7 @@ module API end post ":id/repository/branches" do authorize_push_project + result = CreateBranchService.new(user_project, current_user). execute(params[:branch], params[:ref]) diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 9d9f82fdb83..827a38d33da 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -2,7 +2,10 @@ require 'mime/types' module API class CommitStatuses < Grape::API - resource :projects do + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: { id: %r{[^/]+} } do include PaginationParams before { authenticate! } @@ -11,7 +14,6 @@ module API success Entities::CommitStatus end params do - requires :id, type: String, desc: 'The ID of a project' requires :sha, type: String, desc: 'The commit hash' optional :ref, type: String, desc: 'The ref' optional :stage, type: String, desc: 'The stage' @@ -37,7 +39,6 @@ module API success Entities::CommitStatus end params do - requires :id, type: String, desc: 'The ID of a project' requires :sha, type: String, desc: 'The commit hash' requires :state, type: String, desc: 'The state of the status', values: %w(pending running success failed canceled) diff --git a/lib/api/commits.rb b/lib/api/commits.rb index 42401abfe0f..66b37fd2bcc 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a project repository commits' do success Entities::RepoCommit end diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index 69e85c27a65..b888ede6fe8 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -17,7 +17,7 @@ module API params do requires :id, type: String, desc: 'The ID of the project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do before { authorize_admin_project } desc "Get a specific project's deploy keys" do diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb index 2f1ad12c38c..46b936897f6 100644 --- a/lib/api/deployments.rb +++ b/lib/api/deployments.rb @@ -8,7 +8,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all deployments of the project' do detail 'This feature was introduced in GitLab 8.11.' success Entities::Deployment diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 0a12ee72d49..5954aea8041 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -768,7 +768,7 @@ module API end class Dependency < Grape::Entity - expose :id, :name + expose :id, :name, :token expose :artifacts_file, using: ArtifactFile, if: ->(job, _) { job.artifacts? } end @@ -796,7 +796,7 @@ module API expose :artifacts, using: Artifacts expose :cache, using: Cache expose :credentials, using: Credentials - expose :depends_on_builds, as: :dependencies, using: Dependency + expose :dependencies, using: Dependency end end end diff --git a/lib/api/environments.rb b/lib/api/environments.rb index ebe8c3a5b2c..945771d46f3 100644 --- a/lib/api/environments.rb +++ b/lib/api/environments.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all environments of the project' do detail 'This feature was introduced in GitLab 8.11.' success Entities::Environment diff --git a/lib/api/files.rb b/lib/api/files.rb index bb8f5c3076d..33fc970dc09 100644 --- a/lib/api/files.rb +++ b/lib/api/files.rb @@ -52,7 +52,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get raw file contents from the repository' params do requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb' diff --git a/lib/api/groups.rb b/lib/api/groups.rb index b862ff70b31..8f3799417e3 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -84,7 +84,7 @@ module API params do requires :id, type: String, desc: 'The ID of a group' end - resource :groups do + resource :groups, requirements: { id: %r{[^/]+} } do desc 'Update a group. Available only for users who can administrate groups.' do success Entities::Group end @@ -154,7 +154,7 @@ module API params do requires :project_id, type: String, desc: 'The ID or path of the project' end - post ":id/projects/:project_id" do + post ":id/projects/:project_id", requirements: { project_id: /.+/ } do authenticated_as_admin! group = find_group!(params[:id]) project = find_project!(params[:project_id]) diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index ec2bcaed929..74848a6e144 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -41,14 +41,6 @@ module API (Time.now - current_runner.contacted_at) >= contacted_at_max_age end - def job_not_found! - if headers['User-Agent'].to_s =~ /gitlab(-ci-multi)?-runner \d+\.\d+\.\d+(~beta\.\d+\.g[0-9a-f]+)? / - no_content! - else - not_found! - end - end - def validate_job!(job) not_found! unless job diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 1abe8639445..fd2674910d2 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -58,7 +58,7 @@ module API params do requires :id, type: String, desc: 'The ID of a group' end - resource :groups do + resource :groups, requirements: { id: %r{[^/]+} } do desc 'Get a list of group issues' do success Entities::IssueBasic end @@ -79,7 +79,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do include TimeTrackingEndpoints desc 'Get a list of project issues' do @@ -91,7 +91,7 @@ module API use :issues_params end get ":id/issues" do - project = find_project(params[:id]) + project = find_project!(params[:id]) issues = find_issues(project_id: project.id) diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index 44118522abe..ffab0aafe59 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do helpers do params :optional_scope do optional :scope, types: [String, Array[String]], desc: 'The scope of builds to show', diff --git a/lib/api/labels.rb b/lib/api/labels.rb index 59f0e7cb647..d9a3cb7bb6b 100644 --- a/lib/api/labels.rb +++ b/lib/api/labels.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all labels of the project' do success Entities::Label end diff --git a/lib/api/members.rb b/lib/api/members.rb index baf85e6075a..c200e46a328 100644 --- a/lib/api/members.rb +++ b/lib/api/members.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: "The #{source_type} ID" end - resource source_type.pluralize do + resource source_type.pluralize, requirements: { id: %r{[^/]+} } do desc 'Gets a list of group or project members viewable by the authenticated user.' do success Entities::Member end diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb index a59e39cca26..4b79eac2b8b 100644 --- a/lib/api/merge_request_diffs.rb +++ b/lib/api/merge_request_diffs.rb @@ -5,14 +5,16 @@ module API before { authenticate! } - resource :projects do + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a list of merge request diff versions' do detail 'This feature was introduced in GitLab 8.12.' success Entities::MergeRequestDiff end params do - requires :id, type: String, desc: 'The ID of a project' requires :merge_request_iid, type: Integer, desc: 'The IID of a merge request' use :pagination end @@ -28,7 +30,6 @@ module API end params do - requires :id, type: String, desc: 'The ID of a project' requires :merge_request_iid, type: Integer, desc: 'The IID of a merge request' requires :version_id, type: Integer, desc: 'The ID of a merge request diff version' end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 7a03955a045..5cc807d5bff 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do include TimeTrackingEndpoints helpers do diff --git a/lib/api/milestones.rb b/lib/api/milestones.rb index abd263c1dfc..e7ab82f08db 100644 --- a/lib/api/milestones.rb +++ b/lib/api/milestones.rb @@ -23,7 +23,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a list of project milestones' do success Entities::Milestone end diff --git a/lib/api/notes.rb b/lib/api/notes.rb index 3b3e45cbd06..29ceffdbd2d 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do NOTEABLE_TYPES.each do |noteable_type| noteables_str = noteable_type.to_s.underscore.pluralize diff --git a/lib/api/notification_settings.rb b/lib/api/notification_settings.rb index c5e9b3ad69b..992ea5dc24d 100644 --- a/lib/api/notification_settings.rb +++ b/lib/api/notification_settings.rb @@ -48,14 +48,14 @@ module API end %w[group project].each do |source_type| - resource source_type.pluralize do + params do + requires :id, type: String, desc: "The #{source_type} ID" + end + resource source_type.pluralize, requirements: { id: %r{[^/]+} } do desc "Get #{source_type} level notification level settings, defaults to Global" do detail 'This feature was introduced in GitLab 8.12' success Entities::NotificationSetting end - params do - requires :id, type: String, desc: 'The group ID or project ID or project NAMESPACE/PROJECT_NAME' - end get ":id/notification_settings" do source = find_source(source_type, params[:id]) @@ -69,7 +69,6 @@ module API success Entities::NotificationSetting end params do - requires :id, type: String, desc: 'The group ID or project ID or project NAMESPACE/PROJECT_NAME' optional :level, type: String, desc: "The #{source_type} notification level" NotificationSetting::EMAIL_EVENTS.each do |event| optional event, type: Boolean, desc: 'Enable/disable this notification' diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb index 0721b975ba4..754c3d85a04 100644 --- a/lib/api/pipelines.rb +++ b/lib/api/pipelines.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all Pipelines of the project' do detail 'This feature was introduced in GitLab 8.11.' success Entities::PipelineBasic diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 57a5f97dc7f..53791166c33 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -24,7 +24,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get project hooks' do success Entities::ProjectHook end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index f57e7ea4032..cfee38a9baf 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do helpers do def handle_project_member_errors(errors) if errors[:project_access].any? diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 63a4cdd5954..0fbe1669d45 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -142,7 +142,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: /[^\/]+/ } do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a single project' do success Entities::ProjectWithAccess end diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 531ef5a63ea..8f16e532ecb 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do helpers do def handle_project_member_errors(errors) if errors[:project_access].any? diff --git a/lib/api/runner.rb b/lib/api/runner.rb index c700d2ef4a1..4c9db2c8716 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -47,11 +47,25 @@ module API authenticate_runner! Ci::Runner.find_by_token(params[:token]).destroy end + + desc 'Validates authentication credentials' do + http_codes [[200, 'Credentials are valid'], [403, 'Forbidden']] + end + params do + requires :token, type: String, desc: %q(Runner's authentication token) + end + post '/verify' do + authenticate_runner! + status 200 + end end resource :jobs do desc 'Request a job' do success Entities::JobRequest::Response + http_codes [[201, 'Job was scheduled'], + [204, 'No job for Runner'], + [403, 'Forbidden']] end params do requires :token, type: String, desc: %q(Runner's authentication token) @@ -60,13 +74,13 @@ module API end post '/request' do authenticate_runner! - not_found! unless current_runner.active? + no_content! unless current_runner.active? update_runner_info if current_runner.is_runner_queue_value_latest?(params[:last_update]) header 'X-GitLab-Last-Update', params[:last_update] Gitlab::Metrics.add_event(:build_not_found_cached) - return job_not_found! + return no_content! end new_update = current_runner.ensure_runner_queue_value @@ -80,7 +94,7 @@ module API else Gitlab::Metrics.add_event(:build_not_found) header 'X-GitLab-Last-Update', new_update - job_not_found! + no_content! end else # We received build that is invalid due to concurrency conflict diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 2e41f16f8c6..a77c876a749 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -86,7 +86,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do before { authorize_admin_project } desc 'Get runners available for project' do diff --git a/lib/api/services.rb b/lib/api/services.rb index 5aa2f5eba7b..4e0c9cb1f63 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -107,26 +107,6 @@ module API desc: 'Enable SSL verification for communication' } ], - 'builds-email' => [ - { - required: true, - name: :recipients, - type: String, - desc: 'Comma-separated list of recipient email addresses' - }, - { - required: false, - name: :add_pusher, - type: Boolean, - desc: 'Add pusher to recipients list' - }, - { - required: false, - name: :notify_only_broken_jobs, - type: Boolean, - desc: 'Notify only broken jobs' - } - ], 'campfire' => [ { required: true, @@ -403,9 +383,9 @@ module API }, { required: false, - name: :notify_only_broken_jobs, + name: :notify_only_broken_pipelines, type: Boolean, - desc: 'Notify only broken jobs' + desc: 'Notify only broken pipelines' } ], 'pivotaltracker' => [ @@ -550,7 +530,6 @@ module API BambooService, BugzillaService, BuildkiteService, - BuildsEmailService, CampfireService, CustomIssueTrackerService, DroneCiService, @@ -604,7 +583,10 @@ module API ] }.freeze - resource :projects do + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: { id: %r{[^/]+} } do before { authenticate! } before { authorize_admin_project } @@ -692,7 +674,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc "Trigger a slash command for #{service_slug}" do detail 'Added in GitLab 8.13' end diff --git a/lib/api/subscriptions.rb b/lib/api/subscriptions.rb index 772b5cca017..dbe54d3cd31 100644 --- a/lib/api/subscriptions.rb +++ b/lib/api/subscriptions.rb @@ -12,7 +12,7 @@ module API requires :id, type: String, desc: 'The ID of a project' requires :subscribable_id, type: String, desc: 'The ID of a resource' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do subscribable_types.each do |type, finder| type_singularized = type.singularize entity_class = Entities.const_get(type_singularized.camelcase) diff --git a/lib/api/tags.rb b/lib/api/tags.rb index d31ef9de26b..c7b1efe0bfa 100644 --- a/lib/api/tags.rb +++ b/lib/api/tags.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a project repository tags' do success Entities::RepoTag end diff --git a/lib/api/todos.rb b/lib/api/todos.rb index d9b8837a5bb..d1f7e364029 100644 --- a/lib/api/todos.rb +++ b/lib/api/todos.rb @@ -12,7 +12,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do ISSUABLE_TYPES.each do |type, finder| type_id_str = "#{type.singularize}_iid".to_sym diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb index 119e9024712..a9f2ca2608e 100644 --- a/lib/api/triggers.rb +++ b/lib/api/triggers.rb @@ -5,7 +5,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Trigger a GitLab project pipeline' do success Entities::Pipeline end @@ -14,7 +14,7 @@ module API requires :token, type: String, desc: 'The unique token of trigger' optional :variables, type: Hash, desc: 'The list of variables to be injected into build' end - post ":id/(ref/:ref/)trigger/pipeline" do + post ":id/(ref/:ref/)trigger/pipeline", requirements: { ref: /.+/ } do project = find_project(params[:id]) trigger = Ci::Trigger.find_by_token(params[:token].to_s) not_found! unless project && trigger diff --git a/lib/api/v3/award_emoji.rb b/lib/api/v3/award_emoji.rb index cf9e1551f60..b96b2d70b12 100644 --- a/lib/api/v3/award_emoji.rb +++ b/lib/api/v3/award_emoji.rb @@ -6,7 +6,7 @@ module API before { authenticate! } AWARDABLES = %w[issue merge_request snippet].freeze - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do AWARDABLES.each do |awardable_type| awardable_string = awardable_type.pluralize awardable_id_string = "#{awardable_type}_id" diff --git a/lib/api/v3/boards.rb b/lib/api/v3/boards.rb index b1c2a3c59f2..94acc67171e 100644 --- a/lib/api/v3/boards.rb +++ b/lib/api/v3/boards.rb @@ -6,7 +6,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all project boards' do detail 'This feature was introduced in 8.13' success ::API::Entities::Board diff --git a/lib/api/v3/branches.rb b/lib/api/v3/branches.rb index 699e41b5537..0a877b960f6 100644 --- a/lib/api/v3/branches.rb +++ b/lib/api/v3/branches.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a project repository branches' do success ::API::Entities::RepoBranch end @@ -45,6 +45,27 @@ module API status(200) end + + desc 'Create branch' do + success ::API::Entities::RepoBranch + end + params do + requires :branch_name, type: String, desc: 'The name of the branch' + requires :ref, type: String, desc: 'Create branch from commit sha or existing branch' + end + post ":id/repository/branches" do + authorize_push_project + result = CreateBranchService.new(user_project, current_user). + execute(params[:branch_name], params[:ref]) + + if result[:status] == :success + present result[:branch], + with: ::API::Entities::RepoBranch, + project: user_project + else + render_api_error!(result[:message], 400) + end + end end end end diff --git a/lib/api/v3/commits.rb b/lib/api/v3/commits.rb index d254d247042..3414a2883e5 100644 --- a/lib/api/v3/commits.rb +++ b/lib/api/v3/commits.rb @@ -11,7 +11,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a project repository commits' do success ::API::Entities::RepoCommit end diff --git a/lib/api/v3/deploy_keys.rb b/lib/api/v3/deploy_keys.rb index 5bbb167755c..bbb174b6003 100644 --- a/lib/api/v3/deploy_keys.rb +++ b/lib/api/v3/deploy_keys.rb @@ -13,7 +13,7 @@ module API params do requires :id, type: String, desc: 'The ID of the project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do before { authorize_admin_project } %w(keys deploy_keys).each do |path| diff --git a/lib/api/v3/deployments.rb b/lib/api/v3/deployments.rb index 95114ad1fe1..1d4972eda26 100644 --- a/lib/api/v3/deployments.rb +++ b/lib/api/v3/deployments.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all deployments of the project' do detail 'This feature was introduced in GitLab 8.11.' success ::API::V3::Deployments diff --git a/lib/api/v3/environments.rb b/lib/api/v3/environments.rb index 3056b70e6ef..6bb4e016a01 100644 --- a/lib/api/v3/environments.rb +++ b/lib/api/v3/environments.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all environments of the project' do detail 'This feature was introduced in GitLab 8.11.' success Entities::Environment diff --git a/lib/api/v3/files.rb b/lib/api/v3/files.rb index 4f8d58d37c8..13542b0c71c 100644 --- a/lib/api/v3/files.rb +++ b/lib/api/v3/files.rb @@ -40,7 +40,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a file from repository' params do requires :file_path, type: String, desc: 'The path to the file. Ex. lib/class.rb' diff --git a/lib/api/v3/groups.rb b/lib/api/v3/groups.rb index 0aad87a3f58..c5b37622d79 100644 --- a/lib/api/v3/groups.rb +++ b/lib/api/v3/groups.rb @@ -93,7 +93,7 @@ module API params do requires :id, type: String, desc: 'The ID of a group' end - resource :groups do + resource :groups, requirements: { id: %r{[^/]+} } do desc 'Update a group. Available only for users who can administrate groups.' do success Entities::Group end @@ -163,7 +163,7 @@ module API params do requires :project_id, type: String, desc: 'The ID or path of the project' end - post ":id/projects/:project_id" do + post ":id/projects/:project_id", requirements: { project_id: /.+/ } do authenticated_as_admin! group = find_group!(params[:id]) project = find_project!(params[:project_id]) diff --git a/lib/api/v3/issues.rb b/lib/api/v3/issues.rb index 258cbfed022..54c6a8060b8 100644 --- a/lib/api/v3/issues.rb +++ b/lib/api/v3/issues.rb @@ -68,7 +68,7 @@ module API params do requires :id, type: String, desc: 'The ID of a group' end - resource :groups do + resource :groups, requirements: { id: %r{[^/]+} } do desc 'Get a list of group issues' do success ::API::Entities::Issue end @@ -89,7 +89,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do include TimeTrackingEndpoints desc 'Get a list of project issues' do @@ -103,7 +103,7 @@ module API use :issues_params end get ":id/issues" do - project = find_project(params[:id]) + project = find_project!(params[:id]) issues = find_issues(project_id: project.id) diff --git a/lib/api/v3/labels.rb b/lib/api/v3/labels.rb index 41f45d244e3..bd5eb2175e8 100644 --- a/lib/api/v3/labels.rb +++ b/lib/api/v3/labels.rb @@ -6,7 +6,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all labels of the project' do success ::API::Entities::Label end diff --git a/lib/api/v3/members.rb b/lib/api/v3/members.rb index 3d4972afd9d..684860b553e 100644 --- a/lib/api/v3/members.rb +++ b/lib/api/v3/members.rb @@ -11,7 +11,7 @@ module API params do requires :id, type: String, desc: "The #{source_type} ID" end - resource source_type.pluralize do + resource source_type.pluralize, requirements: { id: %r{[^/]+} } do desc 'Gets a list of group or project members viewable by the authenticated user.' do success ::API::Entities::Member end diff --git a/lib/api/v3/merge_request_diffs.rb b/lib/api/v3/merge_request_diffs.rb index a462803e26c..35f462e907b 100644 --- a/lib/api/v3/merge_request_diffs.rb +++ b/lib/api/v3/merge_request_diffs.rb @@ -4,14 +4,16 @@ module API class MergeRequestDiffs < Grape::API before { authenticate! } - resource :projects do + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a list of merge request diff versions' do detail 'This feature was introduced in GitLab 8.12.' success ::API::Entities::MergeRequestDiff end params do - requires :id, type: String, desc: 'The ID of a project' requires :merge_request_id, type: Integer, desc: 'The ID of a merge request' end @@ -27,7 +29,6 @@ module API end params do - requires :id, type: String, desc: 'The ID of a project' requires :merge_request_id, type: Integer, desc: 'The ID of a merge request' requires :version_id, type: Integer, desc: 'The ID of a merge request diff version' end diff --git a/lib/api/v3/merge_requests.rb b/lib/api/v3/merge_requests.rb index 7dbd4691a94..3077240e650 100644 --- a/lib/api/v3/merge_requests.rb +++ b/lib/api/v3/merge_requests.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do include TimeTrackingEndpoints helpers do diff --git a/lib/api/v3/milestones.rb b/lib/api/v3/milestones.rb index 2a850a08a8a..be90cec4afc 100644 --- a/lib/api/v3/milestones.rb +++ b/lib/api/v3/milestones.rb @@ -18,7 +18,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a list of project milestones' do success ::API::Entities::Milestone end diff --git a/lib/api/v3/notes.rb b/lib/api/v3/notes.rb index 0796bb62e68..4f8e0eff4ff 100644 --- a/lib/api/v3/notes.rb +++ b/lib/api/v3/notes.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do NOTEABLE_TYPES.each do |noteable_type| noteables_str = noteable_type.to_s.underscore.pluralize diff --git a/lib/api/v3/pipelines.rb b/lib/api/v3/pipelines.rb index 2c26a5f7d35..82827249244 100644 --- a/lib/api/v3/pipelines.rb +++ b/lib/api/v3/pipelines.rb @@ -8,7 +8,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get all Pipelines of the project' do detail 'This feature was introduced in GitLab 8.11.' success ::API::Entities::Pipeline diff --git a/lib/api/v3/project_hooks.rb b/lib/api/v3/project_hooks.rb index 861b991b8e1..94614bfc8b6 100644 --- a/lib/api/v3/project_hooks.rb +++ b/lib/api/v3/project_hooks.rb @@ -25,7 +25,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get project hooks' do success ::API::V3::Entities::ProjectHook end diff --git a/lib/api/v3/project_snippets.rb b/lib/api/v3/project_snippets.rb index 809ca4f37ba..fc065a22d74 100644 --- a/lib/api/v3/project_snippets.rb +++ b/lib/api/v3/project_snippets.rb @@ -8,7 +8,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do helpers do def handle_project_member_errors(errors) if errors[:project_access].any? diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index 47bfc12035a..b753dbab381 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -234,7 +234,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: /[^\/]+/ } do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a single project' do success ::API::V3::Entities::ProjectWithAccess end diff --git a/lib/api/v3/repositories.rb b/lib/api/v3/repositories.rb index 44584e2eb70..e4d14bc8168 100644 --- a/lib/api/v3/repositories.rb +++ b/lib/api/v3/repositories.rb @@ -8,7 +8,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do helpers do def handle_project_member_errors(errors) if errors[:project_access].any? diff --git a/lib/api/v3/runners.rb b/lib/api/v3/runners.rb index 8967141fe3d..1934d6e578c 100644 --- a/lib/api/v3/runners.rb +++ b/lib/api/v3/runners.rb @@ -26,7 +26,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do before { authorize_admin_project } desc "Disable project's runner" do diff --git a/lib/api/v3/services.rb b/lib/api/v3/services.rb index d77185ffe5a..3bacaeee032 100644 --- a/lib/api/v3/services.rb +++ b/lib/api/v3/services.rb @@ -554,7 +554,10 @@ module API ] }.freeze - resource :projects do + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: { id: %r{[^/]+} } do before { authenticate! } before { authorize_admin_project } @@ -609,7 +612,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc "Trigger a slash command for #{service_slug}" do detail 'Added in GitLab 8.13' end diff --git a/lib/api/v3/subscriptions.rb b/lib/api/v3/subscriptions.rb index 02a4157c26e..068750ec077 100644 --- a/lib/api/v3/subscriptions.rb +++ b/lib/api/v3/subscriptions.rb @@ -14,7 +14,7 @@ module API requires :id, type: String, desc: 'The ID of a project' requires :subscribable_id, type: String, desc: 'The ID of a resource' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do subscribable_types.each do |type, finder| type_singularized = type.singularize entity_class = ::API::Entities.const_get(type_singularized.camelcase) diff --git a/lib/api/v3/tags.rb b/lib/api/v3/tags.rb index 6913720d9c5..c2541de2f50 100644 --- a/lib/api/v3/tags.rb +++ b/lib/api/v3/tags.rb @@ -6,7 +6,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get a project repository tags' do success ::API::Entities::RepoTag end diff --git a/lib/api/v3/todos.rb b/lib/api/v3/todos.rb index e60cb25e57b..e3b311d61cd 100644 --- a/lib/api/v3/todos.rb +++ b/lib/api/v3/todos.rb @@ -20,9 +20,9 @@ module API desc 'Mark all todos as done' delete do status(200) - + todos = TodosFinder.new(current_user, params).execute - TodoService.new.mark_todos_as_done(todos, current_user) + TodoService.new.mark_todos_as_done(todos, current_user).size end end end diff --git a/lib/api/v3/triggers.rb b/lib/api/v3/triggers.rb index 1dfdb6a5956..a23d6b6b48c 100644 --- a/lib/api/v3/triggers.rb +++ b/lib/api/v3/triggers.rb @@ -6,7 +6,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Trigger a GitLab project build' do success ::API::V3::Entities::TriggerRequest end @@ -15,7 +15,7 @@ module API requires :token, type: String, desc: 'The unique token of trigger' optional :variables, type: Hash, desc: 'The list of variables to be injected into build' end - post ":id/(ref/:ref/)trigger/builds" do + post ":id/(ref/:ref/)trigger/builds", requirements: { ref: /.+/ } do project = find_project(params[:id]) trigger = Ci::Trigger.find_by_token(params[:token].to_s) not_found! unless project && trigger diff --git a/lib/api/v3/variables.rb b/lib/api/v3/variables.rb index 0f55a14fb28..83972b1e7ce 100644 --- a/lib/api/v3/variables.rb +++ b/lib/api/v3/variables.rb @@ -10,7 +10,7 @@ module API requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Delete an existing variable from a project' do success ::API::Entities::Variable end diff --git a/lib/api/variables.rb b/lib/api/variables.rb index 77e5d54c225..5acde41551b 100644 --- a/lib/api/variables.rb +++ b/lib/api/variables.rb @@ -9,7 +9,7 @@ module API requires :id, type: String, desc: 'The ID of a project' end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do desc 'Get project variables' do success Entities::Variable end diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb index 02d5ad70fa7..8bc2dd18bda 100644 --- a/lib/banzai/filter/abstract_reference_filter.rb +++ b/lib/banzai/filter/abstract_reference_filter.rb @@ -239,18 +239,13 @@ module Banzai # path. def projects_per_reference @projects_per_reference ||= begin - hash = {} refs = Set.new references_per_project.each do |project_ref, _| refs << project_ref end - find_projects_for_paths(refs.to_a).each do |project| - hash[project.path_with_namespace] = project - end - - hash + find_projects_for_paths(refs.to_a).index_by(&:full_path) end end diff --git a/lib/banzai/filter/image_link_filter.rb b/lib/banzai/filter/image_link_filter.rb index 651b55523c0..123c92fd250 100644 --- a/lib/banzai/filter/image_link_filter.rb +++ b/lib/banzai/filter/image_link_filter.rb @@ -2,7 +2,6 @@ module Banzai module Filter # HTML filter that wraps links around inline images. class ImageLinkFilter < HTML::Pipeline::Filter - # Find every image that isn't already wrapped in an `a` tag, create # a new node (a link to the image source), copy the image as a child # of the anchor, and then replace the img with the link-wrapped version. @@ -12,7 +11,8 @@ module Banzai 'a', class: 'no-attachment-icon', href: img['src'], - target: '_blank' + target: '_blank', + rel: 'noopener noreferrer' ) link.children = img.clone diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb index a447e2b8bff..9f09ca90697 100644 --- a/lib/banzai/filter/syntax_highlight_filter.rb +++ b/lib/banzai/filter/syntax_highlight_filter.rb @@ -5,8 +5,6 @@ module Banzai # HTML Filter to highlight fenced code blocks # class SyntaxHighlightFilter < HTML::Pipeline::Filter - include Rouge::Plugins::Redcarpet - def call doc.search('pre > code').each do |node| highlight_node(node) @@ -23,7 +21,7 @@ module Banzai lang = lexer.tag begin - code = format(lex(lexer, code)) + code = Rouge::Formatters::HTMLGitlab.format(lex(lexer, code), tag: lang) css_classes << " js-syntax-highlight #{lang}" rescue @@ -45,10 +43,6 @@ module Banzai lexer.lex(code) end - def format(tokens) - rouge_formatter.format(tokens) - end - def lexer_for(language) (Rouge::Lexer.find(language) || Rouge::Lexers::PlainText).new end @@ -57,11 +51,6 @@ module Banzai # Replace the parent `pre` element with the entire highlighted block node.parent.replace(highlighted) end - - # Override Rouge::Plugins::Redcarpet#rouge_formatter - def rouge_formatter(lexer = nil) - @rouge_formatter ||= Rouge::Formatters::HTML.new - end end end end diff --git a/lib/banzai/filter/user_reference_filter.rb b/lib/banzai/filter/user_reference_filter.rb index 849e1142841..fe1f0923136 100644 --- a/lib/banzai/filter/user_reference_filter.rb +++ b/lib/banzai/filter/user_reference_filter.rb @@ -74,10 +74,7 @@ module Banzai # The keys of this Hash are the namespace paths, the values the # corresponding Namespace objects. def namespaces - @namespaces ||= - Namespace.where_full_path_in(usernames).each_with_object({}) do |row, hash| - hash[row.full_path] = row - end + @namespaces ||= Namespace.where_full_path_in(usernames).index_by(&:full_path) end # Returns all usernames referenced in the current document. diff --git a/lib/banzai/filter/video_link_filter.rb b/lib/banzai/filter/video_link_filter.rb index b64a1287d4d..35cb10eae5d 100644 --- a/lib/banzai/filter/video_link_filter.rb +++ b/lib/banzai/filter/video_link_filter.rb @@ -43,6 +43,7 @@ module Banzai element['title'] || element['alt'], href: element['src'], target: '_blank', + rel: 'noopener noreferrer', title: "Download '#{element['title'] || element['alt']}'") download_paragraph = doc.document.create_element('p') download_paragraph.children = link diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb index b25d6f18d59..fd4a6a107c2 100644 --- a/lib/banzai/pipeline/gfm_pipeline.rb +++ b/lib/banzai/pipeline/gfm_pipeline.rb @@ -2,10 +2,10 @@ module Banzai module Pipeline class GfmPipeline < BasePipeline # These filters convert GitLab Flavored Markdown (GFM) to HTML. - # The handlers defined in app/assets/javascripts/copy_as_gfm.js.es6 + # The handlers defined in app/assets/javascripts/copy_as_gfm.js # consequently convert that same HTML to GFM to be copied to the clipboard. # Every filter that generates HTML from GFM should have a handler in - # app/assets/javascripts/copy_as_gfm.js.es6, in reverse order. + # app/assets/javascripts/copy_as_gfm.js, in reverse order. # The GFM-to-HTML-to-GFM cycle is tested in spec/features/copy_as_gfm_spec.rb. def self.filters @filters ||= FilterArray[ diff --git a/lib/banzai/reference_parser/base_parser.rb b/lib/banzai/reference_parser/base_parser.rb index b121c37c5d0..52fdb9a2140 100644 --- a/lib/banzai/reference_parser/base_parser.rb +++ b/lib/banzai/reference_parser/base_parser.rb @@ -134,9 +134,7 @@ module Banzai ids = unique_attribute_values(nodes, attribute) rows = collection_objects_for_ids(collection, ids) - rows.each_with_object({}) do |row, hash| - hash[row.id] = row - end + rows.index_by(&:id) end # Returns an Array containing all unique values of an attribute of the diff --git a/lib/gitlab/conflict/parser.rb b/lib/gitlab/conflict/parser.rb index d3524c338ee..84f9ecd3d23 100644 --- a/lib/gitlab/conflict/parser.rb +++ b/lib/gitlab/conflict/parser.rb @@ -15,11 +15,9 @@ module Gitlab raise UnmergeableFile if text.blank? # Typically a binary file raise UnmergeableFile if text.length > 200.kilobytes - begin - text.to_json - rescue Encoding::UndefinedConversionError - raise UnsupportedEncoding - end + text.force_encoding('UTF-8') + + raise UnsupportedEncoding unless text.valid_encoding? line_obj_index = 0 line_old = 1 diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index f3f417c1a63..63b8d0d3b9d 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -5,8 +5,12 @@ module Gitlab # http://dev.mysql.com/doc/refman/5.7/en/integer-types.html MAX_INT_VALUE = 2147483647 + def self.config + ActiveRecord::Base.configurations[Rails.env] + end + def self.adapter_name - ActiveRecord::Base.configurations[Rails.env]['adapter'] + config['adapter'] end def self.mysql? diff --git a/lib/gitlab/emoji.rb b/lib/gitlab/emoji.rb index 35871fd1b7b..a16d9fc2265 100644 --- a/lib/gitlab/emoji.rb +++ b/lib/gitlab/emoji.rb @@ -44,27 +44,17 @@ module Gitlab end # CSS sprite fallback takes precedence over image fallback - def gl_emoji_tag(name, image: false, sprite: false, force_fallback: false) + def gl_emoji_tag(name) emoji_name = emojis_aliases[name] || name emoji_info = emojis[emoji_name] - emoji_fallback_image_source = ActionController::Base.helpers.url_to_image("emoji/#{emoji_info['name']}.png") - emoji_fallback_sprite_class = "emoji-#{emoji_name}" + return unless emoji_info data = { name: emoji_name, unicode_version: emoji_unicode_version(emoji_name) } - data[:fallback_src] = emoji_fallback_image_source if image - data[:fallback_sprite_class] = emoji_fallback_sprite_class if sprite - ActionController::Base.helpers.content_tag 'gl-emoji', - class: ("emoji-icon #{emoji_fallback_sprite_class}" if force_fallback && sprite), - data: data do - if force_fallback && !sprite - emoji_image_tag(emoji_name, emoji_fallback_image_source) - else - emoji_info['moji'] - end - end + + ActionController::Base.helpers.content_tag('gl-emoji', emoji_info['moji'], data: data) end end end diff --git a/lib/gitlab/git/diff.rb b/lib/gitlab/git/diff.rb index 2a017c93f57..019be151353 100644 --- a/lib/gitlab/git/diff.rb +++ b/lib/gitlab/git/diff.rb @@ -176,9 +176,13 @@ module Gitlab def initialize(raw_diff, collapse: false) case raw_diff when Hash - init_from_hash(raw_diff, collapse: collapse) + init_from_hash(raw_diff) + prune_diff_if_eligible(collapse) when Rugged::Patch, Rugged::Diff::Delta init_from_rugged(raw_diff, collapse: collapse) + when Gitaly::CommitDiffResponse + init_from_gitaly(raw_diff) + prune_diff_if_eligible(collapse) when nil raise "Nil as raw diff passed" else @@ -266,13 +270,26 @@ module Gitlab @diff = encode!(strip_diff_headers(patch.to_s)) end - def init_from_hash(hash, collapse: false) + def init_from_hash(hash) raw_diff = hash.symbolize_keys serialize_keys.each do |key| send(:"#{key}=", raw_diff[key.to_sym]) end + end + + def init_from_gitaly(diff_msg) + @diff = diff_msg.raw_chunks.join + @new_path = encode!(diff_msg.to_path.dup) + @old_path = encode!(diff_msg.from_path.dup) + @a_mode = diff_msg.old_mode.to_s(8) + @b_mode = diff_msg.new_mode.to_s(8) + @new_file = diff_msg.from_id == BLANK_SHA + @renamed_file = diff_msg.from_path != diff_msg.to_path + @deleted_file = diff_msg.to_id == BLANK_SHA + end + def prune_diff_if_eligible(collapse = false) prune_large_diff! if too_large? prune_collapsed_diff! if collapse && collapsible? end diff --git a/lib/gitlab/git/diff_collection.rb b/lib/gitlab/git/diff_collection.rb index 65e06f5065d..4e45ec7c174 100644 --- a/lib/gitlab/git/diff_collection.rb +++ b/lib/gitlab/git/diff_collection.rb @@ -30,7 +30,9 @@ module Gitlab elsif @deltas_only each_delta(&block) else - each_patch(&block) + Gitlab::GitalyClient.migrate(:commit_raw_diffs) do + each_patch(&block) + end end end diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index 228ef7bb7a9..2187dd70ff4 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -201,7 +201,7 @@ module Gitlab def archive_prefix(ref, sha) project_name = self.name.chomp('.git') - "#{project_name}-#{ref.parameterize}-#{sha}" + "#{project_name}-#{ref.tr('/', '-')}-#{sha}" end def archive_metadata(ref, storage_path, format = "tar.gz") diff --git a/lib/gitlab/git_ref_validator.rb b/lib/gitlab/git_ref_validator.rb index 4d83d8e72a8..0e87ee30c98 100644 --- a/lib/gitlab/git_ref_validator.rb +++ b/lib/gitlab/git_ref_validator.rb @@ -5,6 +5,9 @@ module Gitlab # # Returns true for a valid reference name, false otherwise def validate(ref_name) + return false if ref_name.start_with?('refs/heads/') + return false if ref_name.start_with?('refs/remotes/') + Gitlab::Utils.system_silent( %W(#{Gitlab.config.git.bin_path} check-ref-format refs/#{ref_name})) end diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb index b981a629fb0..5534d4af439 100644 --- a/lib/gitlab/gitaly_client.rb +++ b/lib/gitlab/gitaly_client.rb @@ -25,5 +25,19 @@ module Gitlab def self.enabled? gitaly_address.present? end + + def self.feature_enabled?(feature) + enabled? && ENV["GITALY_#{feature.upcase}"] == '1' + end + + def self.migrate(feature) + is_enabled = feature_enabled?(feature) + metric_name = feature.to_s + metric_name += "_gitaly" if is_enabled + + Gitlab::Metrics.measure(metric_name) do + yield is_enabled + end + end end end diff --git a/lib/gitlab/gitaly_client/commit.rb b/lib/gitlab/gitaly_client/commit.rb new file mode 100644 index 00000000000..525b8d680e9 --- /dev/null +++ b/lib/gitlab/gitaly_client/commit.rb @@ -0,0 +1,25 @@ +module Gitlab + module GitalyClient + class Commit + # The ID of empty tree. + # See http://stackoverflow.com/a/40884093/1856239 and https://github.com/git/git/blob/3ad8b5bf26362ac67c9020bf8c30eee54a84f56d/cache.h#L1011-L1012 + EMPTY_TREE_ID = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'.freeze + + class << self + def diff_from_parent(commit, options = {}) + stub = Gitaly::Diff::Stub.new(nil, nil, channel_override: GitalyClient.channel) + repo = Gitaly::Repository.new(path: commit.project.repository.path_to_repo) + parent = commit.parents[0] + parent_id = parent ? parent.id : EMPTY_TREE_ID + request = Gitaly::CommitDiffRequest.new( + repository: repo, + left_commit_id: parent_id, + right_commit_id: commit.id + ) + + Gitlab::Git::DiffCollection.new(stub.commit_diff(request), options) + end + end + end + end +end diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb index 9360afedfcb..d787d5db4a0 100644 --- a/lib/gitlab/highlight.rb +++ b/lib/gitlab/highlight.rb @@ -14,7 +14,7 @@ module Gitlab end def initialize(blob_name, blob_content, repository: nil) - @formatter = Rouge::Formatters::HTMLGitlab.new + @formatter = Rouge::Formatters::HTMLGitlab @repository = repository @blob_name = blob_name @blob_content = blob_content @@ -28,7 +28,7 @@ module Gitlab hl_lexer = self.lexer end - @formatter.format(hl_lexer.lex(text, continue: continue)).html_safe + @formatter.format(hl_lexer.lex(text, continue: continue), tag: hl_lexer.tag).html_safe rescue @formatter.format(Rouge::Lexers::PlainText.lex(text)).html_safe end diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index 416194e57d7..ab74c8782f6 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -73,6 +73,9 @@ excluded_attributes: - :milestone_id award_emoji: - :awardable_id + statuses: + - :trace + - :token methods: labels: @@ -81,6 +84,7 @@ methods: - :type statuses: - :type + - :gl_project_id services: - :type merge_request_diff: diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index fae792237d9..d44563333a5 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -15,7 +15,7 @@ module Gitlab USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id created_by_id merge_user_id resolved_by_id].freeze - PROJECT_REFERENCES = %w[project_id source_project_id gl_project_id target_project_id].freeze + PROJECT_REFERENCES = %w[project_id source_project_id target_project_id].freeze BUILD_MODELS = %w[Ci::Build commit_status].freeze @@ -98,12 +98,11 @@ module Gitlab end def generate_imported_object - if BUILD_MODELS.include?(@relation_name) # call #trace= method after assigning the other attributes - trace = @relation_hash.delete('trace') + if BUILD_MODELS.include?(@relation_name) + @relation_hash.delete('trace') # old export files have trace @relation_hash.delete('token') imported_object do |object| - object.trace = trace object.commit_id = nil end else @@ -121,7 +120,6 @@ module Gitlab # project_id may not be part of the export, but we always need to populate it if required. @relation_hash['project_id'] = project_id - @relation_hash['gl_project_id'] = project_id if @relation_hash['gl_project_id'] @relation_hash['target_project_id'] = project_id if @relation_hash['target_project_id'] end diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb index 62dbd429156..bc5370de32a 100644 --- a/lib/gitlab/redis.rb +++ b/lib/gitlab/redis.rb @@ -1,6 +1,7 @@ # This file should not have any direct dependency on Rails environment # please require all dependencies below: require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/module/delegation' module Gitlab class Redis @@ -9,7 +10,6 @@ module Gitlab SIDEKIQ_NAMESPACE = 'resque:gitlab'.freeze MAILROOM_NAMESPACE = 'mail_room:gitlab'.freeze DEFAULT_REDIS_URL = 'redis://localhost:6379'.freeze - CONFIG_FILE = File.expand_path('../../config/resque.yml', __dir__) class << self delegate :params, :url, to: :new @@ -33,13 +33,17 @@ module Gitlab return @_raw_config if defined?(@_raw_config) begin - @_raw_config = ERB.new(File.read(CONFIG_FILE)).result.freeze + @_raw_config = ERB.new(File.read(config_file)).result.freeze rescue Errno::ENOENT @_raw_config = false end @_raw_config end + + def config_file + ENV['GITLAB_REDIS_CONFIG_FILE'] || File.expand_path('../../config/resque.yml', __dir__) + end end def initialize(rails_env = nil) diff --git a/lib/gitlab/url_blocker.rb b/lib/gitlab/url_blocker.rb new file mode 100644 index 00000000000..7e14a566696 --- /dev/null +++ b/lib/gitlab/url_blocker.rb @@ -0,0 +1,59 @@ +require 'resolv' + +module Gitlab + class UrlBlocker + class << self + # Used to specify what hosts and port numbers should be prohibited for project + # imports. + VALID_PORTS = [22, 80, 443].freeze + + def blocked_url?(url) + return false if url.nil? + + blocked_ips = ["127.0.0.1", "::1", "0.0.0.0"] + blocked_ips.concat(Socket.ip_address_list.map(&:ip_address)) + + begin + uri = Addressable::URI.parse(url) + # Allow imports from the GitLab instance itself but only from the configured ports + return false if internal?(uri) + + return true if blocked_port?(uri.port) + + server_ips = Resolv.getaddresses(uri.hostname) + return true if (blocked_ips & server_ips).any? + rescue Addressable::URI::InvalidURIError + return true + end + + false + end + + private + + def blocked_port?(port) + return false if port.blank? + + port < 1024 && !VALID_PORTS.include?(port) + end + + def internal?(uri) + internal_web?(uri) || internal_shell?(uri) + end + + def internal_web?(uri) + uri.hostname == config.gitlab.host && + (uri.port.blank? || uri.port == config.gitlab.port) + end + + def internal_shell?(uri) + uri.hostname == config.gitlab_shell.ssh_host && + (uri.port.blank? || uri.port == config.gitlab_shell.ssh_port) + end + + def config + Gitlab.config + end + end + end +end diff --git a/lib/gitlab/url_sanitizer.rb b/lib/gitlab/url_sanitizer.rb index c81dc7e30d0..9ce13feb79a 100644 --- a/lib/gitlab/url_sanitizer.rb +++ b/lib/gitlab/url_sanitizer.rb @@ -18,6 +18,12 @@ module Gitlab false end + def self.http_credentials_for_user(user) + return {} unless user.respond_to?(:username) + + { user: user.username } + end + def initialize(url, credentials: nil) @url = Addressable::URI.parse(url.strip) @credentials = credentials diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb index 2248763c106..8f1d1fdc02e 100644 --- a/lib/gitlab/visibility_level.rb +++ b/lib/gitlab/visibility_level.rb @@ -96,8 +96,8 @@ module Gitlab end def level_value(level) - return string_options[level] if level.is_a? String - level + return level.to_i if level.to_i.to_s == level.to_s && string_options.key(level.to_i) + string_options[level] || PRIVATE end def string_level(level) diff --git a/lib/rouge/formatters/html_gitlab.rb b/lib/rouge/formatters/html_gitlab.rb index 4edfd015074..be0d97370d0 100644 --- a/lib/rouge/formatters/html_gitlab.rb +++ b/lib/rouge/formatters/html_gitlab.rb @@ -5,10 +5,10 @@ module Rouge # Creates a new <tt>Rouge::Formatter::HTMLGitlab</tt> instance. # - # [+linenostart+] The line number for the first line (default: 1). - def initialize(linenostart: 1) - @linenostart = linenostart - @line_number = linenostart + # [+tag+] The tag (language) of the lexer used to generate the formatted tokens + def initialize(tag: nil) + @line_number = 1 + @tag = tag end def stream(tokens, &b) @@ -17,7 +17,7 @@ module Rouge yield "\n" unless is_first is_first = false - yield %(<span id="LC#{@line_number}" class="line">) + yield %(<span id="LC#{@line_number}" class="line" lang="#{@tag}">) line.each { |token, value| yield span(token, value.chomp) } yield %(</span>) diff --git a/lib/support/init.d/gitlab.default.example b/lib/support/init.d/gitlab.default.example index e5797d8fe3c..f6642527639 100644 --- a/lib/support/init.d/gitlab.default.example +++ b/lib/support/init.d/gitlab.default.example @@ -56,14 +56,14 @@ gitlab_workhorse_log="$app_root/log/gitlab-workhorse.log" # The value of -listen-http must be set to `gitlab.yml > pages > external_http` # as well. For example: # -# -listen-http 1.1.1.1:80 +# -listen-http 1.1.1.1:80 -listen-http [2001::1]:80 # # To enable HTTPS support for custom domains add the `-listen-https`, # `-root-cert` and `-root-key` directives in `gitlab_pages_options` below. # The value of -listen-https must be set to `gitlab.yml > pages > external_https` # as well. For example: # -# -listen-https 1.1.1.1:443 -root-cert /path/to/example.com.crt -root-key /path/to/example.com.key +# -listen-https 1.1.1.1:443 -listen-http [2001::1]:443 -root-cert /path/to/example.com.crt -root-key /path/to/example.com.key # # The -pages-domain must be specified the same as in `gitlab.yml > pages > host`. # Set `gitlab_pages_enabled=true` if you want to enable the Pages feature. diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 2f7c34a3f31..f25e66d54c8 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -38,6 +38,13 @@ server { ## See app/controllers/application_controller.rb for headers set + ## Real IP Module Config + ## http://nginx.org/en/docs/http/ngx_http_realip_module.html + real_ip_header X-Real-IP; ## X-Real-IP or X-Forwarded-For or proxy_protocol + real_ip_recursive off; ## If you enable 'on' + ## If you have a trusted IP address, uncomment it and set it + # set_real_ip_from YOUR_TRUSTED_ADDRESS; ## Replace this with something like 192.168.1.0/24 + ## Individual nginx logs for this GitLab vhost access_log /var/log/nginx/gitlab_access.log; error_log /var/log/nginx/gitlab_error.log; diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 330031aaddc..2b40da18bab 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -85,6 +85,13 @@ server { ## [Optional] Enable HTTP Strict Transport Security # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; + ## Real IP Module Config + ## http://nginx.org/en/docs/http/ngx_http_realip_module.html + real_ip_header X-Real-IP; ## X-Real-IP or X-Forwarded-For or proxy_protocol + real_ip_recursive off; ## If you enable 'on' + ## If you have a trusted IP address, uncomment it and set it + # set_real_ip_from YOUR_TRUSTED_ADDRESS; ## Replace this with something like 192.168.1.0/24 + ## Individual nginx logs for this GitLab vhost access_log /var/log/nginx/gitlab_access.log; error_log /var/log/nginx/gitlab_error.log; diff --git a/lib/tasks/gitlab/dev.rake b/lib/tasks/gitlab/dev.rake index 7db0779def8..7ccda04a35f 100644 --- a/lib/tasks/gitlab/dev.rake +++ b/lib/tasks/gitlab/dev.rake @@ -4,7 +4,7 @@ namespace :gitlab do task :ee_compat_check, [:branch] => :environment do |_, args| opts = if ENV['CI'] - { branch: ENV['CI_BUILD_REF_NAME'] } + { branch: ENV['CI_COMMIT_REF_NAME'] } else unless args[:branch] puts "Must specify a branch as an argument".color(:red) diff --git a/lib/tasks/migrate/setup_postgresql.rake b/lib/tasks/migrate/setup_postgresql.rake index f5caca3ddbf..8938bc515f5 100644 --- a/lib/tasks/migrate/setup_postgresql.rake +++ b/lib/tasks/migrate/setup_postgresql.rake @@ -3,10 +3,12 @@ require Rails.root.join('lib/gitlab/database/migration_helpers') require Rails.root.join('db/migrate/20151007120511_namespaces_projects_path_lower_indexes') require Rails.root.join('db/migrate/20151008110232_add_users_lower_username_email_indexes') require Rails.root.join('db/migrate/20161212142807_add_lower_path_index_to_routes') +require Rails.root.join('db/migrate/20170317203554_index_routes_path_for_like') desc 'GitLab | Sets up PostgreSQL' task setup_postgresql: :environment do NamespacesProjectsPathLowerIndexes.new.up AddUsersLowerUsernameEmailIndexes.new.up AddLowerPathIndexToRoutes.new.up + IndexRoutesPathForLike.new.up end diff --git a/lib/tasks/tokens.rake b/lib/tasks/tokens.rake new file mode 100644 index 00000000000..95735f43802 --- /dev/null +++ b/lib/tasks/tokens.rake @@ -0,0 +1,38 @@ +require_relative '../../app/models/concerns/token_authenticatable.rb' + +namespace :tokens do + desc "Reset all GitLab user auth tokens" + task reset_all_auth: :environment do + reset_all_users_token(:reset_authentication_token!) + end + + desc "Reset all GitLab email tokens" + task reset_all_email: :environment do + reset_all_users_token(:reset_incoming_email_token!) + end + + def reset_all_users_token(reset_token_method) + TmpUser.find_in_batches do |batch| + puts "Processing batch starting with user ID: #{batch.first.id}" + STDOUT.flush + + batch.each(&reset_token_method) + end + end +end + +class TmpUser < ActiveRecord::Base + include TokenAuthenticatable + + self.table_name = 'users' + + def reset_authentication_token! + write_new_token(:authentication_token) + save!(validate: false) + end + + def reset_incoming_email_token! + write_new_token(:incoming_email_token) + save!(validate: false) + end +end |