summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/appearances_controller.rb1
-rw-r--r--app/controllers/admin/application_settings_controller.rb3
-rw-r--r--app/controllers/admin/builds_controller.rb4
-rw-r--r--app/controllers/admin/groups_controller.rb1
-rw-r--r--app/controllers/admin/hooks_controller.rb1
-rw-r--r--app/controllers/admin/projects_controller.rb8
-rw-r--r--app/controllers/admin/runner_projects_controller.rb9
-rw-r--r--app/controllers/admin/system_info_controller.rb59
-rw-r--r--app/controllers/application_controller.rb8
-rw-r--r--app/controllers/ci/projects_controller.rb2
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb10
-rw-r--r--app/controllers/concerns/creates_commit.rb3
-rw-r--r--app/controllers/concerns/diff_for_path.rb24
-rw-r--r--app/controllers/concerns/membership_actions.rb36
-rw-r--r--app/controllers/confirmations_controller.rb1
-rw-r--r--app/controllers/dashboard/groups_controller.rb2
-rw-r--r--app/controllers/dashboard/todos_controller.rb13
-rw-r--r--app/controllers/groups/group_members_controller.rb14
-rw-r--r--app/controllers/groups_controller.rb23
-rw-r--r--app/controllers/help_controller.rb10
-rw-r--r--app/controllers/import/base_controller.rb1
-rw-r--r--app/controllers/import/fogbugz_controller.rb2
-rw-r--r--app/controllers/import/github_controller.rb25
-rw-r--r--app/controllers/import/gitlab_projects_controller.rb11
-rw-r--r--app/controllers/import/gitorious_controller.rb1
-rw-r--r--app/controllers/import/google_code_controller.rb2
-rw-r--r--app/controllers/invites_controller.rb1
-rw-r--r--app/controllers/notification_settings_controller.rb22
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb6
-rw-r--r--app/controllers/profiles/two_factor_auths_controller.rb3
-rw-r--r--app/controllers/projects/application_controller.rb2
-rw-r--r--app/controllers/projects/artifacts_controller.rb5
-rw-r--r--app/controllers/projects/blob_controller.rb15
-rw-r--r--app/controllers/projects/builds_controller.rb17
-rw-r--r--app/controllers/projects/commit_controller.rb43
-rw-r--r--app/controllers/projects/compare_controller.rb48
-rw-r--r--app/controllers/projects/git_http_controller.rb63
-rw-r--r--app/controllers/projects/issues_controller.rb9
-rw-r--r--app/controllers/projects/merge_requests_controller.rb177
-rw-r--r--app/controllers/projects/network_controller.rb1
-rw-r--r--app/controllers/projects/notes_controller.rb31
-rw-r--r--app/controllers/projects/pipelines_controller.rb2
-rw-r--r--app/controllers/projects/project_members_controller.rb17
-rw-r--r--app/controllers/projects/protected_branches_controller.rb28
-rw-r--r--app/controllers/projects/runner_projects_controller.rb5
-rw-r--r--app/controllers/projects/runners_controller.rb7
-rw-r--r--app/controllers/projects/services_controller.rb3
-rw-r--r--app/controllers/projects/snippets_controller.rb2
-rw-r--r--app/controllers/projects/todos_controller.rb2
-rw-r--r--app/controllers/projects/wikis_controller.rb1
-rw-r--r--app/controllers/projects_controller.rb39
51 files changed, 589 insertions, 234 deletions
diff --git a/app/controllers/admin/appearances_controller.rb b/app/controllers/admin/appearances_controller.rb
index 26cf74e4849..4b0ec54b3f4 100644
--- a/app/controllers/admin/appearances_controller.rb
+++ b/app/controllers/admin/appearances_controller.rb
@@ -5,6 +5,7 @@ class Admin::AppearancesController < Admin::ApplicationController
end
def preview
+ render 'preview', layout: 'devise'
end
def create
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index f4eda864aac..23ba83aba0e 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -87,6 +87,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:version_check_enabled,
:admin_notification_email,
:user_oauth_applications,
+ :user_default_external,
:shared_runners_enabled,
:shared_runners_text,
:max_artifacts_size,
@@ -109,6 +110,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_packet_size,
:send_user_confirmation_email,
:container_registry_token_expire_delay,
+ :repository_storage,
+ :enabled_git_access_protocol,
restricted_visibility_levels: [],
import_sources: [],
disabled_oauth_sign_in_sources: []
diff --git a/app/controllers/admin/builds_controller.rb b/app/controllers/admin/builds_controller.rb
index 0db91eaaf2e..88f3c0e2fd4 100644
--- a/app/controllers/admin/builds_controller.rb
+++ b/app/controllers/admin/builds_controller.rb
@@ -5,8 +5,10 @@ class Admin::BuildsController < Admin::ApplicationController
@builds = @all_builds.order('created_at DESC')
@builds =
case @scope
+ when 'pending'
+ @builds.pending.reverse_order
when 'running'
- @builds.running_or_pending.reverse_order
+ @builds.running.reverse_order
when 'finished'
@builds.finished
else
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index a6db4690df0..94b5aaa71d0 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -10,6 +10,7 @@ class Admin::GroupsController < Admin::ApplicationController
def show
@members = @group.members.order("access_level DESC").page(params[:members_page])
+ @requesters = @group.requesters
@projects = @group.projects.page(params[:projects_page])
end
diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb
index 4e85b6b4cf2..cbfc4581411 100644
--- a/app/controllers/admin/hooks_controller.rb
+++ b/app/controllers/admin/hooks_controller.rb
@@ -22,7 +22,6 @@ class Admin::HooksController < Admin::ApplicationController
redirect_to admin_hooks_path
end
-
def test
@hook = SystemHook.find(params[:hook_id])
data = {
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 87986fdf8b1..0d2f4f6eb38 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -5,11 +5,12 @@ class Admin::ProjectsController < Admin::ApplicationController
def index
@projects = Project.all
@projects = @projects.in_namespace(params[:namespace_id]) if params[:namespace_id].present?
- @projects = @projects.where("projects.visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present?
+ @projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present?
@projects = @projects.with_push if params[:with_push].present?
@projects = @projects.abandoned if params[:abandoned].present?
@projects = @projects.where(last_repository_check_failed: true) if params[:last_repository_check_failed].present?
- @projects = @projects.non_archived unless params[:with_archived].present?
+ @projects = @projects.non_archived unless params[:archived].present?
+ @projects = @projects.personal(current_user) if params[:personal].present?
@projects = @projects.search(params[:name]) if params[:name].present?
@projects = @projects.sort(@sort = params[:sort])
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page])
@@ -20,7 +21,8 @@ class Admin::ProjectsController < Admin::ApplicationController
@group_members = @group.members.order("access_level DESC").page(params[:group_members_page])
end
- @project_members = @project.project_members.page(params[:project_members_page])
+ @project_members = @project.members.page(params[:project_members_page])
+ @requesters = @project.requesters
end
def transfer
diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb
index d25619d94e0..bc65dcc33d3 100644
--- a/app/controllers/admin/runner_projects_controller.rb
+++ b/app/controllers/admin/runner_projects_controller.rb
@@ -1,15 +1,12 @@
class Admin::RunnerProjectsController < Admin::ApplicationController
before_action :project, only: [:create]
- def index
- @runner_projects = project.runner_projects.all
- @runner_project = project.runner_projects.new
- end
-
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
- if @runner.assign_to(@project, current_user)
+ runner_project = @runner.assign_to(@project, current_user)
+
+ if runner_project.persisted?
redirect_to admin_runner_path(@runner)
else
redirect_to admin_runner_path(@runner), alert: 'Failed adding runner to project'
diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb
new file mode 100644
index 00000000000..e4c73008826
--- /dev/null
+++ b/app/controllers/admin/system_info_controller.rb
@@ -0,0 +1,59 @@
+class Admin::SystemInfoController < Admin::ApplicationController
+ EXCLUDED_MOUNT_OPTIONS = [
+ 'nobrowse',
+ 'read-only',
+ 'ro'
+ ]
+
+ EXCLUDED_MOUNT_TYPES = [
+ 'autofs',
+ 'binfmt_misc',
+ 'cgroup',
+ 'debugfs',
+ 'devfs',
+ 'devpts',
+ 'devtmpfs',
+ 'efivarfs',
+ 'fuse.gvfsd-fuse',
+ 'fuseblk',
+ 'fusectl',
+ 'hugetlbfs',
+ 'mqueue',
+ 'proc',
+ 'pstore',
+ 'securityfs',
+ 'sysfs',
+ 'tmpfs',
+ 'tracefs',
+ 'vfat'
+ ]
+
+ def show
+ system_info = Vmstat.snapshot
+ mounts = Sys::Filesystem.mounts
+
+ @disks = []
+ mounts.each do |mount|
+ mount_options = mount.options.split(',')
+
+ next if (EXCLUDED_MOUNT_OPTIONS & mount_options).any?
+ next if (EXCLUDED_MOUNT_TYPES & [mount.mount_type]).any?
+
+ begin
+ disk = Sys::Filesystem.stat(mount.mount_point)
+ @disks.push({
+ bytes_total: disk.bytes_total,
+ bytes_used: disk.bytes_used,
+ disk_name: mount.name,
+ mount_path: disk.path
+ })
+ rescue Sys::Filesystem::Error
+ end
+ end
+
+ @cpus = system_info.cpus.length
+
+ @mem_used = system_info.memory.active_bytes
+ @mem_total = system_info.memory.total_bytes
+ end
+end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index dd1bc6f5d52..a1004d9bcea 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -36,6 +36,10 @@ class ApplicationController < ActionController::Base
render_404
end
+ rescue_from Gitlab::Access::AccessDeniedError do |exception|
+ render_403
+ end
+
def redirect_back_or_default(default: root_path, options: {})
redirect_to request.referer.present? ? :back : default, options
end
@@ -340,10 +344,6 @@ class ApplicationController < ActionController::Base
session[:skip_tfa] && session[:skip_tfa] > Time.current
end
- def browser_supports_u2f?
- browser.chrome? && browser.version.to_i >= 41 && !browser.device.mobile?
- end
-
def redirect_to_home_page_url?
# If user is not signed-in and tries to access root_path - redirect him to landing page
# Don't redirect to the default URL to prevent endless redirections
diff --git a/app/controllers/ci/projects_controller.rb b/app/controllers/ci/projects_controller.rb
index 8bf71a1adbb..aa894fde36b 100644
--- a/app/controllers/ci/projects_controller.rb
+++ b/app/controllers/ci/projects_controller.rb
@@ -25,7 +25,7 @@ module Ci
return render_404 unless @project
image = Ci::ImageForBuildService.new.execute(@project, params)
- send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml"
+ send_file image.path, filename: image.name, disposition: 'inline', type: "image/svg+xml"
end
protected
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb
index 998b8adc411..ba07cea569c 100644
--- a/app/controllers/concerns/authenticates_with_two_factor.rb
+++ b/app/controllers/concerns/authenticates_with_two_factor.rb
@@ -57,7 +57,7 @@ module AuthenticatesWithTwoFactor
# Authenticate using the response from a U2F (universal 2nd factor) device
def authenticate_with_two_factor_via_u2f(user)
- if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenges])
+ if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenge])
# Remove any lingering user data from login
session.delete(:otp_user_id)
session.delete(:challenges)
@@ -77,11 +77,9 @@ module AuthenticatesWithTwoFactor
if key_handles.present?
sign_requests = u2f.authentication_requests(key_handles)
- challenges = sign_requests.map(&:challenge)
- session[:challenges] = challenges
- gon.push(u2f: { challenges: challenges, app_id: u2f_app_id,
- sign_requests: sign_requests,
- browser_supports_u2f: browser_supports_u2f? })
+ session[:challenge] ||= u2f.challenge
+ gon.push(u2f: { challenge: session[:challenge], app_id: u2f_app_id,
+ sign_requests: sign_requests })
end
end
end
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb
index dacb5679dd3..f2b8f297bc2 100644
--- a/app/controllers/concerns/creates_commit.rb
+++ b/app/controllers/concerns/creates_commit.rb
@@ -7,7 +7,8 @@ module CreatesCommit
commit_params = @commit_params.merge(
source_project: @project,
source_branch: @ref,
- target_branch: @target_branch
+ target_branch: @target_branch,
+ previous_path: @previous_path
)
result = service.new(@tree_edit_project, current_user, commit_params).execute
diff --git a/app/controllers/concerns/diff_for_path.rb b/app/controllers/concerns/diff_for_path.rb
new file mode 100644
index 00000000000..026d8b2e1e0
--- /dev/null
+++ b/app/controllers/concerns/diff_for_path.rb
@@ -0,0 +1,24 @@
+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|
+ diff.old_path == params[:old_path] && diff.new_path == params[:new_path]
+ end
+
+ return render_404 unless diff_file
+
+ diff_commit = commit_for_diff(diff_file)
+ blob = diff_file.blob(diff_commit)
+
+ locals = {
+ diff_file: diff_file,
+ diff_commit: diff_commit,
+ diff_refs: diff_refs,
+ blob: blob,
+ project: project
+ }
+
+ render json: { html: view_to_html_string('projects/diffs/_content', locals) }
+ end
+end
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index a24273fad0b..52682ef9dc9 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -10,7 +10,7 @@ module MembershipActions
end
def approve_access_request
- @member = membershipable.members.request.find(params[:id])
+ @member = membershipable.requesters.find(params[:id])
return render_403 unless can?(current_user, action_member_permission(:update, @member), @member)
@@ -20,30 +20,20 @@ module MembershipActions
end
def leave
- @member = membershipable.members.find_by(user_id: current_user)
- return render_403 unless @member
+ @member = membershipable.members.find_by(user_id: current_user) ||
+ membershipable.requesters.find_by(user_id: current_user)
+ Members::DestroyService.new(@member, current_user).execute
source_type = @member.real_source_type.humanize(capitalize: false)
-
- if can?(current_user, action_member_permission(:destroy, @member), @member)
- notice =
- if @member.request?
- "Your access request to the #{source_type} has been withdrawn."
- else
- "You left the \"#{@member.source.human_name}\" #{source_type}."
- end
- @member.destroy
-
- redirect_to [:dashboard, @member.real_source_type.tableize], notice: notice
- else
- if cannot_leave?
- alert = "You can not leave the \"#{@member.source.human_name}\" #{source_type}."
- alert << " Transfer or delete the #{source_type}."
- redirect_to polymorphic_url(membershipable), alert: alert
+ notice =
+ if @member.request?
+ "Your access request to the #{source_type} has been withdrawn."
else
- render_403
+ "You left the \"#{@member.source.human_name}\" #{source_type}."
end
- end
+ redirect_path = @member.request? ? @member.source : [:dashboard, @member.real_source_type.tableize]
+
+ redirect_to redirect_path, notice: notice
end
protected
@@ -51,8 +41,4 @@ module MembershipActions
def membershipable
raise NotImplementedError
end
-
- def cannot_leave?
- raise NotImplementedError
- end
end
diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb
index 7b66ad3f92c..3da44b9b888 100644
--- a/app/controllers/confirmations_controller.rb
+++ b/app/controllers/confirmations_controller.rb
@@ -1,5 +1,4 @@
class ConfirmationsController < Devise::ConfirmationsController
-
def almost_there
flash[:notice] = nil
render layout: "devise_empty"
diff --git a/app/controllers/dashboard/groups_controller.rb b/app/controllers/dashboard/groups_controller.rb
index 71ba6153021..de6bc689bb7 100644
--- a/app/controllers/dashboard/groups_controller.rb
+++ b/app/controllers/dashboard/groups_controller.rb
@@ -1,5 +1,5 @@
class Dashboard::GroupsController < Dashboard::ApplicationController
def index
- @group_members = current_user.group_members.page(params[:page])
+ @group_members = current_user.group_members.includes(:source).page(params[:page])
end
end
diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb
index 3a2db3e6eeb..19a76a5b5d8 100644
--- a/app/controllers/dashboard/todos_controller.rb
+++ b/app/controllers/dashboard/todos_controller.rb
@@ -1,6 +1,4 @@
class Dashboard::TodosController < Dashboard::ApplicationController
- include TodosHelper
-
before_action :find_todos, only: [:index, :destroy_all]
def index
@@ -13,7 +11,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' }
format.js { head :ok }
- format.json { render json: { count: todos_pending_count, done_count: todos_done_count } }
+ format.json { render json: todos_counts }
end
end
@@ -23,7 +21,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' }
format.js { head :ok }
- format.json { render json: { count: todos_pending_count, done_count: todos_done_count } }
+ format.json { render json: todos_counts }
end
end
@@ -36,4 +34,11 @@ class Dashboard::TodosController < Dashboard::ApplicationController
def find_todos
@todos ||= TodosFinder.new(current_user, params).execute
end
+
+ def todos_counts
+ {
+ count: TodosFinder.new(current_user, state: :pending).execute.count,
+ done_count: TodosFinder.new(current_user, state: :done).execute.count
+ }
+ end
end
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index d0f2e2949f0..9fc41a12536 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -7,7 +7,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
def index
@project = @group.projects.find(params[:project_id]) if params[:project_id]
@members = @group.group_members
- @members = @members.non_pending unless can?(current_user, :admin_group, @group)
+ @members = @members.non_invite unless can?(current_user, :admin_group, @group)
if params[:search].present?
users = @group.users.search(params[:search]).to_a
@@ -15,6 +15,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
@members = @members.order('access_level DESC').page(params[:page]).per(50)
+ @requesters = @group.requesters if can?(current_user, :admin_group, @group)
@group_member = @group.group_members.new
end
@@ -34,11 +35,10 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
def destroy
- @group_member = @group.group_members.find(params[:id])
-
- return render_403 unless can?(current_user, :destroy_group_member, @group_member)
+ @group_member = @group.members.find_by(id: params[:id]) ||
+ @group.requesters.find_by(id: params[:id])
- @group_member.destroy
+ Members::DestroyService.new(@group_member, current_user).execute
respond_to do |format|
format.html { redirect_to group_group_members_path(@group), notice: 'User was successfully removed from group.' }
@@ -68,8 +68,4 @@ class Groups::GroupMembersController < Groups::ApplicationController
# MembershipActions concern
alias_method :membershipable, :group
-
- def cannot_leave?
- @group.last_owner?(current_user)
- end
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index ee4fcc4e360..a04bf7df722 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -37,15 +37,12 @@ class GroupsController < Groups::ApplicationController
end
def show
- @last_push = current_user.recent_push if current_user
-
- @projects = @projects.includes(:namespace)
- @projects = @projects.sorted_by_activity
- @projects = filter_projects(@projects)
- @projects = @projects.sort(@sort = params[:sort])
- @projects = @projects.page(params[:page]) if params[:filter_projects].blank?
+ if current_user
+ @last_push = current_user.recent_push
+ @notification_setting = current_user.notification_settings_for(group)
+ end
- @shared_projects = GroupProjectsFinder.new(group, only_shared: true).execute(current_user)
+ setup_projects
respond_to do |format|
format.html
@@ -97,6 +94,16 @@ class GroupsController < Groups::ApplicationController
protected
+ def setup_projects
+ @projects = @projects.includes(:namespace)
+ @projects = @projects.sorted_by_activity
+ @projects = filter_projects(@projects)
+ @projects = @projects.sort(@sort = params[:sort])
+ @projects = @projects.page(params[:page]) if params[:filter_projects].blank?
+
+ @shared_projects = GroupProjectsFinder.new(group, only_shared: true).execute(current_user)
+ end
+
def authorize_create_group!
unless can?(current_user, :create_group, nil)
return render_404
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index 9b5c43b17e2..d3dd98c8a4e 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -12,13 +12,12 @@ class HelpController < ApplicationController
end
def show
- @category = clean_path_info(path_params[:category])
- @file = path_params[:file]
+ @path = clean_path_info(path_params[:path])
respond_to do |format|
format.any(:markdown, :md, :html) do
# Note: We are purposefully NOT using `Rails.root.join`
- path = File.join(Rails.root, 'doc', @category, "#{@file}.md")
+ path = File.join(Rails.root, 'doc', "#{@path}.md")
if File.exist?(path)
@markdown = File.read(path)
@@ -33,7 +32,7 @@ class HelpController < ApplicationController
# Allow access to images in the doc folder
format.any(:png, :gif, :jpeg) do
# Note: We are purposefully NOT using `Rails.root.join`
- path = File.join(Rails.root, 'doc', @category, "#{@file}.#{params[:format]}")
+ path = File.join(Rails.root, 'doc', "#{@path}.#{params[:format]}")
if File.exist?(path)
send_file(path, disposition: 'inline')
@@ -57,8 +56,7 @@ class HelpController < ApplicationController
private
def path_params
- params.require(:category)
- params.require(:file)
+ params.require(:path)
params
end
diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb
index 93a7ace3530..7e8597a5eb3 100644
--- a/app/controllers/import/base_controller.rb
+++ b/app/controllers/import/base_controller.rb
@@ -1,5 +1,4 @@
class Import::BaseController < ApplicationController
-
private
def get_or_create_namespace
diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb
index 18300390851..99b10b2f9b3 100644
--- a/app/controllers/import/fogbugz_controller.rb
+++ b/app/controllers/import/fogbugz_controller.rb
@@ -5,7 +5,6 @@ class Import::FogbugzController < Import::BaseController
rescue_from Fogbugz::AuthenticationException, with: :fogbugz_unauthorized
def new
-
end
def callback
@@ -22,7 +21,6 @@ class Import::FogbugzController < Import::BaseController
end
def new_user_map
-
end
def create_user_map
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index 67bf4190e7e..9c1b0eb20f4 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -1,14 +1,29 @@
class Import::GithubController < Import::BaseController
before_action :verify_github_import_enabled
- before_action :github_auth, except: :callback
+ before_action :github_auth, only: [:status, :jobs, :create]
rescue_from Octokit::Unauthorized, with: :github_unauthorized
+ helper_method :logged_in_with_github?
+
+ def new
+ if logged_in_with_github?
+ go_to_github_for_permissions
+ elsif session[:github_access_token]
+ redirect_to status_import_github_url
+ end
+ end
+
def callback
session[:github_access_token] = client.get_token(params[:code])
redirect_to status_import_github_url
end
+ def personal_access_token
+ session[:github_access_token] = params[:personal_access_token]
+ redirect_to status_import_github_url
+ end
+
def status
@repos = client.repos
@already_added_projects = current_user.created_projects.where(import_type: "github")
@@ -57,10 +72,14 @@ class Import::GithubController < Import::BaseController
end
def github_unauthorized
- go_to_github_for_permissions
+ session[:github_access_token] = nil
+ redirect_to new_import_github_url,
+ alert: 'Access denied to your GitHub account.'
end
- private
+ def logged_in_with_github?
+ current_user.identities.exists?(provider: 'github')
+ end
def access_params
{ github_access_token: session[:github_access_token] }
diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb
index f99aa490d3e..30df1fb2fec 100644
--- a/app/controllers/import/gitlab_projects_controller.rb
+++ b/app/controllers/import/gitlab_projects_controller.rb
@@ -12,9 +12,13 @@ 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"
+
+ FileUtils.copy_entry(project_params[:file].path, imported_file)
+
@project = Gitlab::ImportExport::ProjectCreator.new(project_params[:namespace_id],
current_user,
- File.expand_path(project_params[:file].path),
+ File.expand_path(imported_file),
project_params[:path]).execute
if @project.saved?
@@ -23,10 +27,7 @@ class Import::GitlabProjectsController < Import::BaseController
notice: "Project '#{@project.name}' is being imported."
)
else
- redirect_to(
- new_import_gitlab_project_path,
- alert: "Project could not be imported: #{@project.errors.full_messages.join(', ')}"
- )
+ redirect_back_or_default(options: { alert: "Project could not be imported: #{@project.errors.full_messages.join(', ')}" })
end
end
diff --git a/app/controllers/import/gitorious_controller.rb b/app/controllers/import/gitorious_controller.rb
index eecbe380c9e..a4c4ad23027 100644
--- a/app/controllers/import/gitorious_controller.rb
+++ b/app/controllers/import/gitorious_controller.rb
@@ -44,5 +44,4 @@ class Import::GitoriousController < Import::BaseController
def verify_gitorious_import_enabled
render_404 unless gitorious_import_enabled?
end
-
end
diff --git a/app/controllers/import/google_code_controller.rb b/app/controllers/import/google_code_controller.rb
index e0de31f2251..8d0de158f98 100644
--- a/app/controllers/import/google_code_controller.rb
+++ b/app/controllers/import/google_code_controller.rb
@@ -3,7 +3,6 @@ class Import::GoogleCodeController < Import::BaseController
before_action :user_map, only: [:new_user_map, :create_user_map]
def new
-
end
def callback
@@ -34,7 +33,6 @@ class Import::GoogleCodeController < Import::BaseController
end
def new_user_map
-
end
def create_user_map
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index 94bb108c5f5..58964a0e65d 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -5,7 +5,6 @@ class InvitesController < ApplicationController
respond_to :html
def show
-
end
def accept
diff --git a/app/controllers/notification_settings_controller.rb b/app/controllers/notification_settings_controller.rb
index eddd03cc229..8ec4bb1233f 100644
--- a/app/controllers/notification_settings_controller.rb
+++ b/app/controllers/notification_settings_controller.rb
@@ -2,11 +2,9 @@ class NotificationSettingsController < ApplicationController
before_action :authenticate_user!
def create
- project = Project.find(params[:project][:id])
+ return render_404 unless can_read?(resource)
- return render_404 unless can?(current_user, :read_project, project)
-
- @notification_setting = current_user.notification_settings_for(project)
+ @notification_setting = current_user.notification_settings_for(resource)
@saved = @notification_setting.update_attributes(notification_setting_params)
render_response
@@ -21,6 +19,22 @@ class NotificationSettingsController < ApplicationController
private
+ def resource
+ @resource ||=
+ if params[:project_id].present?
+ Project.find(params[:project_id])
+ elsif params[:namespace_id].present?
+ Group.find(params[:namespace_id])
+ end
+ end
+
+ def can_read?(resource)
+ ability_name = resource.class.name.downcase
+ ability_name = "read_#{ability_name}".to_sym
+
+ can?(current_user, ability_name, resource)
+ end
+
def render_response
render json: {
html: view_to_html_string("shared/notifications/_button", notification_setting: @notification_setting),
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index f35d631df0c..f54c79c2e37 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -107,7 +107,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
# Only allow properly saved users to login.
if @user.persisted? && @user.valid?
log_audit_event(@user, with: oauth['provider'])
- sign_in_and_redirect(@user)
+ if @user.two_factor_enabled?
+ prompt_for_two_factor(@user)
+ else
+ sign_in_and_redirect(@user)
+ end
else
error_message = @user.errors.full_messages.to_sentence
diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb
index 6a358fdcc05..e37e9e136db 100644
--- a/app/controllers/profiles/two_factor_auths_controller.rb
+++ b/app/controllers/profiles/two_factor_auths_controller.rb
@@ -100,7 +100,6 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
gon.push(u2f: { challenges: session[:challenges], app_id: u2f_app_id,
register_requests: registration_requests,
- sign_requests: sign_requests,
- browser_supports_u2f: browser_supports_u2f? })
+ sign_requests: sign_requests })
end
end
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 776ba92c9ab..996909a28c6 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -74,7 +74,7 @@ class Projects::ApplicationController < ApplicationController
end
def require_branch_head
- unless @repository.branch_names.include?(@ref)
+ unless @repository.branch_exists?(@ref)
redirect_to(
namespace_project_tree_path(@project.namespace, @project, @ref),
notice: "This action is not allowed unless you are on a branch"
diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb
index f11c8321464..7241949393b 100644
--- a/app/controllers/projects/artifacts_controller.rb
+++ b/app/controllers/projects/artifacts_controller.rb
@@ -23,10 +23,9 @@ class Projects::ArtifactsController < Projects::ApplicationController
entry = build.artifacts_metadata_entry(params[:path])
if entry.exists?
- render json: { archive: build.artifacts_file.path,
- entry: Base64.encode64(entry.path) }
+ send_artifacts_entry(build, entry)
else
- render json: {}, status: 404
+ render_404
end
end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index cd8b2911674..eda3727a28d 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -16,6 +16,7 @@ class Projects::BlobController < Projects::ApplicationController
before_action :from_merge_request, only: [:edit, :update]
before_action :require_branch_head, only: [:edit, :update]
before_action :editor_variables, except: [:show, :preview, :diff]
+ before_action :validate_diff_params, only: :diff
def new
commit unless @repository.empty?
@@ -37,6 +38,12 @@ class Projects::BlobController < Projects::ApplicationController
end
def update
+ if params[:file_path].present?
+ @previous_path = @path
+ @path = params[:file_path]
+ @commit_params[:file_path] = @path
+ end
+
after_edit_path =
if from_merge_request && @target_branch == @ref
diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) +
@@ -56,7 +63,7 @@ class Projects::BlobController < Projects::ApplicationController
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true)
diff_lines = diffy.diff.scan(/.*\n/)[2..-1]
diff_lines = Gitlab::Diff::Parser.new.parse(diff_lines)
- @diff_lines = Gitlab::Diff::Highlight.new(diff_lines).highlight
+ @diff_lines = Gitlab::Diff::Highlight.new(diff_lines, repository: @repository).highlight
render layout: false
end
@@ -146,4 +153,10 @@ class Projects::BlobController < Projects::ApplicationController
file_content_encoding: params[:encoding]
}
end
+
+ def validate_diff_params
+ if [:since, :to, :offset].any? { |key| params[key].blank? }
+ render nothing: true
+ end
+ end
end
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
index ef3051d7519..553b62741a5 100644
--- a/app/controllers/projects/builds_controller.rb
+++ b/app/controllers/projects/builds_controller.rb
@@ -1,6 +1,6 @@
class Projects::BuildsController < Projects::ApplicationController
before_action :build, except: [:index, :cancel_all]
- before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry]
+ before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry, :play]
before_action :authorize_update_build!, except: [:index, :show, :status, :raw]
layout 'project'
@@ -10,8 +10,10 @@ class Projects::BuildsController < Projects::ApplicationController
@builds = @all_builds.order('created_at DESC')
@builds =
case @scope
+ when 'pending'
+ @builds.pending.reverse_order
when 'running'
- @builds.running_or_pending.reverse_order
+ @builds.running.reverse_order
when 'finished'
@builds.finished
else
@@ -47,14 +49,19 @@ class Projects::BuildsController < Projects::ApplicationController
end
def retry
- unless @build.retryable?
- return render_404
- end
+ return render_404 unless @build.retryable?
build = Ci::Build.retry(@build, current_user)
redirect_to build_path(build)
end
+ def play
+ return render_404 unless @build.playable?
+
+ build = @build.play(current_user)
+ redirect_to build_path(build)
+ end
+
def cancel
@build.cancel
redirect_to build_path(@build)
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 6751737d15e..727e84b40a1 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -3,6 +3,7 @@
# Not to be confused with CommitsController, plural.
class Projects::CommitController < Projects::ApplicationController
include CreatesCommit
+ include DiffForPath
include DiffHelper
# Authorize
@@ -11,22 +12,14 @@ class Projects::CommitController < Projects::ApplicationController
before_action :authorize_update_build!, only: [:cancel_builds, :retry_builds]
before_action :authorize_read_commit_status!, only: [:builds]
before_action :commit
- before_action :define_show_vars, only: [:show, :builds]
+ before_action :define_commit_vars, only: [:show, :diff_for_path, :builds]
+ before_action :define_status_vars, only: [:show, :builds]
+ before_action :define_note_vars, only: [:show, :diff_for_path]
before_action :authorize_edit_tree!, only: [:revert, :cherry_pick]
def show
apply_diff_view_cookie!
- @grouped_diff_notes = commit.notes.grouped_diff_notes
-
- @note = @project.build_commit_note(commit)
- @notes = commit.notes.non_diff_notes.fresh
- @noteable = @commit
- @comments_target = {
- noteable_type: 'Commit',
- commit_id: @commit.id
- }
-
respond_to do |format|
format.html
format.diff { render text: @commit.to_diff }
@@ -34,6 +27,10 @@ class Projects::CommitController < Projects::ApplicationController
end
end
+ def diff_for_path
+ render_diff_for_path(@diffs, @commit.diff_refs, @project)
+ end
+
def builds
end
@@ -107,16 +104,36 @@ class Projects::CommitController < Projects::ApplicationController
@ci_builds ||= Ci::Build.where(pipeline: pipelines)
end
- def define_show_vars
+ def define_commit_vars
return git_not_found! unless commit
opts = diff_options
opts[:ignore_whitespace_change] = true if params[:format] == 'diff'
@diffs = commit.diffs(opts)
- @diff_refs = [commit.parent || commit, commit]
@notes_count = commit.notes.count
+ end
+
+ def define_note_vars
+ @grouped_diff_notes = commit.notes.grouped_diff_notes
+ @notes = commit.notes.non_diff_notes.fresh
+
+ Banzai::NoteRenderer.render(
+ @grouped_diff_notes.values.flatten + @notes,
+ @project,
+ current_user,
+ )
+
+ @note = @project.build_commit_note(commit)
+
+ @noteable = @commit
+ @comments_target = {
+ noteable_type: 'Commit',
+ commit_id: @commit.id
+ }
+ end
+ def define_status_vars
@statuses = CommitStatus.where(pipeline: pipelines)
@builds = Ci::Build.where(pipeline: pipelines)
end
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index af0b69a2442..5f3ee71444d 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -1,30 +1,26 @@
require 'addressable/uri'
class Projects::CompareController < Projects::ApplicationController
+ include DiffForPath
include DiffHelper
# Authorize
before_action :require_non_empty_project
before_action :authorize_download_code!
- before_action :assign_ref_vars, only: [:index, :show]
+ before_action :define_ref_vars, only: [:index, :show, :diff_for_path]
+ before_action :define_diff_vars, only: [:show, :diff_for_path]
before_action :merge_request, only: [:index, :show]
def index
end
def show
- compare = CompareService.new.
- execute(@project, @head_ref, @project, @base_ref, diff_options)
+ end
- if compare
- @commits = Commit.decorate(compare.commits, @project)
- @commit = @project.commit(@head_ref)
- @base_commit = @project.merge_base_commit(@base_ref, @head_ref)
- @diffs = compare.diffs(diff_options)
- @diff_refs = [@base_commit, @commit]
- @diff_notes_disabled = true
- @grouped_diff_notes = {}
- end
+ def diff_for_path
+ return render_404 unless @compare
+
+ render_diff_for_path(@diffs, @diff_refs, @project)
end
def create
@@ -34,13 +30,35 @@ class Projects::CompareController < Projects::ApplicationController
private
- def assign_ref_vars
- @base_ref = Addressable::URI.unescape(params[:from])
+ def define_ref_vars
+ @start_ref = Addressable::URI.unescape(params[:from])
@ref = @head_ref = Addressable::URI.unescape(params[:to])
end
+ def define_diff_vars
+ @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)
+
+ @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_notes = {}
+ end
+ end
+
def merge_request
@merge_request ||= @project.merge_requests.opened.
- find_by(source_project: @project, source_branch: @head_ref, target_branch: @base_ref)
+ find_by(source_project: @project, source_branch: @head_ref, target_branch: @start_ref)
end
end
diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb
index f907d63258b..40a8b7940d9 100644
--- a/app/controllers/projects/git_http_controller.rb
+++ b/app/controllers/projects/git_http_controller.rb
@@ -1,4 +1,9 @@
+# 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
@@ -14,6 +19,8 @@ class Projects::GitHttpController < Projects::ApplicationController
render_ok
elsif receive_pack? && receive_pack_allowed?
render_ok
+ elsif http_blocked?
+ render_not_allowed
else
render_not_found
end
@@ -40,9 +47,12 @@ class Projects::GitHttpController < Projects::ApplicationController
private
def authenticate_user
- return if project && project.public? && upload_pack?
+ if project && project.public? && upload_pack?
+ return # Allow access
+ end
- authenticate_or_request_with_http_basic do |login, password|
+ 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?
@@ -53,8 +63,31 @@ class Projects::GitHttpController < Projects::ApplicationController
@user = auth_result.user
end
- ci? || user
+ 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!
@@ -120,7 +153,11 @@ class Projects::GitHttpController < Projects::ApplicationController
end
def render_not_found
- render text: 'Not Found', status: :not_found
+ render plain: 'Not Found', status: :not_found
+ end
+
+ def render_not_allowed
+ render plain: download_access.message, status: :forbidden
end
def ci?
@@ -131,12 +168,28 @@ class Projects::GitHttpController < Projects::ApplicationController
return false unless Gitlab.config.gitlab_shell.upload_pack
if user
- Gitlab::GitAccess.new(user, project).download_access_check.allowed?
+ download_access.allowed?
else
ci? || project.public?
end
end
+ def access
+ return @access if defined?(@access)
+
+ @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')
+ end
+
+ def http_blocked?
+ !access.protocol_allowed?
+ end
+
def receive_pack_allowed?
return false unless Gitlab.config.gitlab_shell.receive_pack
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 4e2d3bebb2e..fa663c9bda4 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -62,8 +62,12 @@ class Projects::IssuesController < Projects::ApplicationController
end
def show
+ raw_notes = @issue.notes_with_associations.fresh
+
+ @notes = Banzai::NoteRenderer.
+ render(raw_notes, @project, current_user, @path, @project_wiki, @ref)
+
@note = @project.notes.new(noteable: @issue)
- @notes = @issue.notes.with_associations.fresh
@noteable = @issue
respond_to do |format|
@@ -72,7 +76,6 @@ class Projects::IssuesController < Projects::ApplicationController
render json: @issue.to_json(include: [:milestone, :labels])
end
end
-
end
def create
@@ -111,6 +114,7 @@ class Projects::IssuesController < Projects::ApplicationController
render :edit
end
end
+
format.json do
render json: @issue.to_json(include: { milestone: {}, assignee: { methods: :avatar_url }, labels: { methods: :text_color } })
end
@@ -222,6 +226,7 @@ class Projects::IssuesController < Projects::ApplicationController
:assignee_id,
:milestone_id,
:state_event,
+ :subscription_event,
label_ids: [],
add_label_ids: [],
remove_label_ids: []
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 851822d805a..df659bb8c3b 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -1,5 +1,6 @@
class Projects::MergeRequestsController < Projects::ApplicationController
include ToggleSubscriptionAction
+ include DiffForPath
include DiffHelper
include IssuableActions
include ToggleAwardEmoji
@@ -9,10 +10,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
:edit, :update, :show, :diffs, :commits, :builds, :merge, :merge_check,
:ci_status, :toggle_subscription, :cancel_merge_when_build_succeeds, :remove_wip
]
- before_action :closes_issues, only: [:edit, :update, :show, :diffs, :commits, :builds]
before_action :validates_merge_request, only: [:show, :diffs, :commits, :builds]
before_action :define_show_vars, only: [:show, :diffs, :commits, :builds]
before_action :define_widget_vars, only: [:merge, :cancel_merge_when_build_succeeds, :merge_check]
+ before_action :define_commit_vars, only: [:diffs]
+ before_action :define_diff_comment_vars, only: [:diffs]
before_action :ensure_ref_fetched, only: [:show, :diffs, :commits, :builds]
# Allow read any merge_request
@@ -53,13 +55,19 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def show
- @note_counts = Note.where(commit_id: @merge_request.commits.map(&:id)).
- group(:commit_id).count
-
respond_to do |format|
- format.html
- format.json { render json: @merge_request }
- format.patch { render text: @merge_request.to_patch }
+ format.html { define_discussion_vars }
+
+ format.json do
+ render json: @merge_request
+ end
+
+ format.patch do
+ return render_404 unless @merge_request.diff_refs
+
+ send_git_patch @project.repository, @merge_request.diff_refs
+ end
+
format.diff do
return render_404 unless @merge_request.diff_refs
@@ -71,43 +79,65 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def diffs
apply_diff_view_cookie!
- @commit = @merge_request.last_commit
- @base_commit = @merge_request.diff_base_commit
-
- # MRs created before 8.4 don't have a diff_base_commit,
- # but we need it for the "View file @ ..." link by deleted files
- @base_commit ||= @merge_request.first_commit.parent || @merge_request.first_commit
-
- @comments_target = {
- noteable_type: 'MergeRequest',
- noteable_id: @merge_request.id
- }
-
- @grouped_diff_notes = @merge_request.notes.grouped_diff_notes
+ @merge_request_diff = @merge_request.merge_request_diff
respond_to do |format|
- format.html
+ format.html { define_discussion_vars }
format.json { render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") } }
end
end
+ # With an ID param, loads the MR at that ID. Otherwise, accepts the same params as #new
+ # and uses that (unsaved) MR.
+ #
+ def diff_for_path
+ if params[:id]
+ merge_request
+ define_diff_comment_vars
+ else
+ build_merge_request
+ @diff_notes_disabled = true
+ @grouped_diff_notes = {}
+ end
+
+ define_commit_vars
+ diffs = @merge_request.diffs(diff_options)
+
+ render_diff_for_path(diffs, @merge_request.diff_refs, @merge_request.project)
+ end
+
def commits
respond_to do |format|
- format.html { render 'show' }
- format.json { render json: { html: view_to_html_string('projects/merge_requests/show/_commits') } }
+ format.html do
+ define_discussion_vars
+
+ render 'show'
+ end
+ format.json do
+ # Get commits from repository
+ # or from cache if already merged
+ @commits = @merge_request.commits
+ @note_counts = Note.where(commit_id: @commits.map(&:id)).
+ group(:commit_id).count
+
+ render json: { html: view_to_html_string('projects/merge_requests/show/_commits') }
+ end
end
end
def builds
respond_to do |format|
- format.html { render 'show' }
+ format.html do
+ define_discussion_vars
+
+ render 'show'
+ end
format.json { render json: { html: view_to_html_string('projects/merge_requests/show/_builds') } }
end
end
def new
- params[:merge_request] ||= ActionController::Parameters.new(source_project: @project)
- @merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params).execute
+ build_merge_request
@noteable = @merge_request
@target_branches = if @merge_request.target_project
@@ -119,7 +149,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@target_project = merge_request.target_project
@source_project = merge_request.source_project
@commits = @merge_request.compare_commits.reverse
- @commit = @merge_request.last_commit
+ @commit = @merge_request.diff_head_commit
@base_commit = @merge_request.diff_base_commit
@diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare
@diff_notes_disabled = true
@@ -190,12 +220,14 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def merge
return access_denied! unless @merge_request.can_be_merged_by?(current_user)
- unless @merge_request.mergeable?
+ # Disable the CI check if merge_when_build_succeeds is enabled since we have
+ # to wait until CI completes to know
+ unless @merge_request.mergeable?(skip_ci_check: merge_when_build_succeeds_active?)
@status = :failed
return
end
- if params[:sha] != @merge_request.source_sha
+ if params[:sha] != @merge_request.diff_head_sha
@status = :sha_mismatch
return
end
@@ -204,8 +236,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@merge_request.update(merge_error: nil)
- if params[:merge_when_build_succeeds].present?
- if @merge_request.pipeline && @merge_request.pipeline.active?
+ if params[:merge_when_build_succeeds].present?
+ unless @merge_request.pipeline
+ @status = :failed
+ return
+ end
+
+ if @merge_request.pipeline.active?
MergeRequests::MergeWhenBuildSucceedsService.new(@project, current_user, merge_params)
.execute(@merge_request)
@status = :merge_when_build_succeeds
@@ -252,16 +289,16 @@ class Projects::MergeRequestsController < Projects::ApplicationController
status ||= "preparing"
else
ci_service = @merge_request.source_project.ci_service
- status = ci_service.commit_status(merge_request.last_commit.sha, merge_request.source_branch) if ci_service
+ status = ci_service.commit_status(merge_request.diff_head_sha, merge_request.source_branch) if ci_service
if ci_service.respond_to?(:commit_coverage)
- coverage = ci_service.commit_coverage(merge_request.last_commit.sha, merge_request.source_branch)
+ coverage = ci_service.commit_coverage(merge_request.diff_head_sha, merge_request.source_branch)
end
end
response = {
title: merge_request.title,
- sha: merge_request.last_commit_short_sha,
+ sha: merge_request.diff_head_commit.short_id,
status: status,
coverage: coverage
}
@@ -286,10 +323,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
alias_method :issuable, :merge_request
alias_method :awardable, :merge_request
- def closes_issues
- @closes_issues ||= @merge_request.closes_issues
- end
-
def authorize_update_merge_request!
return render_404 unless can?(current_user, :update_merge_request, @merge_request)
end
@@ -318,17 +351,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def define_show_vars
- # Build a note object for comment form
- @note = @project.notes.new(noteable: @merge_request)
- @notes = @merge_request.mr_and_commit_notes.inc_author.fresh
- @discussions = @notes.discussions
@noteable = @merge_request
-
- # Get commits from repository
- # or from cache if already merged
- @commits = @merge_request.commits
-
- @merge_request_diff = @merge_request.merge_request_diff
+ @commits_count = @merge_request.commits.count
@pipeline = @merge_request.pipeline
@statuses = @pipeline.statuses if @pipeline
@@ -339,10 +363,55 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
+ # Discussion tab data is rendered on html responses of actions
+ # :show, :diff, :commits, :builds. but not when request the data through AJAX
+ def define_discussion_vars
+ # Build a note object for comment form
+ @note = @project.notes.new(noteable: @noteable)
+
+ @discussions = @noteable.mr_and_commit_notes.
+ inc_author_project_award_emoji.
+ fresh.
+ discussions
+
+ # This is not executed lazily
+ @notes = Banzai::NoteRenderer.render(
+ @discussions.flatten,
+ @project,
+ current_user,
+ @path,
+ @project_wiki,
+ @ref
+ )
+ end
+
def define_widget_vars
@pipeline = @merge_request.pipeline
@pipelines = [@pipeline].compact
- closes_issues
+ end
+
+ def define_commit_vars
+ @commit = @merge_request.diff_head_commit
+ @base_commit = @merge_request.diff_base_commit || @merge_request.likely_diff_base_commit
+ end
+
+ def define_diff_comment_vars
+ @comments_target = {
+ noteable_type: 'MergeRequest',
+ noteable_id: @merge_request.id
+ }
+
+ @use_legacy_diff_notes = !@merge_request.support_new_diff_notes?
+ @grouped_diff_notes = @merge_request.notes.grouped_diff_notes
+
+ Banzai::NoteRenderer.render(
+ @grouped_diff_notes.values.flatten,
+ @project,
+ current_user,
+ @path,
+ @project_wiki,
+ @ref
+ )
end
def invalid_mr
@@ -368,4 +437,14 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def ensure_ref_fetched
@merge_request.ensure_ref_fetched
end
+
+ def merge_when_build_succeeds_active?
+ params[:merge_when_build_succeeds].present? &&
+ @merge_request.pipeline && @merge_request.pipeline.active?
+ end
+
+ def build_merge_request
+ params[:merge_request] ||= ActionController::Parameters.new(source_project: @project)
+ @merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params).execute
+ end
end
diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb
index b181c47baec..34318391dd9 100644
--- a/app/controllers/projects/network_controller.rb
+++ b/app/controllers/projects/network_controller.rb
@@ -7,7 +7,6 @@ class Projects::NetworkController < Projects::ApplicationController
before_action :authorize_download_code!
def show
-
@url = namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json))
@commit_url = namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s")
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 836f79ff080..3eacdbbd067 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -24,6 +24,10 @@ class Projects::NotesController < Projects::ApplicationController
def create
@note = Notes::CreateService.new(project, current_user, note_params).execute
+ if @note.is_a?(Note)
+ Banzai::NoteRenderer.render([@note], @project, current_user)
+ end
+
respond_to do |format|
format.json { render json: note_json(@note) }
format.html { redirect_back_or_default }
@@ -33,6 +37,10 @@ class Projects::NotesController < Projects::ApplicationController
def update
@note = Notes::UpdateService.new(project, current_user, note_params).execute(note)
+ if @note.is_a?(Note)
+ Banzai::NoteRenderer.render([@note], @project, current_user)
+ end
+
respond_to do |format|
format.json { render json: note_json(@note) }
format.html { redirect_back_or_default }
@@ -118,7 +126,9 @@ class Projects::NotesController < Projects::ApplicationController
name: note.name
}
elsif note.valid?
- {
+ Banzai::NoteRenderer.render([note], @project, current_user)
+
+ attrs = {
valid: true,
id: note.id,
discussion_id: note.discussion_id,
@@ -128,6 +138,23 @@ class Projects::NotesController < Projects::ApplicationController
discussion_html: note_to_discussion_html(note),
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
}
+
+ # The discussion_id is used to add the comment to the correct discussion
+ # element on the merge request page. Among other things, the discussion_id
+ # contains the sha of head commit of the merge request.
+ # When new commits are pushed into the merge request after the initial
+ # load of the merge request page, the discussion elements will still have
+ # the old discussion_ids, with the old head commit sha. The new comment,
+ # however, will have the new discussion_id with the new commit sha.
+ # To ensure that these new comments will still end up in the correct
+ # discussion element, we also send the original discussion_id, with the
+ # old commit sha, along, and fall back on this value when no discussion
+ # element with the new discussion_id could be found.
+ if note.new_diff_note? && note.position != note.original_position
+ attrs[:original_discussion_id] = note.original_discussion_id
+ end
+
+ attrs
else
{
valid: false,
@@ -144,7 +171,7 @@ class Projects::NotesController < Projects::ApplicationController
def note_params
params.require(:note).permit(
:note, :noteable, :noteable_id, :noteable_type, :project_id,
- :attachment, :line_code, :commit_id, :type
+ :attachment, :line_code, :commit_id, :type, :position
)
end
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 127bd1a4318..487963fdcd7 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -54,6 +54,6 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def commit
- @commit ||= @pipeline.commit_data
+ @commit ||= @pipeline.commit
end
end
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index 35d067cd029..3435a118964 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -6,7 +6,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
def index
@project_members = @project.project_members
- @project_members = @project_members.non_pending unless can?(current_user, :admin_project, @project)
+ @project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project)
if params[:search].present?
users = @project.users.search(params[:search]).to_a
@@ -19,7 +19,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
if @group
@group_members = @group.group_members
- @group_members = @group_members.non_pending unless can?(current_user, :admin_group, @group)
+ @group_members = @group_members.non_invite unless can?(current_user, :admin_group, @group)
if params[:search].present?
users = @group.users.search(params[:search]).to_a
@@ -29,6 +29,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController
@group_members = @group_members.order('access_level DESC')
end
+ @requesters = @project.requesters if can?(current_user, :admin_project, @project)
+
@project_member = @project.project_members.new
@project_group_links = @project.project_group_links
end
@@ -48,11 +50,10 @@ class Projects::ProjectMembersController < Projects::ApplicationController
end
def destroy
- @project_member = @project.project_members.find(params[:id])
-
- return render_403 unless can?(current_user, :destroy_project_member, @project_member)
+ @project_member = @project.members.find_by(id: params[:id]) ||
+ @project.requesters.find_by(id: params[:id])
- @project_member.destroy
+ Members::DestroyService.new(@project_member, current_user).execute
respond_to do |format|
format.html do
@@ -98,8 +99,4 @@ class Projects::ProjectMembersController < Projects::ApplicationController
# MembershipActions concern
alias_method :membershipable, :project
-
- def cannot_leave?
- current_user == @project.owner
- end
end
diff --git a/app/controllers/projects/protected_branches_controller.rb b/app/controllers/projects/protected_branches_controller.rb
index efa7bf14d0f..10dca47fded 100644
--- a/app/controllers/projects/protected_branches_controller.rb
+++ b/app/controllers/projects/protected_branches_controller.rb
@@ -2,12 +2,14 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project
before_action :authorize_admin_project!
+ before_action :load_protected_branch, only: [:show, :update, :destroy]
layout "project_settings"
def index
- @branches = @project.protected_branches.to_a
+ @protected_branches = @project.protected_branches.order(:name).page(params[:page])
@protected_branch = @project.protected_branches.new
+ gon.push({ open_branches: @project.open_branches.map { |br| { text: br.name, id: br.name, title: br.name } } })
end
def create
@@ -16,26 +18,24 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
@project)
end
- def update
- protected_branch = @project.protected_branches.find(params[:id])
-
- if protected_branch &&
- protected_branch.update_attributes(
- developers_can_push: params[:developers_can_push]
- )
+ def show
+ @matching_branches = @protected_branch.matching(@project.repository.branches)
+ end
+ def update
+ if @protected_branch && @protected_branch.update_attributes(protected_branch_params)
respond_to do |format|
- format.json { render json: protected_branch, status: :ok }
+ format.json { render json: @protected_branch, status: :ok }
end
else
respond_to do |format|
- format.json { render json: protected_branch.errors, status: :unprocessable_entity }
+ format.json { render json: @protected_branch.errors, status: :unprocessable_entity }
end
end
end
def destroy
- @project.protected_branches.find(params[:id]).destroy
+ @protected_branch.destroy
respond_to do |format|
format.html { redirect_to namespace_project_protected_branches_path }
@@ -45,7 +45,11 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
private
+ def load_protected_branch
+ @protected_branch = @project.protected_branches.find(params[:id])
+ end
+
def protected_branch_params
- params.require(:protected_branch).permit(:name, :developers_can_push)
+ params.require(:protected_branch).permit(:name, :developers_can_push, :developers_can_merge)
end
end
diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb
index bedeb4a295c..8267b14941d 100644
--- a/app/controllers/projects/runner_projects_controller.rb
+++ b/app/controllers/projects/runner_projects_controller.rb
@@ -6,11 +6,12 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
- return head(403) unless current_user.ci_authorized_runners.include?(@runner)
+ return head(403) unless can?(current_user, :assign_runner, @runner)
path = runners_path(project)
+ runner_project = @runner.assign_to(project, current_user)
- if @runner.assign_to(project, current_user)
+ if runner_project.persisted?
redirect_to path
else
redirect_to path, alert: 'Failed adding runner to project'
diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb
index 0b4fa572501..53c36635efe 100644
--- a/app/controllers/projects/runners_controller.rb
+++ b/app/controllers/projects/runners_controller.rb
@@ -5,10 +5,9 @@ class Projects::RunnersController < Projects::ApplicationController
layout 'project_settings'
def index
- @runners = project.runners.ordered
- @specific_runners = current_user.ci_authorized_runners.
- where.not(id: project.runners).
- ordered.page(params[:page]).per(20)
+ @project_runners = project.runners.ordered
+ @assignable_runners = current_user.ci_authorized_runners.
+ assignable_for(project).ordered.page(params[:page]).per(20)
@shared_runners = Ci::Runner.shared.active
@shared_runners_count = @shared_runners.count(:all)
end
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 739681f4085..1b91882048e 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -45,8 +45,9 @@ class Projects::ServicesController < Projects::ApplicationController
end
def test
- data = Gitlab::PushDataBuilder.build_sample(project, current_user)
+ data = @service.test_data(project, current_user)
outcome = @service.test(data)
+
if outcome[:success]
message = { notice: 'We sent a request to the provided URL' }
else
diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb
index 6d2901a24a4..6d0a7ee1031 100644
--- a/app/controllers/projects/snippets_controller.rb
+++ b/app/controllers/projects/snippets_controller.rb
@@ -54,7 +54,7 @@ class Projects::SnippetsController < Projects::ApplicationController
def show
@note = @project.notes.new(noteable: @snippet)
- @notes = @snippet.notes.fresh
+ @notes = Banzai::NoteRenderer.render(@snippet.notes.fresh, @project, current_user)
@noteable = @snippet
end
diff --git a/app/controllers/projects/todos_controller.rb b/app/controllers/projects/todos_controller.rb
index 23868d986e9..5685d0f4e7c 100644
--- a/app/controllers/projects/todos_controller.rb
+++ b/app/controllers/projects/todos_controller.rb
@@ -5,7 +5,7 @@ class Projects::TodosController < Projects::ApplicationController
todo = TodoService.new.mark_todo(issuable, current_user)
render json: {
- count: current_user.todos_pending_count,
+ count: TodosFinder.new(current_user, state: :pending).execute.count,
delete_path: dashboard_todo_path(todo)
}
end
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index 7ec1e73b3be..607fe9c7fed 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -124,5 +124,4 @@ class Projects::WikisController < Projects::ApplicationController
def wiki_params
params[:wiki].slice(:title, :content, :format, :message)
end
-
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 8044c637825..4e5bcff9cf8 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -1,10 +1,11 @@
class ProjectsController < Projects::ApplicationController
include ExtractsPath
- before_action :authenticate_user!, except: [:show, :activity]
+ before_action :authenticate_user!, except: [:show, :activity, :refs]
before_action :project, except: [:new, :create]
before_action :repository, except: [:new, :create]
- before_action :assign_ref_vars, :tree, only: [:show], if: :repo_exists?
+ before_action :assign_ref_vars, only: [:show], if: :repo_exists?
+ before_action :tree, only: [:show], if: [:repo_exists?, :project_view_files?]
# Authorize
before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export, :remove_export, :generate_new_export]
@@ -52,11 +53,11 @@ class ProjectsController < Projects::ApplicationController
notice: "Project '#{@project.name}' was successfully updated."
)
end
- format.js
else
format.html { render 'edit' }
- format.js
end
+
+ format.js
end
end
@@ -251,6 +252,24 @@ class ProjectsController < Projects::ApplicationController
}
end
+ def refs
+ options = {
+ 'Branches' => @repository.branch_names,
+ }
+
+ unless @repository.tag_count.zero?
+ options['Tags'] = VersionSorter.rsort(@repository.tag_names)
+ end
+
+ # If reference is commit id - we should add it to branch/tag selectbox
+ ref = Addressable::URI.unescape(params[:ref])
+ if ref && options.flatten(2).exclude?(ref) && ref =~ /\A[0-9a-zA-Z]{6,52}\z/
+ options['Commits'] = [ref]
+ end
+
+ render json: options.to_json
+ end
+
private
def determine_layout
@@ -285,8 +304,18 @@ class ProjectsController < Projects::ApplicationController
project.repository_exists? && !project.empty_repo?
end
- # Override get_id from ExtractsPath, which returns the branch and file path
+ def project_view_files?
+ current_user && current_user.project_view == 'files'
+ end
+
+ # Override extract_ref from ExtractsPath, which returns the branch and file path
# for the blob/tree, which in this case is just the root of the default branch.
+ # This way we avoid to access the repository.ref_names.
+ def extract_ref(_id)
+ [get_id, '']
+ end
+
+ # Override get_id from ExtractsPath in this case is just the root of the default branch.
def get_id
project.repository.root_ref
end