##// END OF EJS Templates
Fixed: 500 internal error when browsing any Redmine page in Epiphany (#5401)....
Jean-Philippe Lang -
r3588:0d938dff59df
parent child
Show More
@@ -1,341 +1,342
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'uri'
18 require 'uri'
19 require 'cgi'
19 require 'cgi'
20
20
21 class ApplicationController < ActionController::Base
21 class ApplicationController < ActionController::Base
22 include Redmine::I18n
22 include Redmine::I18n
23
23
24 layout 'base'
24 layout 'base'
25 exempt_from_layout 'builder'
25 exempt_from_layout 'builder'
26
26
27 # Remove broken cookie after upgrade from 0.8.x (#4292)
27 # Remove broken cookie after upgrade from 0.8.x (#4292)
28 # See https://rails.lighthouseapp.com/projects/8994/tickets/3360
28 # See https://rails.lighthouseapp.com/projects/8994/tickets/3360
29 # TODO: remove it when Rails is fixed
29 # TODO: remove it when Rails is fixed
30 before_filter :delete_broken_cookies
30 before_filter :delete_broken_cookies
31 def delete_broken_cookies
31 def delete_broken_cookies
32 if cookies['_redmine_session'] && cookies['_redmine_session'] !~ /--/
32 if cookies['_redmine_session'] && cookies['_redmine_session'] !~ /--/
33 cookies.delete '_redmine_session'
33 cookies.delete '_redmine_session'
34 redirect_to home_path
34 redirect_to home_path
35 return false
35 return false
36 end
36 end
37 end
37 end
38
38
39 before_filter :user_setup, :check_if_login_required, :set_localization
39 before_filter :user_setup, :check_if_login_required, :set_localization
40 filter_parameter_logging :password
40 filter_parameter_logging :password
41 protect_from_forgery
41 protect_from_forgery
42
42
43 rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token
43 rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token
44
44
45 include Redmine::Search::Controller
45 include Redmine::Search::Controller
46 include Redmine::MenuManager::MenuController
46 include Redmine::MenuManager::MenuController
47 helper Redmine::MenuManager::MenuHelper
47 helper Redmine::MenuManager::MenuHelper
48
48
49 Redmine::Scm::Base.all.each do |scm|
49 Redmine::Scm::Base.all.each do |scm|
50 require_dependency "repository/#{scm.underscore}"
50 require_dependency "repository/#{scm.underscore}"
51 end
51 end
52
52
53 def user_setup
53 def user_setup
54 # Check the settings cache for each request
54 # Check the settings cache for each request
55 Setting.check_cache
55 Setting.check_cache
56 # Find the current user
56 # Find the current user
57 User.current = find_current_user
57 User.current = find_current_user
58 end
58 end
59
59
60 # Returns the current user or nil if no user is logged in
60 # Returns the current user or nil if no user is logged in
61 # and starts a session if needed
61 # and starts a session if needed
62 def find_current_user
62 def find_current_user
63 if session[:user_id]
63 if session[:user_id]
64 # existing session
64 # existing session
65 (User.active.find(session[:user_id]) rescue nil)
65 (User.active.find(session[:user_id]) rescue nil)
66 elsif cookies[:autologin] && Setting.autologin?
66 elsif cookies[:autologin] && Setting.autologin?
67 # auto-login feature starts a new session
67 # auto-login feature starts a new session
68 user = User.try_to_autologin(cookies[:autologin])
68 user = User.try_to_autologin(cookies[:autologin])
69 session[:user_id] = user.id if user
69 session[:user_id] = user.id if user
70 user
70 user
71 elsif params[:format] == 'atom' && params[:key] && accept_key_auth_actions.include?(params[:action])
71 elsif params[:format] == 'atom' && params[:key] && accept_key_auth_actions.include?(params[:action])
72 # RSS key authentication does not start a session
72 # RSS key authentication does not start a session
73 User.find_by_rss_key(params[:key])
73 User.find_by_rss_key(params[:key])
74 elsif Setting.rest_api_enabled? && ['xml', 'json'].include?(params[:format])
74 elsif Setting.rest_api_enabled? && ['xml', 'json'].include?(params[:format])
75 if params[:key].present? && accept_key_auth_actions.include?(params[:action])
75 if params[:key].present? && accept_key_auth_actions.include?(params[:action])
76 # Use API key
76 # Use API key
77 User.find_by_api_key(params[:key])
77 User.find_by_api_key(params[:key])
78 else
78 else
79 # HTTP Basic, either username/password or API key/random
79 # HTTP Basic, either username/password or API key/random
80 authenticate_with_http_basic do |username, password|
80 authenticate_with_http_basic do |username, password|
81 User.try_to_login(username, password) || User.find_by_api_key(username)
81 User.try_to_login(username, password) || User.find_by_api_key(username)
82 end
82 end
83 end
83 end
84 end
84 end
85 end
85 end
86
86
87 # Sets the logged in user
87 # Sets the logged in user
88 def logged_user=(user)
88 def logged_user=(user)
89 reset_session
89 reset_session
90 if user && user.is_a?(User)
90 if user && user.is_a?(User)
91 User.current = user
91 User.current = user
92 session[:user_id] = user.id
92 session[:user_id] = user.id
93 else
93 else
94 User.current = User.anonymous
94 User.current = User.anonymous
95 end
95 end
96 end
96 end
97
97
98 # check if login is globally required to access the application
98 # check if login is globally required to access the application
99 def check_if_login_required
99 def check_if_login_required
100 # no check needed if user is already logged in
100 # no check needed if user is already logged in
101 return true if User.current.logged?
101 return true if User.current.logged?
102 require_login if Setting.login_required?
102 require_login if Setting.login_required?
103 end
103 end
104
104
105 def set_localization
105 def set_localization
106 lang = nil
106 lang = nil
107 if User.current.logged?
107 if User.current.logged?
108 lang = find_language(User.current.language)
108 lang = find_language(User.current.language)
109 end
109 end
110 if lang.nil? && request.env['HTTP_ACCEPT_LANGUAGE']
110 if lang.nil? && request.env['HTTP_ACCEPT_LANGUAGE']
111 accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.downcase
111 accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first
112 if !accept_lang.blank?
112 if !accept_lang.blank?
113 accept_lang = accept_lang.downcase
113 lang = find_language(accept_lang) || find_language(accept_lang.split('-').first)
114 lang = find_language(accept_lang) || find_language(accept_lang.split('-').first)
114 end
115 end
115 end
116 end
116 lang ||= Setting.default_language
117 lang ||= Setting.default_language
117 set_language_if_valid(lang)
118 set_language_if_valid(lang)
118 end
119 end
119
120
120 def require_login
121 def require_login
121 if !User.current.logged?
122 if !User.current.logged?
122 # Extract only the basic url parameters on non-GET requests
123 # Extract only the basic url parameters on non-GET requests
123 if request.get?
124 if request.get?
124 url = url_for(params)
125 url = url_for(params)
125 else
126 else
126 url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
127 url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
127 end
128 end
128 respond_to do |format|
129 respond_to do |format|
129 format.html { redirect_to :controller => "account", :action => "login", :back_url => url }
130 format.html { redirect_to :controller => "account", :action => "login", :back_url => url }
130 format.atom { redirect_to :controller => "account", :action => "login", :back_url => url }
131 format.atom { redirect_to :controller => "account", :action => "login", :back_url => url }
131 format.xml { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
132 format.xml { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
132 format.json { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
133 format.json { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
133 end
134 end
134 return false
135 return false
135 end
136 end
136 true
137 true
137 end
138 end
138
139
139 def require_admin
140 def require_admin
140 return unless require_login
141 return unless require_login
141 if !User.current.admin?
142 if !User.current.admin?
142 render_403
143 render_403
143 return false
144 return false
144 end
145 end
145 true
146 true
146 end
147 end
147
148
148 def deny_access
149 def deny_access
149 User.current.logged? ? render_403 : require_login
150 User.current.logged? ? render_403 : require_login
150 end
151 end
151
152
152 # Authorize the user for the requested action
153 # Authorize the user for the requested action
153 def authorize(ctrl = params[:controller], action = params[:action], global = false)
154 def authorize(ctrl = params[:controller], action = params[:action], global = false)
154 allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project, :global => global)
155 allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project, :global => global)
155 allowed ? true : deny_access
156 allowed ? true : deny_access
156 end
157 end
157
158
158 # Authorize the user for the requested action outside a project
159 # Authorize the user for the requested action outside a project
159 def authorize_global(ctrl = params[:controller], action = params[:action], global = true)
160 def authorize_global(ctrl = params[:controller], action = params[:action], global = true)
160 authorize(ctrl, action, global)
161 authorize(ctrl, action, global)
161 end
162 end
162
163
163 # Find project of id params[:id]
164 # Find project of id params[:id]
164 def find_project
165 def find_project
165 @project = Project.find(params[:id])
166 @project = Project.find(params[:id])
166 rescue ActiveRecord::RecordNotFound
167 rescue ActiveRecord::RecordNotFound
167 render_404
168 render_404
168 end
169 end
169
170
170 # Finds and sets @project based on @object.project
171 # Finds and sets @project based on @object.project
171 def find_project_from_association
172 def find_project_from_association
172 render_404 unless @object.present?
173 render_404 unless @object.present?
173
174
174 @project = @object.project
175 @project = @object.project
175 rescue ActiveRecord::RecordNotFound
176 rescue ActiveRecord::RecordNotFound
176 render_404
177 render_404
177 end
178 end
178
179
179 def find_model_object
180 def find_model_object
180 model = self.class.read_inheritable_attribute('model_object')
181 model = self.class.read_inheritable_attribute('model_object')
181 if model
182 if model
182 @object = model.find(params[:id])
183 @object = model.find(params[:id])
183 self.instance_variable_set('@' + controller_name.singularize, @object) if @object
184 self.instance_variable_set('@' + controller_name.singularize, @object) if @object
184 end
185 end
185 rescue ActiveRecord::RecordNotFound
186 rescue ActiveRecord::RecordNotFound
186 render_404
187 render_404
187 end
188 end
188
189
189 def self.model_object(model)
190 def self.model_object(model)
190 write_inheritable_attribute('model_object', model)
191 write_inheritable_attribute('model_object', model)
191 end
192 end
192
193
193 # make sure that the user is a member of the project (or admin) if project is private
194 # make sure that the user is a member of the project (or admin) if project is private
194 # used as a before_filter for actions that do not require any particular permission on the project
195 # used as a before_filter for actions that do not require any particular permission on the project
195 def check_project_privacy
196 def check_project_privacy
196 if @project && @project.active?
197 if @project && @project.active?
197 if @project.is_public? || User.current.member_of?(@project) || User.current.admin?
198 if @project.is_public? || User.current.member_of?(@project) || User.current.admin?
198 true
199 true
199 else
200 else
200 User.current.logged? ? render_403 : require_login
201 User.current.logged? ? render_403 : require_login
201 end
202 end
202 else
203 else
203 @project = nil
204 @project = nil
204 render_404
205 render_404
205 false
206 false
206 end
207 end
207 end
208 end
208
209
209 def redirect_back_or_default(default)
210 def redirect_back_or_default(default)
210 back_url = CGI.unescape(params[:back_url].to_s)
211 back_url = CGI.unescape(params[:back_url].to_s)
211 if !back_url.blank?
212 if !back_url.blank?
212 begin
213 begin
213 uri = URI.parse(back_url)
214 uri = URI.parse(back_url)
214 # do not redirect user to another host or to the login or register page
215 # do not redirect user to another host or to the login or register page
215 if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
216 if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
216 redirect_to(back_url)
217 redirect_to(back_url)
217 return
218 return
218 end
219 end
219 rescue URI::InvalidURIError
220 rescue URI::InvalidURIError
220 # redirect to default
221 # redirect to default
221 end
222 end
222 end
223 end
223 redirect_to default
224 redirect_to default
224 end
225 end
225
226
226 def render_403
227 def render_403
227 @project = nil
228 @project = nil
228 respond_to do |format|
229 respond_to do |format|
229 format.html { render :template => "common/403", :layout => (request.xhr? ? false : 'base'), :status => 403 }
230 format.html { render :template => "common/403", :layout => (request.xhr? ? false : 'base'), :status => 403 }
230 format.atom { head 403 }
231 format.atom { head 403 }
231 format.xml { head 403 }
232 format.xml { head 403 }
232 format.json { head 403 }
233 format.json { head 403 }
233 end
234 end
234 return false
235 return false
235 end
236 end
236
237
237 def render_404
238 def render_404
238 respond_to do |format|
239 respond_to do |format|
239 format.html { render :template => "common/404", :layout => !request.xhr?, :status => 404 }
240 format.html { render :template => "common/404", :layout => !request.xhr?, :status => 404 }
240 format.atom { head 404 }
241 format.atom { head 404 }
241 format.xml { head 404 }
242 format.xml { head 404 }
242 format.json { head 404 }
243 format.json { head 404 }
243 end
244 end
244 return false
245 return false
245 end
246 end
246
247
247 def render_error(msg)
248 def render_error(msg)
248 respond_to do |format|
249 respond_to do |format|
249 format.html {
250 format.html {
250 flash.now[:error] = msg
251 flash.now[:error] = msg
251 render :text => '', :layout => !request.xhr?, :status => 500
252 render :text => '', :layout => !request.xhr?, :status => 500
252 }
253 }
253 format.atom { head 500 }
254 format.atom { head 500 }
254 format.xml { head 500 }
255 format.xml { head 500 }
255 format.json { head 500 }
256 format.json { head 500 }
256 end
257 end
257 end
258 end
258
259
259 def invalid_authenticity_token
260 def invalid_authenticity_token
260 if api_request?
261 if api_request?
261 logger.error "Form authenticity token is missing or is invalid. API calls must include a proper Content-type header (text/xml or text/json)."
262 logger.error "Form authenticity token is missing or is invalid. API calls must include a proper Content-type header (text/xml or text/json)."
262 end
263 end
263 render_error "Invalid form authenticity token."
264 render_error "Invalid form authenticity token."
264 end
265 end
265
266
266 def render_feed(items, options={})
267 def render_feed(items, options={})
267 @items = items || []
268 @items = items || []
268 @items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
269 @items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
269 @items = @items.slice(0, Setting.feeds_limit.to_i)
270 @items = @items.slice(0, Setting.feeds_limit.to_i)
270 @title = options[:title] || Setting.app_title
271 @title = options[:title] || Setting.app_title
271 render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml'
272 render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml'
272 end
273 end
273
274
274 def self.accept_key_auth(*actions)
275 def self.accept_key_auth(*actions)
275 actions = actions.flatten.map(&:to_s)
276 actions = actions.flatten.map(&:to_s)
276 write_inheritable_attribute('accept_key_auth_actions', actions)
277 write_inheritable_attribute('accept_key_auth_actions', actions)
277 end
278 end
278
279
279 def accept_key_auth_actions
280 def accept_key_auth_actions
280 self.class.read_inheritable_attribute('accept_key_auth_actions') || []
281 self.class.read_inheritable_attribute('accept_key_auth_actions') || []
281 end
282 end
282
283
283 # Returns the number of objects that should be displayed
284 # Returns the number of objects that should be displayed
284 # on the paginated list
285 # on the paginated list
285 def per_page_option
286 def per_page_option
286 per_page = nil
287 per_page = nil
287 if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
288 if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
288 per_page = params[:per_page].to_s.to_i
289 per_page = params[:per_page].to_s.to_i
289 session[:per_page] = per_page
290 session[:per_page] = per_page
290 elsif session[:per_page]
291 elsif session[:per_page]
291 per_page = session[:per_page]
292 per_page = session[:per_page]
292 else
293 else
293 per_page = Setting.per_page_options_array.first || 25
294 per_page = Setting.per_page_options_array.first || 25
294 end
295 end
295 per_page
296 per_page
296 end
297 end
297
298
298 # qvalues http header parser
299 # qvalues http header parser
299 # code taken from webrick
300 # code taken from webrick
300 def parse_qvalues(value)
301 def parse_qvalues(value)
301 tmp = []
302 tmp = []
302 if value
303 if value
303 parts = value.split(/,\s*/)
304 parts = value.split(/,\s*/)
304 parts.each {|part|
305 parts.each {|part|
305 if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
306 if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
306 val = m[1]
307 val = m[1]
307 q = (m[2] or 1).to_f
308 q = (m[2] or 1).to_f
308 tmp.push([val, q])
309 tmp.push([val, q])
309 end
310 end
310 }
311 }
311 tmp = tmp.sort_by{|val, q| -q}
312 tmp = tmp.sort_by{|val, q| -q}
312 tmp.collect!{|val, q| val}
313 tmp.collect!{|val, q| val}
313 end
314 end
314 return tmp
315 return tmp
315 rescue
316 rescue
316 nil
317 nil
317 end
318 end
318
319
319 # Returns a string that can be used as filename value in Content-Disposition header
320 # Returns a string that can be used as filename value in Content-Disposition header
320 def filename_for_content_disposition(name)
321 def filename_for_content_disposition(name)
321 request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
322 request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
322 end
323 end
323
324
324 def api_request?
325 def api_request?
325 %w(xml json).include? params[:format]
326 %w(xml json).include? params[:format]
326 end
327 end
327
328
328 # Renders a warning flash if obj has unsaved attachments
329 # Renders a warning flash if obj has unsaved attachments
329 def render_attachment_warning_if_needed(obj)
330 def render_attachment_warning_if_needed(obj)
330 flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present?
331 flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present?
331 end
332 end
332
333
333 # Rescues an invalid query statement. Just in case...
334 # Rescues an invalid query statement. Just in case...
334 def query_statement_invalid(exception)
335 def query_statement_invalid(exception)
335 logger.error "Query::StatementInvalid: #{exception.message}" if logger
336 logger.error "Query::StatementInvalid: #{exception.message}" if logger
336 session.delete(:query)
337 session.delete(:query)
337 sort_clear if respond_to?(:sort_clear)
338 sort_clear if respond_to?(:sort_clear)
338 render_error "An error occurred while executing the query and has been logged. Please report this error to your Redmine administrator."
339 render_error "An error occurred while executing the query and has been logged. Please report this error to your Redmine administrator."
339 end
340 end
340
341
341 end
342 end
General Comments 0
You need to be logged in to leave comments. Login now