summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/abuse_reports_controller.rb2
-rw-r--r--app/controllers/admin/application_settings_controller.rb18
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb2
-rw-r--r--app/controllers/admin/health_check_controller.rb5
-rw-r--r--app/controllers/admin/keys_controller.rb2
-rw-r--r--app/controllers/admin/runners_controller.rb37
-rw-r--r--app/controllers/admin/spam_logs_controller.rb2
-rw-r--r--app/controllers/admin/users_controller.rb3
-rw-r--r--app/controllers/application_controller.rb22
-rw-r--r--app/controllers/autocomplete_controller.rb18
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb59
-rw-r--r--app/controllers/concerns/creates_commit.rb2
-rw-r--r--app/controllers/concerns/toggle_award_emoji.rb31
-rw-r--r--app/controllers/concerns/toggle_subscription_action.rb2
-rw-r--r--app/controllers/dashboard/labels_controller.rb2
-rw-r--r--app/controllers/dashboard/projects_controller.rb2
-rw-r--r--app/controllers/dashboard/todos_controller.rb4
-rw-r--r--app/controllers/dashboard_controller.rb2
-rw-r--r--app/controllers/groups/group_members_controller.rb2
-rw-r--r--app/controllers/health_check_controller.rb22
-rw-r--r--app/controllers/jwt_controller.rb49
-rw-r--r--app/controllers/oauth/applications_controller.rb2
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb2
-rw-r--r--app/controllers/profiles/emails_controller.rb2
-rw-r--r--app/controllers/profiles/keys_controller.rb2
-rw-r--r--app/controllers/profiles/notifications_controller.rb23
-rw-r--r--app/controllers/profiles/two_factor_auths_controller.rb45
-rw-r--r--app/controllers/projects/application_controller.rb2
-rw-r--r--app/controllers/projects/artifacts_controller.rb2
-rw-r--r--app/controllers/projects/avatars_controller.rb5
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/controllers/projects/builds_controller.rb14
-rw-r--r--app/controllers/projects/commit_controller.rb22
-rw-r--r--app/controllers/projects/compare_controller.rb3
-rw-r--r--app/controllers/projects/container_registry_controller.rb34
-rw-r--r--app/controllers/projects/find_file_controller.rb52
-rw-r--r--app/controllers/projects/git_http_controller.rb147
-rw-r--r--app/controllers/projects/hooks_controller.rb9
-rw-r--r--app/controllers/projects/imports_controller.rb1
-rw-r--r--app/controllers/projects/issues_controller.rb16
-rw-r--r--app/controllers/projects/labels_controller.rb29
-rw-r--r--app/controllers/projects/merge_requests_controller.rb59
-rw-r--r--app/controllers/projects/milestones_controller.rb2
-rw-r--r--app/controllers/projects/notes_controller.rb52
-rw-r--r--app/controllers/projects/pipelines_controller.rb59
-rw-r--r--app/controllers/projects/project_members_controller.rb4
-rw-r--r--app/controllers/projects/protected_branches_controller.rb2
-rw-r--r--app/controllers/projects/raw_controller.rb5
-rw-r--r--app/controllers/projects/repositories_controller.rb3
-rw-r--r--app/controllers/projects/runners_controller.rb4
-rw-r--r--app/controllers/projects/variables_controller.rb30
-rw-r--r--app/controllers/projects/wikis_controller.rb6
-rw-r--r--app/controllers/projects_controller.rb20
-rw-r--r--app/controllers/registrations_controller.rb4
-rw-r--r--app/controllers/sessions_controller.rb37
-rw-r--r--app/controllers/snippets_controller.rb2
-rw-r--r--app/controllers/users_controller.rb24
57 files changed, 795 insertions, 220 deletions
diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb
index e9b0972bdd8..5055c318a5f 100644
--- a/app/controllers/admin/abuse_reports_controller.rb
+++ b/app/controllers/admin/abuse_reports_controller.rb
@@ -9,6 +9,6 @@ class Admin::AbuseReportsController < Admin::ApplicationController
abuse_report.remove_user(deleted_by: current_user) if params[:remove_user]
abuse_report.destroy
- render nothing: true
+ head :ok
end
end
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index ec22548ddeb..f4eda864aac 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -19,6 +19,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
redirect_to admin_runners_path
end
+ def reset_health_check_token
+ @application_setting.reset_health_check_access_token!
+ flash[:notice] = 'New health check access token has been generated!'
+ redirect_to :back
+ end
+
def clear_repository_check_states
RepositoryCheck::ClearWorker.perform_async
@@ -53,6 +59,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
end
end
+ enabled_oauth_sign_in_sources = params[:application_setting].delete(:enabled_oauth_sign_in_sources)
+
+ params[:application_setting][:disabled_oauth_sign_in_sources] =
+ AuthHelper.button_based_providers.map(&:to_s) -
+ Array(enabled_oauth_sign_in_sources)
+
params.require(:application_setting).permit(
:default_projects_limit,
:default_branch_protection,
@@ -62,6 +74,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:two_factor_grace_period,
:gravatar_enabled,
:sign_in_text,
+ :after_sign_up_text,
:help_page_text,
:home_page_url,
:after_sign_out_path,
@@ -94,8 +107,11 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:email_author_in_body,
:repository_checks_enabled,
:metrics_packet_size,
+ :send_user_confirmation_email,
+ :container_registry_token_expire_delay,
restricted_visibility_levels: [],
- import_sources: []
+ import_sources: [],
+ disabled_oauth_sign_in_sources: []
)
end
end
diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb
index fc342924987..82055006ac0 100644
--- a/app/controllers/admin/broadcast_messages_controller.rb
+++ b/app/controllers/admin/broadcast_messages_controller.rb
@@ -32,7 +32,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
respond_to do |format|
format.html { redirect_back_or_default(default: { action: 'index' }) }
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
diff --git a/app/controllers/admin/health_check_controller.rb b/app/controllers/admin/health_check_controller.rb
new file mode 100644
index 00000000000..241c7be0ea1
--- /dev/null
+++ b/app/controllers/admin/health_check_controller.rb
@@ -0,0 +1,5 @@
+class Admin::HealthCheckController < Admin::ApplicationController
+ def show
+ @errors = HealthCheck::Utils.process_checks('standard')
+ end
+end
diff --git a/app/controllers/admin/keys_controller.rb b/app/controllers/admin/keys_controller.rb
index cb33fdd9763..054bb52b696 100644
--- a/app/controllers/admin/keys_controller.rb
+++ b/app/controllers/admin/keys_controller.rb
@@ -6,7 +6,7 @@ class Admin::KeysController < Admin::ApplicationController
respond_to do |format|
format.html
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index a701d49b844..7345c91f67d 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -9,23 +9,18 @@ class Admin::RunnersController < Admin::ApplicationController
end
def show
- @builds = @runner.builds.order('id DESC').first(30)
- @projects =
- if params[:search].present?
- ::Project.search(params[:search])
- else
- Project.all
- end
- @projects = @projects.where.not(id: @runner.projects.select(:id)) if @runner.projects.any?
- @projects = @projects.page(params[:page]).per(30)
+ assign_builds_and_projects
end
def update
- @runner.update_attributes(runner_params)
-
- respond_to do |format|
- format.js
- format.html { redirect_to admin_runner_path(@runner) }
+ if @runner.update_attributes(runner_params)
+ respond_to do |format|
+ format.js
+ format.html { redirect_to admin_runner_path(@runner) }
+ end
+ else
+ assign_builds_and_projects
+ render 'show'
end
end
@@ -58,6 +53,18 @@ class Admin::RunnersController < Admin::ApplicationController
end
def runner_params
- params.require(:runner).permit(:token, :description, :tag_list, :active)
+ params.require(:runner).permit(Ci::Runner::FORM_EDITABLE)
+ end
+
+ def assign_builds_and_projects
+ @builds = runner.builds.order('id DESC').first(30)
+ @projects =
+ if params[:search].present?
+ ::Project.search(params[:search])
+ else
+ Project.all
+ end
+ @projects = @projects.where.not(id: runner.projects.select(:id)) if runner.projects.any?
+ @projects = @projects.page(params[:page]).per(30)
end
end
diff --git a/app/controllers/admin/spam_logs_controller.rb b/app/controllers/admin/spam_logs_controller.rb
index 377e9741e5f..3a2f0185315 100644
--- a/app/controllers/admin/spam_logs_controller.rb
+++ b/app/controllers/admin/spam_logs_controller.rb
@@ -11,7 +11,7 @@ class Admin::SpamLogsController < Admin::ApplicationController
redirect_to admin_spam_logs_path, notice: "User #{spam_log.user.username} was successfully removed."
else
spam_log.destroy
- render nothing: true
+ head :ok
end
end
end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index f2f654c7bcd..f35f4a8c811 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -119,6 +119,7 @@ class Admin::UsersController < Admin::ApplicationController
user_params_with_pass.merge!(
password: params[:user][:password],
password_confirmation: params[:user][:password_confirmation],
+ password_expires_at: Time.now
)
end
@@ -153,7 +154,7 @@ class Admin::UsersController < Admin::ApplicationController
respond_to do |format|
format.html { redirect_back_or_admin_user(notice: "Successfully removed email.") }
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 17b3f49aed1..cd6ae507cf1 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -6,6 +6,7 @@ class ApplicationController < ActionController::Base
include Gitlab::GonHelper
include GitlabRoutingHelper
include PageLayoutHelper
+ include WorkhorseHelper
before_action :authenticate_user_from_token!
before_action :authenticate_user!
@@ -176,14 +177,14 @@ class ApplicationController < ActionController::Base
end
def check_password_expiration
- if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now && !current_user.ldap_user?
+ if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now && !current_user.ldap_user?
redirect_to new_profile_password_path and return
end
end
def check_2fa_requirement
- if two_factor_authentication_required? && current_user && !current_user.two_factor_enabled && !skip_two_factor?
- redirect_to new_profile_two_factor_auth_path
+ if two_factor_authentication_required? && current_user && !current_user.two_factor_enabled? && !skip_two_factor?
+ redirect_to profile_two_factor_auth_path
end
end
@@ -232,7 +233,7 @@ class ApplicationController < ActionController::Base
end
def configure_permitted_parameters
- devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me, :otp_attempt) }
+ devise_parameter_sanitizer.permit(:sign_in, keys: [:username, :email, :password, :login, :remember_me, :otp_attempt])
end
def hexdigest(string)
@@ -263,7 +264,7 @@ class ApplicationController < ActionController::Base
# internal repos where you are not a member. Enable this filter
# or improve current implementation to filter only issues you
# created or assigned or mentioned
- #@filter_params[:authorized_only] = true
+ # @filter_params[:authorized_only] = true
end
@filter_params
@@ -342,6 +343,10 @@ 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
@@ -355,6 +360,13 @@ class ApplicationController < ActionController::Base
current_user.nil? && root_path == request.path
end
+ # U2F (universal 2nd factor) devices need a unique identifier for the application
+ # to perform authentication.
+ # https://developers.yubico.com/U2F/App_ID.html
+ def u2f_app_id
+ request.base_url
+ end
+
private
def set_default_sort
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index eb0abc80ab4..3865b2d61fd 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -31,6 +31,24 @@ class AutocompleteController < ApplicationController
render json: @user, only: [:name, :username, :id], methods: [:avatar_url]
end
+ def projects
+ project = Project.find_by_id(params[:project_id])
+
+ projects = current_user.authorized_projects
+ projects = projects.select do |project|
+ current_user.can?(:admin_issue, project)
+ end
+
+ no_project = {
+ id: 0,
+ name_with_namespace: 'No project',
+ }
+ projects.unshift(no_project)
+ projects.delete(project)
+
+ render json: projects.to_json(only: [:id, :name_with_namespace], methods: :name_with_namespace)
+ end
+
private
def find_users
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb
index d5918a7af3b..998b8adc411 100644
--- a/app/controllers/concerns/authenticates_with_two_factor.rb
+++ b/app/controllers/concerns/authenticates_with_two_factor.rb
@@ -24,7 +24,64 @@ module AuthenticatesWithTwoFactor
# Returns nil
def prompt_for_two_factor(user)
session[:otp_user_id] = user.id
+ setup_u2f_authentication(user)
+ render 'devise/sessions/two_factor'
+ end
+
+ def authenticate_with_two_factor
+ user = self.resource = find_user
+
+ if user_params[:otp_attempt].present? && session[:otp_user_id]
+ authenticate_with_two_factor_via_otp(user)
+ elsif user_params[:device_response].present? && session[:otp_user_id]
+ authenticate_with_two_factor_via_u2f(user)
+ elsif user && user.valid_password?(user_params[:password])
+ prompt_for_two_factor(user)
+ end
+ end
+
+ private
+
+ def authenticate_with_two_factor_via_otp(user)
+ if valid_otp_attempt?(user)
+ # Remove any lingering user data from login
+ session.delete(:otp_user_id)
+
+ remember_me(user) if user_params[:remember_me] == '1'
+ sign_in(user)
+ else
+ flash.now[:alert] = 'Invalid two-factor code.'
+ render :two_factor
+ end
+ end
+
+ # 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])
+ # Remove any lingering user data from login
+ session.delete(:otp_user_id)
+ session.delete(:challenges)
+
+ sign_in(user)
+ else
+ flash.now[:alert] = 'Authentication via U2F device failed.'
+ prompt_for_two_factor(user)
+ end
+ end
+
+ # Setup in preparation of communication with a U2F (universal 2nd factor) device
+ # Actual communication is performed using a Javascript API
+ def setup_u2f_authentication(user)
+ key_handles = user.u2f_registrations.pluck(:key_handle)
+ u2f = U2F::U2F.new(u2f_app_id)
- render 'devise/sessions/two_factor' and return
+ 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? })
+ end
end
end
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb
index 787416c17ab..dacb5679dd3 100644
--- a/app/controllers/concerns/creates_commit.rb
+++ b/app/controllers/concerns/creates_commit.rb
@@ -122,7 +122,7 @@ module CreatesCommit
# Merge request from fork to this project
@mr_source_project = @tree_edit_project
@mr_target_project = @project
- @mr_target_branch ||= @ref
+ @mr_target_branch ||= @ref
end
end
end
diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb
new file mode 100644
index 00000000000..036777c80c1
--- /dev/null
+++ b/app/controllers/concerns/toggle_award_emoji.rb
@@ -0,0 +1,31 @@
+module ToggleAwardEmoji
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :authenticate_user!, only: [:toggle_award_emoji]
+ end
+
+ def toggle_award_emoji
+ name = params.require(:name)
+
+ awardable.toggle_award_emoji(name, current_user)
+ TodoService.new.new_award_emoji(to_todoable(awardable), current_user)
+
+ render json: { ok: true }
+ end
+
+ private
+
+ def to_todoable(awardable)
+ case awardable
+ when Note
+ awardable.noteable
+ else
+ awardable
+ end
+ end
+
+ def awardable
+ raise NotImplementedError
+ end
+end
diff --git a/app/controllers/concerns/toggle_subscription_action.rb b/app/controllers/concerns/toggle_subscription_action.rb
index 8a43c0b93c4..9e3b9be2ff4 100644
--- a/app/controllers/concerns/toggle_subscription_action.rb
+++ b/app/controllers/concerns/toggle_subscription_action.rb
@@ -6,7 +6,7 @@ module ToggleSubscriptionAction
subscribable_resource.toggle_subscription(current_user)
- render nothing: true
+ head :ok
end
private
diff --git a/app/controllers/dashboard/labels_controller.rb b/app/controllers/dashboard/labels_controller.rb
index 23a4ef21ea2..2a88350a4ca 100644
--- a/app/controllers/dashboard/labels_controller.rb
+++ b/app/controllers/dashboard/labels_controller.rb
@@ -1,6 +1,6 @@
class Dashboard::LabelsController < Dashboard::ApplicationController
def index
- labels = Label.where(project_id: projects).select(:title, :color).uniq(:title)
+ labels = Label.where(project_id: projects).select(:id, :title, :color).uniq(:title)
respond_to do |format|
format.json { render json: labels }
diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb
index 71acc244a91..c08eb811532 100644
--- a/app/controllers/dashboard/projects_controller.rb
+++ b/app/controllers/dashboard/projects_controller.rb
@@ -28,7 +28,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
end
def starred
- @projects = current_user.starred_projects.sorted_by_activity
+ @projects = current_user.viewable_starred_projects.sorted_by_activity
@projects = filter_projects(@projects)
@projects = @projects.includes(:namespace, :forked_from_project, :tags)
@projects = @projects.sort(@sort = params[:sort])
diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb
index 5abf97342c3..f9a1929c117 100644
--- a/app/controllers/dashboard/todos_controller.rb
+++ b/app/controllers/dashboard/todos_controller.rb
@@ -12,7 +12,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: todo_notice }
- format.js { render nothing: true }
+ format.js { head :ok }
format.json do
render json: { count: @todos.size, done_count: current_user.todos.done.count }
end
@@ -24,7 +24,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 { render nothing: true }
+ format.js { head :ok }
format.json do
find_todos
render json: { count: @todos.size, done_count: current_user.todos.done.count }
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 1dce4a21729..4dda4e51f6a 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -25,7 +25,7 @@ class DashboardController < Dashboard::ApplicationController
def load_events
projects =
if params[:filter] == "starred"
- current_user.starred_projects
+ current_user.viewable_starred_projects
else
current_user.authorized_projects
end
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index d5ef33888c6..48dbf656e84 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -40,7 +40,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
respond_to do |format|
format.html { redirect_to group_group_members_path(@group), notice: 'User was successfully removed from group.' }
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
diff --git a/app/controllers/health_check_controller.rb b/app/controllers/health_check_controller.rb
new file mode 100644
index 00000000000..037da7d2bce
--- /dev/null
+++ b/app/controllers/health_check_controller.rb
@@ -0,0 +1,22 @@
+class HealthCheckController < HealthCheck::HealthCheckController
+ before_action :validate_health_check_access!
+
+ private
+
+ def validate_health_check_access!
+ render_404 unless token_valid?
+ end
+
+ def token_valid?
+ token = params[:token].presence || request.headers['TOKEN']
+ token.present? &&
+ ActiveSupport::SecurityUtils.variable_size_secure_compare(
+ token,
+ current_application_settings.health_check_access_token
+ )
+ end
+
+ def render_404
+ render file: Rails.root.join('public', '404'), layout: false, status: '404'
+ end
+end
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
new file mode 100644
index 00000000000..014b9b43ff2
--- /dev/null
+++ b/app/controllers/jwt_controller.rb
@@ -0,0 +1,49 @@
+class JwtController < ApplicationController
+ skip_before_action :authenticate_user!
+ skip_before_action :verify_authenticity_token
+ before_action :authenticate_project_or_user
+
+ SERVICES = {
+ Auth::ContainerRegistryAuthenticationService::AUDIENCE => Auth::ContainerRegistryAuthenticationService,
+ }
+
+ def auth
+ service = SERVICES[params[:service]]
+ return head :not_found unless service
+
+ result = service.new(@project, @user, auth_params).execute
+
+ render json: result, status: result[:http_status]
+ end
+
+ private
+
+ def authenticate_project_or_user
+ authenticate_with_http_basic do |login, password|
+ # if it's possible we first try to authenticate project with login and password
+ @project = authenticate_project(login, password)
+ return if @project
+
+ @user = authenticate_user(login, password)
+ return if @user
+
+ render_403
+ end
+ end
+
+ def auth_params
+ params.permit(:service, :scope, :account, :client_id)
+ end
+
+ def authenticate_project(login, password)
+ if login == 'gitlab-ci-token'
+ Project.find_by(builds_enabled: true, runners_token: password)
+ end
+ end
+
+ def authenticate_user(login, password)
+ user = Gitlab::Auth.find_with_user_password(login, password)
+ Gitlab::Auth.rate_limit!(request.ip, success: user.present?, login: login)
+ user
+ end
+end
diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb
index c6bdd0602c1..0f54dfa4efc 100644
--- a/app/controllers/oauth/applications_controller.rb
+++ b/app/controllers/oauth/applications_controller.rb
@@ -32,7 +32,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
def verify_user_oauth_applications_enabled
return if current_application_settings.user_oauth_applications?
- redirect_to applications_profile_url
+ redirect_to profile_path
end
def set_index_vars
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index df98f56a1cd..f35d631df0c 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -97,7 +97,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
handle_signup_error
end
- def handle_service_ticket provider, ticket
+ def handle_service_ticket(provider, ticket)
Gitlab::OAuth::Session.create provider, ticket
session[:service_tickets] ||= {}
session[:service_tickets][provider] = ticket
diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb
index 0ede9b8e21b..1c24c4db993 100644
--- a/app/controllers/profiles/emails_controller.rb
+++ b/app/controllers/profiles/emails_controller.rb
@@ -24,7 +24,7 @@ class Profiles::EmailsController < Profiles::ApplicationController
respond_to do |format|
format.html { redirect_to profile_emails_url }
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb
index a12549d6bcb..830e0b9591b 100644
--- a/app/controllers/profiles/keys_controller.rb
+++ b/app/controllers/profiles/keys_controller.rb
@@ -32,7 +32,7 @@ class Profiles::KeysController < Profiles::ApplicationController
respond_to do |format|
format.html { redirect_to profile_keys_url }
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb
index 18ee55c839a..40d1906a53f 100644
--- a/app/controllers/profiles/notifications_controller.rb
+++ b/app/controllers/profiles/notifications_controller.rb
@@ -1,12 +1,13 @@
class Profiles::NotificationsController < Profiles::ApplicationController
def show
- @user = current_user
- @group_notifications = current_user.notification_settings.for_groups
- @project_notifications = current_user.notification_settings.for_projects
+ @user = current_user
+ @group_notifications = current_user.notification_settings.for_groups
+ @project_notifications = current_user.notification_settings.for_projects
+ @global_notification_setting = current_user.global_notification_setting
end
def update
- if current_user.update_attributes(user_params)
+ if current_user.update_attributes(user_params) && update_notification_settings
flash[:notice] = "Notification settings saved"
else
flash[:alert] = "Failed to save new settings"
@@ -16,6 +17,18 @@ class Profiles::NotificationsController < Profiles::ApplicationController
end
def user_params
- params.require(:user).permit(:notification_email, :notification_level)
+ params.require(:user).permit(:notification_email)
+ end
+
+ def global_notification_setting_params
+ params.require(:global_notification_setting).permit(:level)
+ end
+
+ private
+
+ def update_notification_settings
+ return true unless global_notification_setting_params
+
+ current_user.global_notification_setting.update_attributes(global_notification_setting_params)
end
end
diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb
index 8f83fdd02bc..6a358fdcc05 100644
--- a/app/controllers/profiles/two_factor_auths_controller.rb
+++ b/app/controllers/profiles/two_factor_auths_controller.rb
@@ -1,7 +1,7 @@
class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
skip_before_action :check_2fa_requirement
- def new
+ def show
unless current_user.otp_secret
current_user.otp_secret = User.generate_otp_secret(32)
end
@@ -12,21 +12,22 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
current_user.save! if current_user.changed?
- if two_factor_authentication_required?
+ if two_factor_authentication_required? && !current_user.two_factor_enabled?
if two_factor_grace_period_expired?
- flash.now[:alert] = 'You must enable Two-factor Authentication for your account.'
+ flash.now[:alert] = 'You must enable Two-Factor Authentication for your account.'
else
grace_period_deadline = current_user.otp_grace_period_started_at + two_factor_grace_period.hours
- flash.now[:alert] = "You must enable Two-factor Authentication for your account before #{l(grace_period_deadline)}."
+ flash.now[:alert] = "You must enable Two-Factor Authentication for your account before #{l(grace_period_deadline)}."
end
end
@qr_code = build_qr_code
+ setup_u2f_registration
end
def create
if current_user.validate_and_consume_otp!(params[:pin_code])
- current_user.two_factor_enabled = true
+ current_user.otp_required_for_login = true
@codes = current_user.generate_otp_backup_codes!
current_user.save!
@@ -34,8 +35,23 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
else
@error = 'Invalid pin code'
@qr_code = build_qr_code
+ setup_u2f_registration
+ render 'show'
+ end
+ end
+
+ # A U2F (universal 2nd factor) device's information is stored after successful
+ # registration, which is then used while 2FA authentication is taking place.
+ def create_u2f
+ @u2f_registration = U2fRegistration.register(current_user, u2f_app_id, params[:device_response], session[:challenges])
- render 'new'
+ if @u2f_registration.persisted?
+ session.delete(:challenges)
+ redirect_to profile_account_path, notice: "Your U2F device was registered!"
+ else
+ @qr_code = build_qr_code
+ setup_u2f_registration
+ render :show
end
end
@@ -70,4 +86,21 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
def issuer_host
Gitlab.config.gitlab.host
end
+
+ # Setup in preparation of communication with a U2F (universal 2nd factor) device
+ # Actual communication is performed using a Javascript API
+ def setup_u2f_registration
+ @u2f_registration ||= U2fRegistration.new
+ @registration_key_handles = current_user.u2f_registrations.pluck(:key_handle)
+ u2f = U2F::U2F.new(u2f_app_id)
+
+ registration_requests = u2f.registration_requests
+ sign_requests = u2f.authentication_requests(@registration_key_handles)
+ session[:challenges] = registration_requests.map(&:challenge)
+
+ 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? })
+ end
end
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index be872a93fee..776ba92c9ab 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -26,7 +26,7 @@ class Projects::ApplicationController < ApplicationController
project_path = "#{namespace}/#{id}"
@project = Project.find_with_namespace(project_path)
- if @project && can?(current_user, :read_project, @project)
+ if can?(current_user, :read_project, @project) && !@project.pending_delete?
if @project.path_with_namespace != project_path
redirect_to request.original_url.gsub(project_path, @project.path_with_namespace)
end
diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb
index cfea1266516..832d7deb57d 100644
--- a/app/controllers/projects/artifacts_controller.rb
+++ b/app/controllers/projects/artifacts_controller.rb
@@ -37,7 +37,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
private
def build
- @build ||= project.builds.unscoped.find_by!(id: params[:build_id])
+ @build ||= project.builds.find_by!(id: params[:build_id])
end
def artifacts_file
diff --git a/app/controllers/projects/avatars_controller.rb b/app/controllers/projects/avatars_controller.rb
index 72921b3aa14..5962f74c39b 100644
--- a/app/controllers/projects/avatars_controller.rb
+++ b/app/controllers/projects/avatars_controller.rb
@@ -10,10 +10,7 @@ class Projects::AvatarsController < Projects::ApplicationController
return if cached_blob?
- headers.store(*Gitlab::Workhorse.send_git_blob(@repository, @blob))
- headers['Content-Disposition'] = 'inline'
- headers['Content-Type'] = safe_content_type(@blob)
- head :ok # 'render nothing: true' messes up the Content-Type
+ send_git_blob @repository, @blob
else
render_404
end
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index d09e7375b67..dd9508da049 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -50,7 +50,7 @@ class Projects::BranchesController < Projects::ApplicationController
redirect_to namespace_project_branches_path(@project.namespace,
@project), status: 303
end
- format.js { render status: status[:return_code] }
+ format.js { render nothing: true, status: status[:return_code] }
end
end
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
index b8b9e78427d..14c82826342 100644
--- a/app/controllers/projects/builds_controller.rb
+++ b/app/controllers/projects/builds_controller.rb
@@ -26,9 +26,9 @@ class Projects::BuildsController < Projects::ApplicationController
end
def show
- @builds = @project.ci_commits.find_by_sha(@build.sha).builds.order('id DESC')
+ @builds = @project.pipelines.find_by_sha(@build.sha).builds.order('id DESC')
@builds = @builds.where("id not in (?)", @build.id)
- @commit = @build.commit
+ @pipeline = @build.pipeline
respond_to do |format|
format.html
@@ -38,6 +38,14 @@ class Projects::BuildsController < Projects::ApplicationController
end
end
+ def trace
+ respond_to do |format|
+ format.json do
+ render json: @build.trace_with_state(params[:state].presence).merge!(id: @build.id, status: @build.status)
+ end
+ end
+ end
+
def retry
unless @build.retryable?
return render_404
@@ -73,7 +81,7 @@ class Projects::BuildsController < Projects::ApplicationController
private
def build
- @build ||= project.builds.unscoped.find_by!(id: params[:id])
+ @build ||= project.builds.find_by!(id: params[:id])
end
def build_path(build)
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index a202cb38692..20637fa46fe 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -17,12 +17,12 @@ class Projects::CommitController < Projects::ApplicationController
def show
apply_diff_view_cookie!
- @line_notes = commit.notes.inline
+ @grouped_diff_notes = commit.notes.grouped_diff_notes
+
@note = @project.build_commit_note(commit)
- @notes = commit.notes.not_inline.fresh
+ @notes = commit.notes.non_diff_notes.fresh
@noteable = @commit
- @comments_allowed = @reply_allowed = true
- @comments_target = {
+ @comments_target = {
noteable_type: 'Commit',
commit_id: @commit.id
}
@@ -67,10 +67,10 @@ class Projects::CommitController < Projects::ApplicationController
create_commit(Commits::RevertService, success_notice: "The #{@commit.change_type_title} has been successfully reverted.",
success_path: successful_change_path, failure_path: failed_change_path)
end
-
+
def cherry_pick
assign_change_commit_vars(@commit.cherry_pick_branch_name)
-
+
return render_404 if @target_branch.blank?
create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title} has been successfully cherry-picked.",
@@ -99,12 +99,12 @@ class Projects::CommitController < Projects::ApplicationController
@commit ||= @project.commit(params[:id])
end
- def ci_commits
- @ci_commits ||= project.ci_commits.where(sha: commit.sha)
+ def pipelines
+ @pipelines ||= project.pipelines.where(sha: commit.sha)
end
def ci_builds
- @ci_builds ||= Ci::Build.where(commit: ci_commits)
+ @ci_builds ||= Ci::Build.where(pipeline: pipelines)
end
def define_show_vars
@@ -117,8 +117,8 @@ class Projects::CommitController < Projects::ApplicationController
@diff_refs = [commit.parent || commit, commit]
@notes_count = commit.notes.count
- @statuses = CommitStatus.where(commit: ci_commits)
- @builds = Ci::Build.where(commit: ci_commits)
+ @statuses = CommitStatus.where(pipeline: pipelines)
+ @builds = Ci::Build.where(pipeline: pipelines)
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 671d5c23024..af0b69a2442 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -22,7 +22,8 @@ class Projects::CompareController < Projects::ApplicationController
@base_commit = @project.merge_base_commit(@base_ref, @head_ref)
@diffs = compare.diffs(diff_options)
@diff_refs = [@base_commit, @commit]
- @line_notes = []
+ @diff_notes_disabled = true
+ @grouped_diff_notes = {}
end
end
diff --git a/app/controllers/projects/container_registry_controller.rb b/app/controllers/projects/container_registry_controller.rb
new file mode 100644
index 00000000000..d1f46497207
--- /dev/null
+++ b/app/controllers/projects/container_registry_controller.rb
@@ -0,0 +1,34 @@
+class Projects::ContainerRegistryController < Projects::ApplicationController
+ before_action :verify_registry_enabled
+ before_action :authorize_read_container_image!
+ before_action :authorize_update_container_image!, only: [:destroy]
+ layout 'project'
+
+ def index
+ @tags = container_registry_repository.tags
+ end
+
+ def destroy
+ url = namespace_project_container_registry_index_path(project.namespace, project)
+
+ if tag.delete
+ redirect_to url
+ else
+ redirect_to url, alert: 'Failed to remove tag'
+ end
+ end
+
+ private
+
+ def verify_registry_enabled
+ render_404 unless Gitlab.config.registry.enabled
+ end
+
+ def container_registry_repository
+ @container_registry_repository ||= project.container_registry_repository
+ end
+
+ def tag
+ @tag ||= container_registry_repository.tag(params[:id])
+ end
+end
diff --git a/app/controllers/projects/find_file_controller.rb b/app/controllers/projects/find_file_controller.rb
index 54a0c447aee..cf53ad0a670 100644
--- a/app/controllers/projects/find_file_controller.rb
+++ b/app/controllers/projects/find_file_controller.rb
@@ -1,26 +1,26 @@
-# Controller for viewing a repository's file structure
-class Projects::FindFileController < Projects::ApplicationController
- include ExtractsPath
- include ActionView::Helpers::SanitizeHelper
- include TreeHelper
-
- before_action :require_non_empty_project
- before_action :assign_ref_vars
- before_action :authorize_download_code!
-
- def show
- return render_404 unless @repository.commit(@ref)
-
- respond_to do |format|
- format.html
- end
- end
-
- def list
- file_paths = @repo.ls_files(@ref)
-
- respond_to do |format|
- format.json { render json: file_paths }
- end
- end
-end
+# Controller for viewing a repository's file structure
+class Projects::FindFileController < Projects::ApplicationController
+ include ExtractsPath
+ include ActionView::Helpers::SanitizeHelper
+ include TreeHelper
+
+ before_action :require_non_empty_project
+ before_action :assign_ref_vars
+ before_action :authorize_download_code!
+
+ def show
+ return render_404 unless @repository.commit(@ref)
+
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def list
+ file_paths = @repo.ls_files(@ref)
+
+ respond_to do |format|
+ format.json { render json: file_paths }
+ end
+ end
+end
diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb
new file mode 100644
index 00000000000..f907d63258b
--- /dev/null
+++ b/app/controllers/projects/git_http_controller.rb
@@ -0,0 +1,147 @@
+class Projects::GitHttpController < Projects::ApplicationController
+ 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!
+
+ # 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
+ if upload_pack? && upload_pack_allowed?
+ render_ok
+ elsif receive_pack? && receive_pack_allowed?
+ render_ok
+ else
+ render_not_found
+ end
+ end
+
+ # POST /foo/bar.git/git-upload-pack (git pull)
+ def git_upload_pack
+ if upload_pack? && upload_pack_allowed?
+ render_ok
+ else
+ render_not_found
+ end
+ end
+
+ # POST /foo/bar.git/git-receive-pack" (git push)
+ def git_receive_pack
+ if receive_pack? && receive_pack_allowed?
+ render_ok
+ else
+ render_not_found
+ end
+ end
+
+ private
+
+ def authenticate_user
+ return if project && project.public? && upload_pack?
+
+ authenticate_or_request_with_http_basic do |login, password|
+ 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
+
+ ci? || user
+ end
+ 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 upload_pack?
+ git_command == 'git-upload-pack'
+ end
+
+ def receive_pack?
+ git_command == 'git-receive-pack'
+ end
+
+ def git_command
+ if action_name == 'info_refs'
+ params[:service]
+ else
+ action_name.dasherize
+ end
+ end
+
+ def render_ok
+ 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 text: 'Not Found', status: :not_found
+ end
+
+ def ci?
+ @ci.present?
+ end
+
+ def upload_pack_allowed?
+ return false unless Gitlab.config.gitlab_shell.upload_pack
+
+ if user
+ Gitlab::GitAccess.new(user, project).download_access_check.allowed?
+ else
+ ci? || project.public?
+ end
+ end
+
+ 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?
+ end
+end
diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb
index dfa9bd259e8..a60027ff477 100644
--- a/app/controllers/projects/hooks_controller.rb
+++ b/app/controllers/projects/hooks_controller.rb
@@ -27,8 +27,10 @@ class Projects::HooksController < Projects::ApplicationController
if !@project.empty_repo?
status, message = TestHookService.new.execute(hook, current_user)
- if status
- flash[:notice] = 'Hook successfully executed.'
+ if status && status >= 200 && status < 400
+ flash[:notice] = "Hook executed successfully: HTTP #{status}"
+ elsif status
+ flash[:alert] = "Hook executed successfully but returned HTTP #{status} #{message}"
else
flash[:alert] = "Hook execution failed: #{message}"
end
@@ -61,7 +63,8 @@ class Projects::HooksController < Projects::ApplicationController
:push_events,
:tag_push_events,
:token,
- :url
+ :url,
+ :wiki_page_events
)
end
end
diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb
index 7756f0f0ed3..a1b84afcd91 100644
--- a/app/controllers/projects/imports_controller.rb
+++ b/app/controllers/projects/imports_controller.rb
@@ -20,6 +20,7 @@ class Projects::ImportsController < Projects::ApplicationController
@project.import_retry
else
@project.import_start
+ @project.add_import_job
end
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 016f5dd0005..4e2d3bebb2e 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -1,6 +1,7 @@
class Projects::IssuesController < Projects::ApplicationController
include ToggleSubscriptionAction
include IssuableActions
+ include ToggleAwardEmoji
before_action :module_enabled
before_action :issue, only: [:edit, :update, :show, :referenced_merge_requests,
@@ -62,7 +63,7 @@ class Projects::IssuesController < Projects::ApplicationController
def show
@note = @project.notes.new(noteable: @issue)
- @notes = @issue.notes.nonawards.with_associations.fresh
+ @notes = @issue.notes.with_associations.fresh
@noteable = @issue
respond_to do |format|
@@ -155,7 +156,12 @@ class Projects::IssuesController < Projects::ApplicationController
def bulk_update
result = Issues::BulkUpdateService.new(project, current_user, bulk_update_params).execute
- redirect_back_or_default(default: { action: 'index' }, options: { notice: "#{result[:count]} issues updated" })
+
+ respond_to do |format|
+ format.json do
+ render json: { notice: "#{result[:count]} issues updated" }
+ end
+ end
end
protected
@@ -169,6 +175,7 @@ class Projects::IssuesController < Projects::ApplicationController
end
alias_method :subscribable_resource, :issue
alias_method :issuable, :issue
+ alias_method :awardable, :issue
def authorize_read_issue!
return render_404 unless can?(current_user, :read_issue, @issue)
@@ -214,7 +221,10 @@ class Projects::IssuesController < Projects::ApplicationController
:issues_ids,
:assignee_id,
:milestone_id,
- :state_event
+ :state_event,
+ label_ids: [],
+ add_label_ids: [],
+ remove_label_ids: []
)
end
end
diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb
index ff771ea6d9c..0ca675623e5 100644
--- a/app/controllers/projects/labels_controller.rb
+++ b/app/controllers/projects/labels_controller.rb
@@ -5,13 +5,14 @@ class Projects::LabelsController < Projects::ApplicationController
before_action :label, only: [:edit, :update, :destroy]
before_action :authorize_read_label!
before_action :authorize_admin_labels!, only: [
- :new, :create, :edit, :update, :generate, :destroy
+ :new, :create, :edit, :update, :generate, :destroy, :remove_priority, :set_priorities
]
respond_to :js, :html
def index
- @labels = @project.labels.page(params[:page])
+ @labels = @project.labels.unprioritized.page(params[:page])
+ @prioritized_labels = @project.labels.prioritized
respond_to do |format|
format.html
@@ -71,6 +72,30 @@ class Projects::LabelsController < Projects::ApplicationController
end
end
+ def remove_priority
+ respond_to do |format|
+ if label.update_attribute(:priority, nil)
+ format.json { render json: label }
+ else
+ message = label.errors.full_messages.uniq.join('. ')
+ format.json { render json: { message: message }, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ def set_priorities
+ Label.transaction do
+ params[:label_ids].each_with_index do |label_id, index|
+ label = @project.labels.find_by_id(label_id)
+ label.update_attribute(:priority, index) if label
+ end
+ end
+
+ respond_to do |format|
+ format.json { render json: { message: 'success' } }
+ end
+ end
+
protected
def module_enabled
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 9c147b3689e..67e7187c10d 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -2,6 +2,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
include ToggleSubscriptionAction
include DiffHelper
include IssuableActions
+ include ToggleAwardEmoji
before_action :module_enabled
before_action :merge_request, only: [
@@ -57,9 +58,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController
respond_to do |format|
format.html
- format.json { render json: @merge_request }
- format.diff { render text: @merge_request.to_diff }
- format.patch { render text: @merge_request.to_patch }
+ format.json { render json: @merge_request }
+ format.patch { render text: @merge_request.to_patch }
+ format.diff do
+ return render_404 unless @merge_request.diff_refs
+
+ send_git_diff @project.repository, @merge_request.diff_refs
+ end
end
end
@@ -73,12 +78,12 @@ class Projects::MergeRequestsController < Projects::ApplicationController
# but we need it for the "View file @ ..." link by deleted files
@base_commit ||= @merge_request.first_commit.parent || @merge_request.first_commit
- @comments_allowed = @reply_allowed = true
@comments_target = {
noteable_type: 'MergeRequest',
noteable_id: @merge_request.id
}
- @line_notes = @merge_request.notes.where("line_code is not null")
+
+ @grouped_diff_notes = @merge_request.notes.grouped_diff_notes
respond_to do |format|
format.html
@@ -117,9 +122,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commit = @merge_request.last_commit
@base_commit = @merge_request.diff_base_commit
@diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare
+ @diff_notes_disabled = true
- @ci_commit = @merge_request.ci_commit
- @statuses = @ci_commit.statuses if @ci_commit
+ @pipeline = @merge_request.pipeline
+ @statuses = @pipeline.statuses if @pipeline
@note_counts = Note.where(commit_id: @commits.map(&:id)).
group(:commit_id).count
@@ -189,13 +195,18 @@ class Projects::MergeRequestsController < Projects::ApplicationController
return
end
+ if params[:sha] != @merge_request.source_sha
+ @status = :sha_mismatch
+ return
+ end
+
TodoService.new.merge_merge_request(merge_request, current_user)
@merge_request.update(merge_error: nil)
- if params[:merge_when_build_succeeds].present? && @merge_request.ci_commit && @merge_request.ci_commit.active?
+ if params[:merge_when_build_succeeds].present? && @merge_request.pipeline && @merge_request.pipeline.active?
MergeRequests::MergeWhenBuildSucceedsService.new(@project, current_user, merge_params)
- .execute(@merge_request)
+ .execute(@merge_request)
@status = :merge_when_build_succeeds
else
MergeWorker.perform_async(@merge_request.id, current_user.id, params)
@@ -204,7 +215,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def branch_from
- #This is always source
+ # This is always source
@source_project = @merge_request.nil? ? @project : @merge_request.source_project
@commit = @repository.commit(params[:ref]) if params[:ref].present?
render layout: false
@@ -224,10 +235,12 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def ci_status
- ci_commit = @merge_request.ci_commit
- if ci_commit
- status = ci_commit.status
- coverage = ci_commit.try(:coverage)
+ pipeline = @merge_request.pipeline
+ if pipeline
+ status = pipeline.status
+ coverage = pipeline.try(:coverage)
+
+ 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
@@ -237,8 +250,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
- status = "preparing" if status.nil?
-
response = {
title: merge_request.title,
sha: merge_request.last_commit_short_sha,
@@ -264,6 +275,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
alias_method :subscribable_resource, :merge_request
alias_method :issuable, :merge_request
+ alias_method :awardable, :merge_request
def closes_issues
@closes_issues ||= @merge_request.closes_issues
@@ -299,8 +311,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
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.nonawards.inc_author.fresh
- @discussions = Note.discussions_from_notes(@notes)
+ @notes = @merge_request.mr_and_commit_notes.inc_author.fresh
+ @discussions = @notes.discussions
@noteable = @merge_request
# Get commits from repository
@@ -309,8 +321,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@merge_request_diff = @merge_request.merge_request_diff
- @ci_commit = @merge_request.ci_commit
- @statuses = @ci_commit.statuses if @ci_commit
+ @pipeline = @merge_request.pipeline
+ @statuses = @pipeline.statuses if @pipeline
if @merge_request.locked_long_ago?
@merge_request.unlock_mr
@@ -319,8 +331,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def define_widget_vars
- @ci_commit = @merge_request.ci_commit
- @ci_commits = [@ci_commit].compact
+ @pipeline = @merge_request.pipeline
+ @pipelines = [@pipeline].compact
closes_issues
end
@@ -333,7 +345,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
params.require(:merge_request).permit(
:title, :assignee_id, :source_project_id, :source_branch,
:target_project_id, :target_branch, :milestone_id,
- :state_event, :description, :task_num, label_ids: []
+ :state_event, :description, :task_num, :force_remove_source_branch,
+ label_ids: []
)
end
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index f7b6d137bde..da2892bfb3f 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -75,7 +75,7 @@ class Projects::MilestonesController < Projects::ApplicationController
respond_to do |format|
format.html { redirect_to namespace_project_milestones_path }
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 707a0d0e5c6..836f79ff080 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -1,9 +1,11 @@
class Projects::NotesController < Projects::ApplicationController
+ include ToggleAwardEmoji
+
# Authorize
before_action :authorize_read_note!
before_action :authorize_create_note!, only: [:create]
before_action :authorize_admin_note!, only: [:update, :destroy]
- before_action :find_current_user_notes, except: [:destroy, :delete_attachment, :award_toggle]
+ before_action :find_current_user_notes, only: [:index]
def index
current_fetched_at = Time.now.to_i
@@ -43,7 +45,7 @@ class Projects::NotesController < Projects::ApplicationController
end
respond_to do |format|
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
@@ -52,39 +54,16 @@ class Projects::NotesController < Projects::ApplicationController
note.update_attribute(:attachment, nil)
respond_to do |format|
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
- def award_toggle
- noteable = if note_params[:noteable_type] == "issue"
- project.issues.find(note_params[:noteable_id])
- else
- project.merge_requests.find(note_params[:noteable_id])
- end
-
- data = {
- author: current_user,
- is_award: true,
- note: note_params[:note].delete(":")
- }
-
- note = noteable.notes.find_by(data)
-
- if note
- note.destroy
- else
- Notes::CreateService.new(project, current_user, note_params).execute
- end
-
- render json: { ok: true }
- end
-
private
def note
@note ||= @project.notes.find(params[:id])
end
+ alias_method :awardable, :note
def note_to_html(note)
render_to_string(
@@ -96,7 +75,7 @@ class Projects::NotesController < Projects::ApplicationController
end
def note_to_discussion_html(note)
- return unless note.for_diff_line?
+ return unless note.diff_note?
if params[:view] == 'parallel'
template = "projects/notes/_diff_notes_with_reply_parallel"
@@ -120,7 +99,7 @@ class Projects::NotesController < Projects::ApplicationController
end
def note_to_discussion_with_diff_html(note)
- return unless note.for_diff_line?
+ return unless note.diff_note?
render_to_string(
"projects/notes/_discussion",
@@ -131,13 +110,20 @@ class Projects::NotesController < Projects::ApplicationController
end
def note_json(note)
- if note.valid?
+ if note.is_a?(AwardEmoji)
+ {
+ valid: note.valid?,
+ award: true,
+ id: note.id,
+ name: note.name
+ }
+ elsif note.valid?
{
valid: true,
id: note.id,
discussion_id: note.discussion_id,
html: note_to_html(note),
- award: note.is_award,
+ award: false,
note: note.note,
discussion_html: note_to_discussion_html(note),
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
@@ -145,7 +131,7 @@ class Projects::NotesController < Projects::ApplicationController
else
{
valid: false,
- award: note.is_award,
+ award: false,
errors: note.errors
}
end
@@ -158,7 +144,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
+ :attachment, :line_code, :commit_id, :type
)
end
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
new file mode 100644
index 00000000000..cac440ae53e
--- /dev/null
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -0,0 +1,59 @@
+class Projects::PipelinesController < Projects::ApplicationController
+ before_action :pipeline, except: [:index, :new, :create]
+ before_action :commit, only: [:show]
+ before_action :authorize_read_pipeline!
+ before_action :authorize_create_pipeline!, only: [:new, :create]
+ before_action :authorize_update_pipeline!, only: [:retry, :cancel]
+
+ def index
+ @scope = params[:scope]
+ all_pipelines = project.pipelines
+ @pipelines_count = all_pipelines.count
+ @running_or_pending_count = all_pipelines.running_or_pending.count
+ @pipelines = PipelinesFinder.new(project).execute(all_pipelines, @scope)
+ @pipelines = @pipelines.order(id: :desc).page(params[:page]).per(30)
+ end
+
+ def new
+ @pipeline = project.pipelines.new(ref: @project.default_branch)
+ end
+
+ def create
+ @pipeline = Ci::CreatePipelineService.new(project, current_user, create_params).execute
+ unless @pipeline.persisted?
+ render 'new'
+ return
+ end
+
+ redirect_to namespace_project_pipeline_path(project.namespace, project, @pipeline)
+ end
+
+ def show
+ end
+
+ def retry
+ pipeline.retry_failed
+
+ redirect_back_or_default default: namespace_project_pipelines_path(project.namespace, project)
+ end
+
+ def cancel
+ pipeline.cancel_running
+
+ redirect_back_or_default default: namespace_project_pipelines_path(project.namespace, project)
+ end
+
+ private
+
+ def create_params
+ params.require(:pipeline).permit(:ref)
+ end
+
+ def pipeline
+ @pipeline ||= project.pipelines.find_by!(id: params[:id])
+ end
+
+ def commit
+ @commit ||= @pipeline.commit_data
+ end
+end
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index 33b2625c0ac..cdea5f0b776 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -55,7 +55,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
format.html do
redirect_to namespace_project_project_members_path(@project.namespace, @project)
end
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
@@ -81,7 +81,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
respond_to do |format|
format.html { redirect_to dashboard_projects_path, notice: "You left the project." }
- format.js { render nothing: true }
+ format.js { head :ok }
end
else
if current_user == @project.owner
diff --git a/app/controllers/projects/protected_branches_controller.rb b/app/controllers/projects/protected_branches_controller.rb
index e49259c34b6..efa7bf14d0f 100644
--- a/app/controllers/projects/protected_branches_controller.rb
+++ b/app/controllers/projects/protected_branches_controller.rb
@@ -39,7 +39,7 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
respond_to do |format|
format.html { redirect_to namespace_project_protected_branches_path }
- format.js { render nothing: true }
+ format.js { head :ok }
end
end
diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb
index 10de0e60530..10d24da16d7 100644
--- a/app/controllers/projects/raw_controller.rb
+++ b/app/controllers/projects/raw_controller.rb
@@ -18,10 +18,7 @@ class Projects::RawController < Projects::ApplicationController
if @blob.lfs_pointer?
send_lfs_object
else
- headers.store(*Gitlab::Workhorse.send_git_blob(@repository, @blob))
- headers['Content-Disposition'] = 'inline'
- headers['Content-Type'] = safe_content_type(@blob)
- head :ok # 'render nothing: true' messes up the Content-Type
+ send_git_blob @repository, @blob
end
else
render_404
diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb
index bb7a6b6a5ab..d5af0341d18 100644
--- a/app/controllers/projects/repositories_controller.rb
+++ b/app/controllers/projects/repositories_controller.rb
@@ -11,8 +11,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
end
def archive
- headers.store(*Gitlab::Workhorse.send_git_archive(@project, params[:ref], params[:format]))
- head :ok
+ send_git_archive @repository, ref: params[:ref], format: params[:format]
rescue => ex
logger.error("#{self.class.name}: #{ex}")
return git_not_found!
diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb
index 0dd2d6a99be..0b4fa572501 100644
--- a/app/controllers/projects/runners_controller.rb
+++ b/app/controllers/projects/runners_controller.rb
@@ -20,7 +20,7 @@ class Projects::RunnersController < Projects::ApplicationController
if @runner.update_attributes(runner_params)
redirect_to runner_path(@runner), notice: 'Runner was successfully updated.'
else
- redirect_to runner_path(@runner), alert: 'Runner was not updated.'
+ render 'edit'
end
end
@@ -64,6 +64,6 @@ class Projects::RunnersController < Projects::ApplicationController
end
def runner_params
- params.require(:runner).permit(:description, :tag_list, :active)
+ params.require(:runner).permit(Ci::Runner::FORM_EDITABLE)
end
end
diff --git a/app/controllers/projects/variables_controller.rb b/app/controllers/projects/variables_controller.rb
index 00234654578..6f068729390 100644
--- a/app/controllers/projects/variables_controller.rb
+++ b/app/controllers/projects/variables_controller.rb
@@ -3,20 +3,44 @@ class Projects::VariablesController < Projects::ApplicationController
layout 'project_settings'
+ def index
+ @variable = Ci::Variable.new
+ end
+
def show
+ @variable = @project.variables.find(params[:id])
end
def update
- if project.update_attributes(project_params)
+ @variable = @project.variables.find(params[:id])
+
+ if @variable.update_attributes(project_params)
+ redirect_to namespace_project_variables_path(project.namespace, project), notice: 'Variable was successfully updated.'
+ else
+ render action: "show"
+ end
+ end
+
+ def create
+ @variable = Ci::Variable.new(project_params)
+
+ if @variable.valid? && @project.variables << @variable
redirect_to namespace_project_variables_path(project.namespace, project), notice: 'Variables were successfully updated.'
else
- render action: 'show'
+ render action: "index"
end
end
+ def destroy
+ @key = @project.variables.find(params[:id])
+ @key.destroy
+
+ redirect_to namespace_project_variables_path(project.namespace, project), notice: 'Variable was successfully removed.'
+ end
+
private
def project_params
- params.require(:project).permit({ variables_attributes: [:id, :key, :value, :_destroy] })
+ params.require(:variable).permit([:id, :key, :value, :_destroy])
end
end
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index 0d6c32fabd2..2aa6bed0724 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -91,11 +91,11 @@ class Projects::WikisController < Projects::ApplicationController
def markdown_preview
text = params[:text]
- ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user)
- ext.analyze(text)
+ ext = Gitlab::ReferenceExtractor.new(@project, current_user)
+ ext.analyze(text, author: current_user)
render json: {
- body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki),
+ body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki, page_slug: params[:id]),
references: {
users: ext.users.map(&:username)
}
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 3768efe142a..a6479c42d94 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -101,13 +101,7 @@ class ProjectsController < Projects::ApplicationController
respond_to do |format|
format.html do
- if current_user
- @membership = @project.team.find_member(current_user.id)
-
- if @membership
- @notification_setting = current_user.notification_settings_for(@project)
- end
- end
+ @notification_setting = current_user.notification_settings_for(@project) if current_user
if @project.repository_exists?
if @project.empty_repo?
@@ -145,8 +139,9 @@ class ProjectsController < Projects::ApplicationController
participants = ::Projects::ParticipantsService.new(@project, current_user).execute(note_type, note_id)
@suggestions = {
- emojis: AwardEmoji.urls,
+ emojis: Gitlab::AwardEmoji.urls,
issues: autocomplete.issues,
+ milestones: autocomplete.milestones,
mergerequests: autocomplete.merge_requests,
members: participants
}
@@ -202,8 +197,8 @@ class ProjectsController < Projects::ApplicationController
def markdown_preview
text = params[:text]
- ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user)
- ext.analyze(text)
+ ext = Gitlab::ReferenceExtractor.new(@project, current_user)
+ ext.analyze(text, author: current_user)
render json: {
body: view_context.markdown(text),
@@ -235,10 +230,11 @@ class ProjectsController < Projects::ApplicationController
def project_params
params.require(:project).permit(
:name, :path, :description, :issues_tracker, :tag_list, :runners_token,
- :issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch,
+ :issues_enabled, :merge_requests_enabled, :snippets_enabled, :container_registry_enabled,
+ :issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
:builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
- :public_builds,
+ :public_builds, :only_allow_merge_if_build_succeeds
)
end
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 352bff19383..75b78a49eab 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -37,8 +37,8 @@ class RegistrationsController < Devise::RegistrationsController
super
end
- def after_sign_up_path_for(_resource)
- users_almost_there_path
+ def after_sign_up_path_for(user)
+ user.confirmed? ? dashboard_projects_path : users_almost_there_path
end
def after_inactive_sign_up_path_for(_resource)
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index c29f4609e93..dae8f7b1447 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -1,5 +1,6 @@
class SessionsController < Devise::SessionsController
include AuthenticatesWithTwoFactor
+ include Devise::Controllers::Rememberable
include Recaptcha::ClientHelper
skip_before_action :check_2fa_requirement, only: [:destroy]
@@ -13,6 +14,7 @@ class SessionsController < Devise::SessionsController
before_action :load_recaptcha
def new
+ set_minimum_password_length
if Gitlab.config.ldap.enabled
@ldap_servers = Gitlab::LDAP::Config.servers
else
@@ -29,8 +31,7 @@ class SessionsController < Devise::SessionsController
resource.update_attributes(reset_password_token: nil,
reset_password_sent_at: nil)
end
- authenticated_with = user_params[:otp_attempt] ? "two-factor" : "standard"
- log_audit_event(current_user, with: authenticated_with)
+ log_audit_event(current_user, with: authentication_method)
end
end
@@ -53,7 +54,7 @@ class SessionsController < Devise::SessionsController
end
def user_params
- params.require(:user).permit(:login, :password, :remember_me, :otp_attempt)
+ params.require(:user).permit(:login, :password, :remember_me, :otp_attempt, :device_response)
end
def find_user
@@ -88,26 +89,6 @@ class SessionsController < Devise::SessionsController
find_user.try(:two_factor_enabled?)
end
- def authenticate_with_two_factor
- user = self.resource = find_user
-
- if user_params[:otp_attempt].present? && session[:otp_user_id]
- if valid_otp_attempt?(user)
- # Remove any lingering user data from login
- session.delete(:otp_user_id)
-
- sign_in(user) and return
- else
- flash.now[:alert] = 'Invalid two-factor code.'
- render :two_factor and return
- end
- else
- if user && user.valid_password?(user_params[:password])
- prompt_for_two_factor(user)
- end
- end
- end
-
def auto_sign_in_with_provider
provider = Gitlab.config.omniauth.auto_sign_in_with_provider
return unless provider.present?
@@ -136,4 +117,14 @@ class SessionsController < Devise::SessionsController
def load_recaptcha
Gitlab::Recaptcha.load_configurations!
end
+
+ def authentication_method
+ if user_params[:otp_attempt]
+ "two-factor"
+ elsif user_params[:device_response]
+ "two-factor-via-u2f-device"
+ else
+ "standard"
+ end
+ end
end
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 2daceed039b..2a17c1f34db 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -10,7 +10,7 @@ class SnippetsController < ApplicationController
# Allow destroy snippet
before_action :authorize_admin_snippet!, only: [:destroy]
- skip_before_action :authenticate_user!, only: [:index, :user_index, :show, :raw]
+ skip_before_action :authenticate_user!, only: [:index, :show, :raw]
layout 'snippets'
respond_to :html
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 2ae180c8a12..a99632454d9 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -58,11 +58,22 @@ class UsersController < ApplicationController
end
end
+ def snippets
+ load_snippets
+
+ respond_to do |format|
+ format.html { render 'show' }
+ format.json do
+ render json: {
+ html: view_to_html_string("snippets/_snippets", collection: @snippets)
+ }
+ end
+ end
+ end
+
def calendar
calendar = contributions_calendar
@timestamps = calendar.timestamps
- @starting_year = calendar.starting_year
- @starting_month = calendar.starting_month
render 'calendar', layout: false
end
@@ -116,6 +127,15 @@ class UsersController < ApplicationController
@groups = JoinedGroupsFinder.new(user).execute(current_user)
end
+ def load_snippets
+ @snippets = SnippetsFinder.new.execute(
+ current_user,
+ filter: :by_user,
+ user: user,
+ scope: params[:scope]
+ ).page(params[:page])
+ end
+
def projects_for_current_user
ProjectsFinder.new.execute(current_user)
end