diff options
Diffstat (limited to 'app/controllers')
-rw-r--r-- | app/controllers/account_controller.rb | 3 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 8 | ||||
-rw-r--r-- | app/controllers/auto_completes_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/messages_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/my_controller.rb | 1 | ||||
-rw-r--r-- | app/controllers/news_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/oauth2_applications_controller.rb | 38 | ||||
-rw-r--r-- | app/controllers/previews_controller.rb | 6 | ||||
-rw-r--r-- | app/controllers/projects_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/reactions_controller.rb | 65 | ||||
-rw-r--r-- | app/controllers/repositories_controller.rb | 10 | ||||
-rw-r--r-- | app/controllers/roles_controller.rb | 10 | ||||
-rw-r--r-- | app/controllers/twofa_backup_codes_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/twofa_controller.rb | 16 | ||||
-rw-r--r-- | app/controllers/versions_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/wiki_controller.rb | 1 |
16 files changed, 165 insertions, 13 deletions
diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index 5e615d17f..ea75d5de1 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -36,6 +36,7 @@ class AccountController < ApplicationController redirect_back_or_default home_url, :referer => true end end + no_store rescue AuthSourceException => e logger.error "An error occurred when authenticating #{params[:username]}: #{e.message}" render_error :message => e.message @@ -95,6 +96,7 @@ class AccountController < ApplicationController end end end + no_store render :template => "account/password_recovery" return else @@ -218,6 +220,7 @@ class AccountController < ApplicationController def twofa_confirm @twofa_view = @twofa.otp_confirm_view_variables + no_store end def twofa diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 074392709..a01d5c75f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -131,6 +131,14 @@ class ApplicationController < ActionController::Base if (key = api_key_from_request) # Use API key user = User.find_by_api_key(key) + elsif access_token = Doorkeeper.authenticate(request) + # Oauth + if access_token.accessible? + user = User.active.find_by_id(access_token.resource_owner_id) + user.oauth_scope = access_token.scopes.all.map(&:to_sym) + else + doorkeeper_render_error + end elsif /\ABasic /i.match?(request.authorization.to_s) # HTTP Basic, either username/password or API key/random authenticate_with_http_basic do |username, password| diff --git a/app/controllers/auto_completes_controller.rb b/app/controllers/auto_completes_controller.rb index 2982447e9..77105c8e8 100644 --- a/app/controllers/auto_completes_controller.rb +++ b/app/controllers/auto_completes_controller.rb @@ -26,7 +26,7 @@ class AutoCompletesController < ApplicationController status = params[:status].to_s issue_id = params[:issue_id].to_s - scope = Issue.cross_project_scope(@project, params[:scope]).visible + scope = Issue.cross_project_scope(@project, params[:scope]).includes(:tracker).visible scope = scope.open(status == 'o') if status.present? scope = scope.where.not(:id => issue_id.to_i) if issue_id.present? if q.present? diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 5159bf540..8b26bee73 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -51,6 +51,8 @@ class MessagesController < ApplicationController offset(@reply_pages.offset). to_a + Message.preload_reaction_details(@replies) + @reply = Message.new(:subject => "RE: #{@message.subject}") render :action => "show", :layout => false if request.xhr? end @@ -134,7 +136,7 @@ class MessagesController < ApplicationController def preview message = @board.messages.find_by_id(params[:id]) - @text = params[:text] ? params[:text] : nil + @text = params[:text] || nil @previewed = message render :partial => 'common/preview' end diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 01fe3995c..35483c8ef 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -115,6 +115,7 @@ class MyController < ApplicationController end end end + no_store end # Create a new feeds key diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index 06240e359..dd6bade24 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -67,8 +67,10 @@ class NewsController < ApplicationController end def show - @comments = @news.comments.to_a + @comments = @news.comments.preload(:commented).to_a @comments.reverse! if User.current.wants_comments_in_reverse_order? + + Comment.preload_reaction_details(@comments) end def new diff --git a/app/controllers/oauth2_applications_controller.rb b/app/controllers/oauth2_applications_controller.rb new file mode 100644 index 000000000..107af2ec0 --- /dev/null +++ b/app/controllers/oauth2_applications_controller.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +# +# Redmine - project management software +# Copyright (C) 2006- Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +class Oauth2ApplicationsController < Doorkeeper::ApplicationsController + private + + def application_params + params[:doorkeeper_application] ||= {} + params[:doorkeeper_application][:scopes] ||= [] + + scopes = Redmine::AccessControl.public_permissions.map{|p| p.name.to_s} + + if params[:doorkeeper_application][:scopes].is_a?(Array) + scopes |= params[:doorkeeper_application][:scopes] + else + scopes |= params[:doorkeeper_application][:scopes].split(/\s+/) + end + params[:doorkeeper_application][:scopes] = scopes.join(' ') + super + end +end diff --git a/app/controllers/previews_controller.rb b/app/controllers/previews_controller.rb index 9dd228a3d..744daa7c8 100644 --- a/app/controllers/previews_controller.rb +++ b/app/controllers/previews_controller.rb @@ -26,7 +26,7 @@ class PreviewsController < ApplicationController if @issue @previewed = @issue end - @text = params[:text] ? params[:text] : nil + @text = params[:text] || nil render :partial => 'common/preview' end @@ -34,12 +34,12 @@ class PreviewsController < ApplicationController if params[:id].present? && news = News.visible.find_by_id(params[:id]) @previewed = news end - @text = params[:text] ? params[:text] : nil + @text = params[:text] || nil render :partial => 'common/preview' end def text - @text = params[:text] ? params[:text] : nil + @text = params[:text] || nil render :partial => 'common/preview' end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index f9a390c58..2a42c99ed 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -176,7 +176,7 @@ class ProjectsController < ApplicationController respond_to do |format| format.html do @principals_by_role = @project.principals_by_role - @subprojects = @project.children.visible.to_a + @subprojects = @project.leaf? ? [] : @project.children.visible.to_a @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").to_a with_subprojects = Setting.display_subprojects_issues? @trackers = @project.rolled_up_trackers(with_subprojects).visible diff --git a/app/controllers/reactions_controller.rb b/app/controllers/reactions_controller.rb new file mode 100644 index 000000000..71b37e5f8 --- /dev/null +++ b/app/controllers/reactions_controller.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +# Redmine - project management software +# Copyright (C) 2006- Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class ReactionsController < ApplicationController + before_action :require_login + + before_action :check_enabled + before_action :set_object, :authorize_reactable + + def create + respond_to do |format| + format.js do + @object.reactions.find_or_create_by!(user: User.current) + end + format.any { head :not_found } + end + end + + def destroy + respond_to do |format| + format.js do + reaction = @object.reactions.by(User.current).find_by(id: params[:id]) + reaction&.destroy + end + format.any { head :not_found } + end + end + + private + + def check_enabled + render_403 unless Setting.reactions_enabled? + end + + def set_object + object_type = params[:object_type] + + unless Redmine::Reaction::REACTABLE_TYPES.include?(object_type) + render_403 + return + end + + @object = object_type.constantize.find(params[:object_id]) + end + + def authorize_reactable + render_403 unless Redmine::Reaction.editable?(@object, User.current) + end +end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 9be7878ce..d6a13daf2 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -160,7 +160,15 @@ class RepositoriesController < ApplicationController # Force the download send_opt = {:filename => filename_for_content_disposition(@path.split('/').last)} send_type = Redmine::MimeType.of(@path) - send_opt[:type] = send_type.to_s if send_type + case send_type + when nil + # No MIME type detected. Let Rails use the default type. + when 'application/javascript' + # Avoid ActionController::InvalidCrossOriginRequest exception by setting non-JS content type + send_opt[:type] = 'text/plain' + else + send_opt[:type] = send_type + end send_opt[:disposition] = disposition(@path) send_data @repository.cat(@path, @rev), send_opt else diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index dfe7c2b8f..89f9ee497 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -99,7 +99,15 @@ class RolesController < ApplicationController begin @role.destroy rescue - flash[:error] = l(:error_can_not_remove_role) + flash[:error] = l(:error_can_not_remove_role) + + if @role.members.present? + projects = Project.joins(members: :member_roles).where(member_roles: { role_id: @role.id }).distinct.sorted + links = projects.map do |p| + view_context.link_to(p, settings_project_path(p, tab: 'members')) + end.join(', ') + flash[:error] += l(:error_can_not_remove_role_reason_members_html, projects: links) + end end redirect_to roles_path end diff --git a/app/controllers/twofa_backup_codes_controller.rb b/app/controllers/twofa_backup_codes_controller.rb index 8e14247b0..923b9671b 100644 --- a/app/controllers/twofa_backup_codes_controller.rb +++ b/app/controllers/twofa_backup_codes_controller.rb @@ -26,7 +26,7 @@ class TwofaBackupCodesController < ApplicationController before_action :twofa_setup - require_sudo_mode :init + require_sudo_mode :init, :confirm, :create, :show def init if @twofa.send_code(controller: 'twofa_backup_codes', action: 'create') @@ -37,6 +37,7 @@ class TwofaBackupCodesController < ApplicationController def confirm @twofa_view = @twofa.otp_confirm_view_variables + no_store end def create @@ -64,6 +65,7 @@ class TwofaBackupCodesController < ApplicationController if tokens.present? && (@created_at = tokens.collect(&:created_on).max) > 5.minutes.ago @backup_codes = tokens.collect(&:value) + no_store else flash[:warning] = l('twofa_backup_codes_already_shown', bc_path: my_twofa_backup_codes_init_path) redirect_to controller: 'my', action: 'account' diff --git a/app/controllers/twofa_controller.rb b/app/controllers/twofa_controller.rb index 446d2f105..3023caa9b 100644 --- a/app/controllers/twofa_controller.rb +++ b/app/controllers/twofa_controller.rb @@ -27,10 +27,14 @@ class TwofaController < ApplicationController before_action :require_active_twofa - require_sudo_mode :activate_init, :deactivate_init + require_sudo_mode :select_scheme, + :activate_init, :activate_confirm, :activate, + :deactivate_init, :deactivate_confirm, :deactivate skip_before_action :check_twofa_activation, only: [:select_scheme, :activate_init, :activate_confirm, :activate] + before_action :ensure_user_has_no_twofa, only: [:select_scheme, :activate_init, :activate_confirm, :activate] + def select_scheme @user = User.current end @@ -43,6 +47,7 @@ class TwofaController < ApplicationController def activate_confirm @twofa_view = @twofa.init_pairing_view_variables + no_store end def activate @@ -114,4 +119,13 @@ class TwofaController < ApplicationController redirect_to my_account_path end end + + def ensure_user_has_no_twofa + # Allow activating a new 2FA scheme / showing twofa secret only if no other + # is already configured + return true if User.current.twofa_scheme.blank? + + flash[:warning] = l('twofa_already_setup') + redirect_to controller: 'my', action: 'account' + end end diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index d52b43ba3..328d3e56e 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -51,7 +51,7 @@ class VersionsController < ApplicationController if @selected_tracker_ids.any? && @versions.any? issues = Issue.visible. includes(:project, :tracker). - preload(:status, :priority, :fixed_version). + preload(:status, :priority, :fixed_version, {:assigned_to => :email_address}). where(:tracker_id => @selected_tracker_ids, :project_id => project_ids, :fixed_version_id => @versions.map(&:id)). order("#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id") @issues_by_version = issues.group_by(&:fixed_version) @@ -69,7 +69,7 @@ class VersionsController < ApplicationController format.html do @issues = @version.fixed_issues.visible. includes(:status, :tracker, :priority). - preload(:project). + preload(:project, {:assigned_to => :email_address}). reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id"). to_a end diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 36b90da77..bcb3b0891 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -240,6 +240,7 @@ class WikiController < ApplicationController # don't load text @versions = @page.content.versions. select("id, author_id, comments, updated_on, version"). + preload(:author). reorder('version DESC'). limit(@version_pages.per_page + 1). offset(@version_pages.offset). |