summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2016-08-15 17:27:22 +0300
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2016-08-15 17:27:22 +0300
commit5e95c0b8d201a6bfdd020aa29a5a6e14c7085e3f (patch)
tree5e221b64c68dfbe5c6cb026b7ac92065104342f1 /app/controllers
parent94a7198ade54595d72797cab09db2c2a89172535 (diff)
parent6af598fc173bd0f7cd4237fa3e60d223103301a3 (diff)
downloadgitlab-ce-5e95c0b8d201a6bfdd020aa29a5a6e14c7085e3f.tar.gz
Merge branch 'master' into dz-merge-request-version
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/groups_controller.rb4
-rw-r--r--app/controllers/concerns/diff_for_path.rb6
-rw-r--r--app/controllers/dashboard/todos_controller.rb4
-rw-r--r--app/controllers/groups_controller.rb4
-rw-r--r--app/controllers/import/gitlab_projects_controller.rb7
-rw-r--r--app/controllers/profiles/passwords_controller.rb1
-rw-r--r--app/controllers/projects/badges_controller.rb3
-rw-r--r--app/controllers/projects/blob_controller.rb2
-rw-r--r--app/controllers/projects/branches_controller.rb3
-rw-r--r--app/controllers/projects/builds_controller.rb2
-rw-r--r--app/controllers/projects/commit_controller.rb6
-rw-r--r--app/controllers/projects/compare_controller.rb16
-rw-r--r--app/controllers/projects/deploy_keys_controller.rb20
-rw-r--r--app/controllers/projects/git_http_client_controller.rb110
-rw-r--r--app/controllers/projects/git_http_controller.rb142
-rw-r--r--app/controllers/projects/issues_controller.rb13
-rw-r--r--app/controllers/projects/lfs_api_controller.rb94
-rw-r--r--app/controllers/projects/lfs_storage_controller.rb92
-rw-r--r--app/controllers/projects/merge_requests_controller.rb17
-rw-r--r--app/controllers/projects/pipelines_controller.rb2
-rw-r--r--app/controllers/projects/pipelines_settings_controller.rb2
-rw-r--r--app/controllers/projects/wikis_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb4
-rw-r--r--app/controllers/registrations_controller.rb2
-rw-r--r--app/controllers/sessions_controller.rb2
25 files changed, 385 insertions, 175 deletions
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index f3a88a8e6c8..4ce18321649 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -48,9 +48,9 @@ class Admin::GroupsController < Admin::ApplicationController
end
def destroy
- DestroyGroupService.new(@group, current_user).execute
+ DestroyGroupService.new(@group, current_user).async_execute
- redirect_to admin_groups_path, notice: 'Group was successfully deleted.'
+ redirect_to admin_groups_path, alert: "Group '#{@group.name}' was scheduled for deletion."
end
private
diff --git a/app/controllers/concerns/diff_for_path.rb b/app/controllers/concerns/diff_for_path.rb
index 026d8b2e1e0..aeec3009f15 100644
--- a/app/controllers/concerns/diff_for_path.rb
+++ b/app/controllers/concerns/diff_for_path.rb
@@ -1,8 +1,8 @@
module DiffForPath
extend ActiveSupport::Concern
- def render_diff_for_path(diffs, diff_refs, project)
- diff_file = safe_diff_files(diffs, diff_refs: diff_refs, repository: project.repository).find do |diff|
+ def render_diff_for_path(diffs)
+ diff_file = diffs.diff_files.find do |diff|
diff.old_path == params[:old_path] && diff.new_path == params[:new_path]
end
@@ -14,7 +14,7 @@ module DiffForPath
locals = {
diff_file: diff_file,
diff_commit: diff_commit,
- diff_refs: diff_refs,
+ diff_refs: diffs.diff_refs,
blob: blob,
project: project
}
diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb
index 19a76a5b5d8..1243bb96d4d 100644
--- a/app/controllers/dashboard/todos_controller.rb
+++ b/app/controllers/dashboard/todos_controller.rb
@@ -37,8 +37,8 @@ class Dashboard::TodosController < Dashboard::ApplicationController
def todos_counts
{
- count: TodosFinder.new(current_user, state: :pending).execute.count,
- done_count: TodosFinder.new(current_user, state: :done).execute.count
+ count: current_user.todos_pending_count,
+ done_count: current_user.todos_done_count
}
end
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 6780a6d4d87..cb82d62616c 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -87,9 +87,9 @@ class GroupsController < Groups::ApplicationController
end
def destroy
- DestroyGroupService.new(@group, current_user).execute
+ DestroyGroupService.new(@group, current_user).async_execute
- redirect_to root_path, alert: "Group '#{@group.name}' was successfully deleted."
+ redirect_to root_path, alert: "Group '#{@group.name}' was scheduled for deletion."
end
protected
diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb
index 30df1fb2fec..3ec173abcdb 100644
--- a/app/controllers/import/gitlab_projects_controller.rb
+++ b/app/controllers/import/gitlab_projects_controller.rb
@@ -12,13 +12,14 @@ class Import::GitlabProjectsController < Import::BaseController
return redirect_back_or_default(options: { alert: "You need to upload a GitLab project export archive." })
end
- imported_file = project_params[:file].path + "-import"
+ import_upload_path = Gitlab::ImportExport.import_upload_path(filename: project_params[:file].original_filename)
- FileUtils.copy_entry(project_params[:file].path, imported_file)
+ FileUtils.mkdir_p(File.dirname(import_upload_path))
+ FileUtils.copy_entry(project_params[:file].path, import_upload_path)
@project = Gitlab::ImportExport::ProjectCreator.new(project_params[:namespace_id],
current_user,
- File.expand_path(imported_file),
+ import_upload_path,
project_params[:path]).execute
if @project.saved?
diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb
index c780e0983f9..6217ec5ecef 100644
--- a/app/controllers/profiles/passwords_controller.rb
+++ b/app/controllers/profiles/passwords_controller.rb
@@ -50,6 +50,7 @@ class Profiles::PasswordsController < Profiles::ApplicationController
flash[:notice] = "Password was successfully updated. Please login with it"
redirect_to new_user_session_path
else
+ @user.reload
render 'edit'
end
end
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index a9f482c8787..d0f5071d2cc 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -8,8 +8,9 @@ class Projects::BadgesController < Projects::ApplicationController
respond_to do |format|
format.html { render_404 }
+
format.svg do
- send_data(badge.data, type: badge.type, disposition: 'inline')
+ render 'badge', locals: { badge: badge.template }
end
end
end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index eda3727a28d..19d051720e9 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -76,6 +76,8 @@ class Projects::BlobController < Projects::ApplicationController
end
def diff
+ apply_diff_view_cookie!
+
@form = UnfoldForm.new(params)
@lines = Gitlab::Highlight.highlight_lines(repository, @ref, @path)
@lines = @lines[@form.since - 1..@form.to - 1]
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index e926043f3eb..48fe81b0d74 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -1,12 +1,13 @@
class Projects::BranchesController < Projects::ApplicationController
include ActionView::Helpers::SanitizeHelper
+ include SortingHelper
# Authorize
before_action :require_non_empty_project
before_action :authorize_download_code!
before_action :authorize_push_code!, only: [:new, :create, :destroy]
def index
- @sort = params[:sort].presence || 'name'
+ @sort = params[:sort].presence || sort_value_name
@branches = BranchesFinder.new(@repository, params).execute
@branches = Kaminari.paginate_array(@branches).page(params[:page])
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
index 553b62741a5..12195c3cbb8 100644
--- a/app/controllers/projects/builds_controller.rb
+++ b/app/controllers/projects/builds_controller.rb
@@ -6,7 +6,7 @@ class Projects::BuildsController < Projects::ApplicationController
def index
@scope = params[:scope]
- @all_builds = project.builds
+ @all_builds = project.builds.relevant
@builds = @all_builds.order('created_at DESC')
@builds =
case @scope
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 7ae034f9398..f44e9bb3fd7 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -28,7 +28,7 @@ class Projects::CommitController < Projects::ApplicationController
end
def diff_for_path
- render_diff_for_path(@diffs, @commit.diff_refs, @project)
+ render_diff_for_path(@commit.diffs(diff_options))
end
def builds
@@ -134,8 +134,8 @@ class Projects::CommitController < Projects::ApplicationController
end
def define_status_vars
- @statuses = CommitStatus.where(pipeline: pipelines)
- @builds = Ci::Build.where(pipeline: pipelines)
+ @statuses = CommitStatus.where(pipeline: pipelines).relevant
+ @builds = Ci::Build.where(pipeline: pipelines).relevant
end
def assign_change_commit_vars(mr_source_branch)
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 8c004724f02..bee3d56076c 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -21,7 +21,7 @@ class Projects::CompareController < Projects::ApplicationController
def diff_for_path
return render_404 unless @compare
- render_diff_for_path(@diffs, @diff_refs, @project)
+ render_diff_for_path(@compare.diffs(diff_options))
end
def create
@@ -40,18 +40,12 @@ class Projects::CompareController < Projects::ApplicationController
@compare = CompareService.new.execute(@project, @head_ref, @project, @start_ref)
if @compare
- @commits = Commit.decorate(@compare.commits, @project)
-
- @start_commit = @project.commit(@start_ref)
- @commit = @project.commit(@head_ref)
- @base_commit = @project.merge_base_commit(@start_ref, @head_ref)
+ @commits = @compare.commits
+ @start_commit = @compare.start_commit
+ @commit = @compare.commit
+ @base_commit = @compare.base_commit
@diffs = @compare.diffs(diff_options)
- @diff_refs = Gitlab::Diff::DiffRefs.new(
- base_sha: @base_commit.try(:sha),
- start_sha: @start_commit.try(:sha),
- head_sha: @commit.try(:sha)
- )
@diff_notes_disabled = true
@grouped_diff_discussions = {}
diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb
index 83d5ced9be8..529e0aa2d33 100644
--- a/app/controllers/projects/deploy_keys_controller.rb
+++ b/app/controllers/projects/deploy_keys_controller.rb
@@ -12,8 +12,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
end
def new
- redirect_to namespace_project_deploy_keys_path(@project.namespace,
- @project)
+ redirect_to namespace_project_deploy_keys_path(@project.namespace, @project)
end
def create
@@ -21,19 +20,16 @@ class Projects::DeployKeysController < Projects::ApplicationController
set_index_vars
if @key.valid? && @project.deploy_keys << @key
- redirect_to namespace_project_deploy_keys_path(@project.namespace,
- @project)
+ redirect_to namespace_project_deploy_keys_path(@project.namespace, @project)
else
render "index"
end
end
def enable
- @key = accessible_keys.find(params[:id])
- @project.deploy_keys << @key
+ Projects::EnableDeployKeyService.new(@project, current_user, params).execute
- redirect_to namespace_project_deploy_keys_path(@project.namespace,
- @project)
+ redirect_to namespace_project_deploy_keys_path(@project.namespace, @project)
end
def disable
@@ -45,9 +41,9 @@ class Projects::DeployKeysController < Projects::ApplicationController
protected
def set_index_vars
- @enabled_keys ||= @project.deploy_keys
+ @enabled_keys ||= @project.deploy_keys
- @available_keys ||= accessible_keys - @enabled_keys
+ @available_keys ||= current_user.accessible_deploy_keys - @enabled_keys
@available_project_keys ||= current_user.project_deploy_keys - @enabled_keys
@available_public_keys ||= DeployKey.are_public - @enabled_keys
@@ -56,10 +52,6 @@ class Projects::DeployKeysController < Projects::ApplicationController
@available_public_keys -= @available_project_keys
end
- def accessible_keys
- @accessible_keys ||= current_user.accessible_deploy_keys
- end
-
def deploy_key_params
params.require(:deploy_key).permit(:key, :title)
end
diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb
new file mode 100644
index 00000000000..7c21bd181dc
--- /dev/null
+++ b/app/controllers/projects/git_http_client_controller.rb
@@ -0,0 +1,110 @@
+# This file should be identical in GitLab Community Edition and Enterprise Edition
+
+class Projects::GitHttpClientController < Projects::ApplicationController
+ include ActionController::HttpAuthentication::Basic
+ include KerberosSpnegoHelper
+
+ attr_reader :user
+
+ # Git clients will not know what authenticity token to send along
+ skip_before_action :verify_authenticity_token
+ skip_before_action :repository
+ before_action :authenticate_user
+ before_action :ensure_project_found!
+
+ private
+
+ def authenticate_user
+ if project && project.public? && download_request?
+ return # Allow access
+ end
+
+ if allow_basic_auth? && basic_auth_provided?
+ login, password = user_name_and_password(request)
+ auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip)
+
+ if auth_result.type == :ci && download_request?
+ @ci = true
+ elsif auth_result.type == :oauth && !download_request?
+ # Not allowed
+ else
+ @user = auth_result.user
+ end
+
+ if ci? || user
+ return # Allow access
+ end
+ elsif allow_kerberos_spnego_auth? && spnego_provided?
+ @user = find_kerberos_user
+
+ if user
+ send_final_spnego_response
+ return # Allow access
+ end
+ end
+
+ send_challenges
+ render plain: "HTTP Basic: Access denied\n", status: 401
+ end
+
+ def basic_auth_provided?
+ has_basic_credentials?(request)
+ end
+
+ def send_challenges
+ challenges = []
+ challenges << 'Basic realm="GitLab"' if allow_basic_auth?
+ challenges << spnego_challenge if allow_kerberos_spnego_auth?
+ headers['Www-Authenticate'] = challenges.join("\n") if challenges.any?
+ end
+
+ def ensure_project_found!
+ render_not_found if project.blank?
+ end
+
+ def project
+ return @project if defined?(@project)
+
+ project_id, _ = project_id_with_suffix
+ if project_id.blank?
+ @project = nil
+ else
+ @project = Project.find_with_namespace("#{params[:namespace_id]}/#{project_id}")
+ end
+ end
+
+ # This method returns two values so that we can parse
+ # params[:project_id] (untrusted input!) in exactly one place.
+ def project_id_with_suffix
+ id = params[:project_id] || ''
+
+ %w[.wiki.git .git].each do |suffix|
+ if id.end_with?(suffix)
+ # Be careful to only remove the suffix from the end of 'id'.
+ # Accidentally removing it from the middle is how security
+ # vulnerabilities happen!
+ return [id.slice(0, id.length - suffix.length), suffix]
+ end
+ end
+
+ # Something is wrong with params[:project_id]; do not pass it on.
+ [nil, nil]
+ end
+
+ def repository
+ _, suffix = project_id_with_suffix
+ if suffix == '.wiki.git'
+ project.wiki.repository
+ else
+ project.repository
+ end
+ end
+
+ def render_not_found
+ render plain: 'Not Found', status: :not_found
+ end
+
+ def ci?
+ @ci.present?
+ end
+end
diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb
index 40a8b7940d9..b4373ef89ef 100644
--- a/app/controllers/projects/git_http_controller.rb
+++ b/app/controllers/projects/git_http_controller.rb
@@ -1,17 +1,6 @@
# This file should be identical in GitLab Community Edition and Enterprise Edition
-class Projects::GitHttpController < Projects::ApplicationController
- include ActionController::HttpAuthentication::Basic
- include KerberosSpnegoHelper
-
- attr_reader :user
-
- # Git clients will not know what authenticity token to send along
- skip_before_action :verify_authenticity_token
- skip_before_action :repository
- before_action :authenticate_user
- before_action :ensure_project_found!
-
+class Projects::GitHttpController < Projects::GitHttpClientController
# GET /foo/bar.git/info/refs?service=git-upload-pack (git pull)
# GET /foo/bar.git/info/refs?service=git-receive-pack (git push)
def info_refs
@@ -20,9 +9,9 @@ class Projects::GitHttpController < Projects::ApplicationController
elsif receive_pack? && receive_pack_allowed?
render_ok
elsif http_blocked?
- render_not_allowed
+ render_http_not_allowed
else
- render_not_found
+ render_denied
end
end
@@ -31,7 +20,7 @@ class Projects::GitHttpController < Projects::ApplicationController
if upload_pack? && upload_pack_allowed?
render_ok
else
- render_not_found
+ render_denied
end
end
@@ -40,87 +29,14 @@ class Projects::GitHttpController < Projects::ApplicationController
if receive_pack? && receive_pack_allowed?
render_ok
else
- render_not_found
+ render_denied
end
end
private
- def authenticate_user
- if project && project.public? && upload_pack?
- return # Allow access
- end
-
- if allow_basic_auth? && basic_auth_provided?
- login, password = user_name_and_password(request)
- auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip)
-
- if auth_result.type == :ci && upload_pack?
- @ci = true
- elsif auth_result.type == :oauth && !upload_pack?
- # Not allowed
- else
- @user = auth_result.user
- end
-
- if ci? || user
- return # Allow access
- end
- elsif allow_kerberos_spnego_auth? && spnego_provided?
- @user = find_kerberos_user
-
- if user
- send_final_spnego_response
- return # Allow access
- end
- end
-
- send_challenges
- render plain: "HTTP Basic: Access denied\n", status: 401
- end
-
- def basic_auth_provided?
- has_basic_credentials?(request)
- end
-
- def send_challenges
- challenges = []
- challenges << 'Basic realm="GitLab"' if allow_basic_auth?
- challenges << spnego_challenge if allow_kerberos_spnego_auth?
- headers['Www-Authenticate'] = challenges.join("\n") if challenges.any?
- end
-
- def ensure_project_found!
- render_not_found if project.blank?
- end
-
- def project
- return @project if defined?(@project)
-
- project_id, _ = project_id_with_suffix
- if project_id.blank?
- @project = nil
- else
- @project = Project.find_with_namespace("#{params[:namespace_id]}/#{project_id}")
- end
- end
-
- # This method returns two values so that we can parse
- # params[:project_id] (untrusted input!) in exactly one place.
- def project_id_with_suffix
- id = params[:project_id] || ''
-
- %w[.wiki.git .git].each do |suffix|
- if id.end_with?(suffix)
- # Be careful to only remove the suffix from the end of 'id'.
- # Accidentally removing it from the middle is how security
- # vulnerabilities happen!
- return [id.slice(0, id.length - suffix.length), suffix]
- end
- end
-
- # Something is wrong with params[:project_id]; do not pass it on.
- [nil, nil]
+ def download_request?
+ upload_pack?
end
def upload_pack?
@@ -143,47 +59,37 @@ class Projects::GitHttpController < Projects::ApplicationController
render json: Gitlab::Workhorse.git_http_ok(repository, user)
end
- def repository
- _, suffix = project_id_with_suffix
- if suffix == '.wiki.git'
- project.wiki.repository
- else
- project.repository
- end
- end
-
- def render_not_found
- render plain: 'Not Found', status: :not_found
+ def render_http_not_allowed
+ render plain: access_check.message, status: :forbidden
end
- def render_not_allowed
- render plain: download_access.message, status: :forbidden
- end
-
- def ci?
- @ci.present?
+ def render_denied
+ if user && user.can?(:read_project, project)
+ render plain: 'Access denied', status: :forbidden
+ else
+ # Do not leak information about project existence
+ render_not_found
+ end
end
def upload_pack_allowed?
return false unless Gitlab.config.gitlab_shell.upload_pack
if user
- download_access.allowed?
+ access_check.allowed?
else
ci? || project.public?
end
end
def access
- return @access if defined?(@access)
-
- @access = Gitlab::GitAccess.new(user, project, 'http')
+ @access ||= Gitlab::GitAccess.new(user, project, 'http')
end
- def download_access
- return @download_access if defined?(@download_access)
-
- @download_access = access.check('git-upload-pack')
+ def access_check
+ # Use the magic string '_any' to indicate we do not know what the
+ # changes are. This is also what gitlab-shell does.
+ @access_check ||= access.check(git_command, '_any')
end
def http_blocked?
@@ -193,8 +99,6 @@ class Projects::GitHttpController < Projects::ApplicationController
def receive_pack_allowed?
return false unless Gitlab.config.gitlab_shell.receive_pack
- # Skip user authorization on upload request.
- # It will be done by the pre-receive hook in the repository.
- user.present?
+ access_check.allowed?
end
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 7f5c3ff3d6a..660e0eba06f 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -5,6 +5,7 @@ class Projects::IssuesController < Projects::ApplicationController
include ToggleAwardEmoji
include IssuableCollections
+ before_action :redirect_to_external_issue_tracker, only: [:index, :new]
before_action :module_enabled
before_action :issue, only: [:edit, :update, :show, :referenced_merge_requests,
:related_branches, :can_create_branch]
@@ -201,6 +202,18 @@ class Projects::IssuesController < Projects::ApplicationController
return render_404 unless @project.issues_enabled && @project.default_issues_tracker?
end
+ def redirect_to_external_issue_tracker
+ external = @project.external_issue_tracker
+
+ return unless external
+
+ if action_name == 'new'
+ redirect_to external.new_issue_path
+ else
+ redirect_to external.issues_url
+ end
+ end
+
# Since iids are implemented only in 6.1
# user may navigate to issue page using old global ids.
#
diff --git a/app/controllers/projects/lfs_api_controller.rb b/app/controllers/projects/lfs_api_controller.rb
new file mode 100644
index 00000000000..ece49dcd922
--- /dev/null
+++ b/app/controllers/projects/lfs_api_controller.rb
@@ -0,0 +1,94 @@
+class Projects::LfsApiController < Projects::GitHttpClientController
+ include LfsHelper
+
+ before_action :require_lfs_enabled!
+ before_action :lfs_check_access!, except: [:deprecated]
+
+ def batch
+ unless objects.present?
+ render_lfs_not_found
+ return
+ end
+
+ if download_request?
+ render json: { objects: download_objects! }
+ elsif upload_request?
+ render json: { objects: upload_objects! }
+ else
+ raise "Never reached"
+ end
+ end
+
+ def deprecated
+ render(
+ json: {
+ message: 'Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.',
+ documentation_url: "#{Gitlab.config.gitlab.url}/help",
+ },
+ status: 501
+ )
+ end
+
+ private
+
+ def objects
+ @objects ||= (params[:objects] || []).to_a
+ end
+
+ def existing_oids
+ @existing_oids ||= begin
+ storage_project.lfs_objects.where(oid: objects.map { |o| o['oid'].to_s }).pluck(:oid)
+ end
+ end
+
+ def download_objects!
+ objects.each do |object|
+ if existing_oids.include?(object[:oid])
+ object[:actions] = download_actions(object)
+ else
+ object[:error] = {
+ code: 404,
+ message: "Object does not exist on the server or you don't have permissions to access it",
+ }
+ end
+ end
+ objects
+ end
+
+ def upload_objects!
+ objects.each do |object|
+ object[:actions] = upload_actions(object) unless existing_oids.include?(object[:oid])
+ end
+ objects
+ end
+
+ def download_actions(object)
+ {
+ download: {
+ href: "#{project.http_url_to_repo}/gitlab-lfs/objects/#{object[:oid]}",
+ header: {
+ Authorization: request.headers['Authorization']
+ }.compact
+ }
+ }
+ end
+
+ def upload_actions(object)
+ {
+ upload: {
+ href: "#{project.http_url_to_repo}/gitlab-lfs/objects/#{object[:oid]}/#{object[:size]}",
+ header: {
+ Authorization: request.headers['Authorization']
+ }.compact
+ }
+ }
+ end
+
+ def download_request?
+ params[:operation] == 'download'
+ end
+
+ def upload_request?
+ params[:operation] == 'upload'
+ end
+end
diff --git a/app/controllers/projects/lfs_storage_controller.rb b/app/controllers/projects/lfs_storage_controller.rb
new file mode 100644
index 00000000000..69066cb40e6
--- /dev/null
+++ b/app/controllers/projects/lfs_storage_controller.rb
@@ -0,0 +1,92 @@
+class Projects::LfsStorageController < Projects::GitHttpClientController
+ include LfsHelper
+
+ before_action :require_lfs_enabled!
+ before_action :lfs_check_access!
+
+ def download
+ lfs_object = LfsObject.find_by_oid(oid)
+ unless lfs_object && lfs_object.file.exists?
+ render_lfs_not_found
+ return
+ end
+
+ send_file lfs_object.file.path, content_type: "application/octet-stream"
+ end
+
+ def upload_authorize
+ render(
+ json: {
+ StoreLFSPath: "#{Gitlab.config.lfs.storage_path}/tmp/upload",
+ LfsOid: oid,
+ LfsSize: size,
+ },
+ content_type: 'application/json; charset=utf-8'
+ )
+ end
+
+ def upload_finalize
+ unless tmp_filename
+ render_lfs_forbidden
+ return
+ end
+
+ if store_file(oid, size, tmp_filename)
+ head 200
+ else
+ render plain: 'Unprocessable entity', status: 422
+ end
+ end
+
+ private
+
+ def download_request?
+ action_name == 'download'
+ end
+
+ def upload_request?
+ %w[upload_authorize upload_finalize].include? action_name
+ end
+
+ def oid
+ params[:oid].to_s
+ end
+
+ def size
+ params[:size].to_i
+ end
+
+ def tmp_filename
+ name = request.headers['X-Gitlab-Lfs-Tmp']
+ return if name.include?('/')
+ return unless oid.present? && name.start_with?(oid)
+ name
+ end
+
+ def store_file(oid, size, tmp_file)
+ # Define tmp_file_path early because we use it in "ensure"
+ tmp_file_path = File.join("#{Gitlab.config.lfs.storage_path}/tmp/upload", tmp_file)
+
+ object = LfsObject.find_or_create_by(oid: oid, size: size)
+ file_exists = object.file.exists? || move_tmp_file_to_storage(object, tmp_file_path)
+ file_exists && link_to_project(object)
+ ensure
+ FileUtils.rm_f(tmp_file_path)
+ end
+
+ def move_tmp_file_to_storage(object, path)
+ File.open(path) do |f|
+ object.file = f
+ end
+
+ object.file.store!
+ object.save
+ end
+
+ def link_to_project(object)
+ if object && !object.projects.exists?(storage_project.id)
+ object.projects << storage_project
+ object.save
+ end
+ end
+end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 33188e88385..a0b80c823fb 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -90,7 +90,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
respond_to do |format|
format.html { define_discussion_vars }
- format.json { render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") } }
+ format.json do
+ @diffs = @merge_request.diffs(diff_options)
+
+ render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") }
+ end
end
end
@@ -108,9 +112,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
define_commit_vars
- diffs = @merge_request.diffs(diff_options)
- render_diff_for_path(diffs, @merge_request.diff_refs, @merge_request.project)
+ render_diff_for_path(@merge_request.diffs(diff_options))
end
def commits
@@ -158,11 +161,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commits = @merge_request.compare_commits.reverse
@commit = @merge_request.diff_head_commit
@base_commit = @merge_request.diff_base_commit
- @diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare
+ @diffs = @merge_request.diffs(diff_options) if @merge_request.compare
@diff_notes_disabled = true
@pipeline = @merge_request.pipeline
- @statuses = @pipeline.statuses if @pipeline
+ @statuses = @pipeline.statuses.relevant if @pipeline
@note_counts = Note.where(commit_id: @commits.map(&:id)).
group(:commit_id).count
@@ -364,7 +367,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commits_count = @merge_request.commits.count
@pipeline = @merge_request.pipeline
- @statuses = @pipeline.statuses if @pipeline
+ @statuses = @pipeline.statuses.relevant if @pipeline
if @merge_request.locked_long_ago?
@merge_request.unlock_mr
@@ -383,6 +386,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
fresh.
discussions
+ preload_noteable_for_regular_notes(@discussions.flat_map(&:notes))
+
# This is not executed lazily
@notes = Banzai::NoteRenderer.render(
@discussions.flat_map(&:notes),
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 487963fdcd7..b0c72cfe4b4 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -19,7 +19,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def create
- @pipeline = Ci::CreatePipelineService.new(project, current_user, create_params).execute
+ @pipeline = Ci::CreatePipelineService.new(project, current_user, create_params).execute(ignore_skip_ci: true, save_on_errors: false)
unless @pipeline.persisted?
render 'new'
return
diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb
index 85ba706e5cd..75dd3648e45 100644
--- a/app/controllers/projects/pipelines_settings_controller.rb
+++ b/app/controllers/projects/pipelines_settings_controller.rb
@@ -3,7 +3,7 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController
def show
@ref = params[:ref] || @project.default_branch || 'master'
- @build_badge = Gitlab::Badge::Build.new(@project, @ref)
+ @build_badge = Gitlab::Badge::Build.new(@project, @ref).metadata
end
def update
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index 607fe9c7fed..177ccf5eec9 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -91,7 +91,7 @@ class Projects::WikisController < Projects::ApplicationController
)
end
- def markdown_preview
+ def preview_markdown
text = params[:text]
ext = Gitlab::ReferenceExtractor.new(@project, current_user)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index a6e1aa5ccc1..47efbd4a939 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -125,7 +125,7 @@ class ProjectsController < Projects::ApplicationController
def destroy
return access_denied! unless can?(current_user, :remove_project, @project)
- ::Projects::DestroyService.new(@project, current_user, {}).pending_delete!
+ ::Projects::DestroyService.new(@project, current_user, {}).async_execute
flash[:alert] = "Project '#{@project.name}' will be deleted."
redirect_to dashboard_projects_path
@@ -238,7 +238,7 @@ class ProjectsController < Projects::ApplicationController
}
end
- def markdown_preview
+ def preview_markdown
text = params[:text]
ext = Gitlab::ReferenceExtractor.new(@project, current_user)
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 75b78a49eab..3327f4f2b87 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -33,7 +33,7 @@ class RegistrationsController < Devise::RegistrationsController
protected
- def build_resource(hash=nil)
+ def build_resource(hash = nil)
super
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 17aed816cbd..5d7ecfeacf4 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -101,7 +101,7 @@ class SessionsController < Devise::SessionsController
# Prevent alert from popping up on the first page shown after authentication.
flash[:alert] = nil
- redirect_to user_omniauth_authorize_path(provider.to_sym)
+ redirect_to omniauth_authorize_path(:user, provider)
end
def valid_otp_attempt?(user)