Mercurial > hg > soundsoftware-site
comparison app/controllers/.svn/text-base/application_controller.rb.svn-base @ 441:cbce1fd3b1b7 redmine-1.2
Update to Redmine 1.2-stable branch (Redmine SVN rev 6000)
author | Chris Cannam |
---|---|
date | Mon, 06 Jun 2011 14:24:13 +0100 |
parents | 8661b858af72 |
children | 0c939c159af4 |
comparison
equal
deleted
inserted
replaced
245:051f544170fe | 441:cbce1fd3b1b7 |
---|---|
1 # redMine - project management software | 1 # Redmine - project management software |
2 # Copyright (C) 2006-2007 Jean-Philippe Lang | 2 # Copyright (C) 2006-2011 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' |
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', 'rsb' | 25 exempt_from_layout 'builder', 'rsb' |
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 |
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 |
115 end | 115 end |
116 end | 116 end |
117 lang ||= Setting.default_language | 117 lang ||= Setting.default_language |
118 set_language_if_valid(lang) | 118 set_language_if_valid(lang) |
119 end | 119 end |
120 | 120 |
121 def require_login | 121 def require_login |
122 if !User.current.logged? | 122 if !User.current.logged? |
123 # Extract only the basic url parameters on non-GET requests | 123 # Extract only the basic url parameters on non-GET requests |
124 if request.get? | 124 if request.get? |
125 url = url_for(params) | 125 url = url_for(params) |
144 render_403 | 144 render_403 |
145 return false | 145 return false |
146 end | 146 end |
147 true | 147 true |
148 end | 148 end |
149 | 149 |
150 def deny_access | 150 def deny_access |
151 User.current.logged? ? render_403 : require_login | 151 User.current.logged? ? render_403 : require_login |
152 end | 152 end |
153 | 153 |
154 # Authorize the user for the requested action | 154 # Authorize the user for the requested action |
195 end | 195 end |
196 | 196 |
197 # Finds and sets @project based on @object.project | 197 # Finds and sets @project based on @object.project |
198 def find_project_from_association | 198 def find_project_from_association |
199 render_404 unless @object.present? | 199 render_404 unless @object.present? |
200 | 200 |
201 @project = @object.project | 201 @project = @object.project |
202 rescue ActiveRecord::RecordNotFound | 202 rescue ActiveRecord::RecordNotFound |
203 render_404 | 203 render_404 |
204 end | 204 end |
205 | 205 |
219 | 219 |
220 # Filter for bulk issue operations | 220 # Filter for bulk issue operations |
221 def find_issues | 221 def find_issues |
222 @issues = Issue.find_all_by_id(params[:id] || params[:ids]) | 222 @issues = Issue.find_all_by_id(params[:id] || params[:ids]) |
223 raise ActiveRecord::RecordNotFound if @issues.empty? | 223 raise ActiveRecord::RecordNotFound if @issues.empty? |
224 if @issues.detect {|issue| !issue.visible?} | |
225 deny_access | |
226 return | |
227 end | |
224 @projects = @issues.collect(&:project).compact.uniq | 228 @projects = @issues.collect(&:project).compact.uniq |
225 @project = @projects.first if @projects.size == 1 | 229 @project = @projects.first if @projects.size == 1 |
226 rescue ActiveRecord::RecordNotFound | 230 rescue ActiveRecord::RecordNotFound |
227 render_404 | 231 render_404 |
228 end | 232 end |
229 | 233 |
230 # Check if project is unique before bulk operations | 234 # Check if project is unique before bulk operations |
231 def check_project_uniqueness | 235 def check_project_uniqueness |
232 unless @project | 236 unless @project |
233 # TODO: let users bulk edit/move/destroy issues from different projects | 237 # TODO: let users bulk edit/move/destroy issues from different projects |
234 render_error 'Can not bulk edit/move/destroy issues from different projects' | 238 render_error 'Can not bulk edit/move/destroy issues from different projects' |
235 return false | 239 return false |
236 end | 240 end |
237 end | 241 end |
238 | 242 |
239 # make sure that the user is a member of the project (or admin) if project is private | 243 # make sure that the user is a member of the project (or admin) if project is private |
240 # used as a before_filter for actions that do not require any particular permission on the project | 244 # used as a before_filter for actions that do not require any particular permission on the project |
241 def check_project_privacy | 245 def check_project_privacy |
242 if @project && @project.active? | 246 if @project && @project.active? |
243 if @project.is_public? || User.current.member_of?(@project) || User.current.admin? | 247 if @project.is_public? || User.current.member_of?(@project) || User.current.admin? |
269 rescue URI::InvalidURIError | 273 rescue URI::InvalidURIError |
270 # redirect to default | 274 # redirect to default |
271 end | 275 end |
272 end | 276 end |
273 redirect_to default | 277 redirect_to default |
274 end | 278 false |
275 | 279 end |
280 | |
276 def render_403(options={}) | 281 def render_403(options={}) |
277 @project = nil | 282 @project = nil |
278 render_error({:message => :notice_not_authorized, :status => 403}.merge(options)) | 283 render_error({:message => :notice_not_authorized, :status => 403}.merge(options)) |
279 return false | 284 return false |
280 end | 285 end |
281 | 286 |
282 def render_404(options={}) | 287 def render_404(options={}) |
283 render_error({:message => :notice_file_not_found, :status => 404}.merge(options)) | 288 render_error({:message => :notice_file_not_found, :status => 404}.merge(options)) |
284 return false | 289 return false |
285 end | 290 end |
286 | 291 |
287 # Renders an error response | 292 # Renders an error response |
288 def render_error(arg) | 293 def render_error(arg) |
289 arg = {:message => arg} unless arg.is_a?(Hash) | 294 arg = {:message => arg} unless arg.is_a?(Hash) |
290 | 295 |
291 @message = arg[:message] | 296 @message = arg[:message] |
292 @message = l(@message) if @message.is_a?(Symbol) | 297 @message = l(@message) if @message.is_a?(Symbol) |
293 @status = arg[:status] || 500 | 298 @status = arg[:status] || 500 |
294 | 299 |
295 respond_to do |format| | 300 respond_to do |format| |
296 format.html { | 301 format.html { |
297 render :template => 'common/error', :layout => use_layout, :status => @status | 302 render :template => 'common/error', :layout => use_layout, :status => @status |
298 } | 303 } |
299 format.atom { head @status } | 304 format.atom { head @status } |
307 # | 312 # |
308 # @return [boolean, string] name of the layout to use or false for no layout | 313 # @return [boolean, string] name of the layout to use or false for no layout |
309 def use_layout | 314 def use_layout |
310 request.xhr? ? false : 'base' | 315 request.xhr? ? false : 'base' |
311 end | 316 end |
312 | 317 |
313 def invalid_authenticity_token | 318 def invalid_authenticity_token |
314 if api_request? | 319 if api_request? |
315 logger.error "Form authenticity token is missing or is invalid. API calls must include a proper Content-type header (text/xml or text/json)." | 320 logger.error "Form authenticity token is missing or is invalid. API calls must include a proper Content-type header (text/xml or text/json)." |
316 end | 321 end |
317 render_error "Invalid form authenticity token." | 322 render_error "Invalid form authenticity token." |
318 end | 323 end |
319 | 324 |
320 def render_feed(items, options={}) | 325 def render_feed(items, options={}) |
321 @items = items || [] | 326 @items = items || [] |
322 @items.sort! {|x,y| y.event_datetime <=> x.event_datetime } | 327 @items.sort! {|x,y| y.event_datetime <=> x.event_datetime } |
323 @items = @items.slice(0, Setting.feeds_limit.to_i) | 328 @items = @items.slice(0, Setting.feeds_limit.to_i) |
324 @title = options[:title] || Setting.app_title | 329 @title = options[:title] || Setting.app_title |
325 render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml' | 330 render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml' |
326 end | 331 end |
327 | 332 |
328 def self.accept_key_auth(*actions) | 333 def self.accept_key_auth(*actions) |
329 actions = actions.flatten.map(&:to_s) | 334 actions = actions.flatten.map(&:to_s) |
330 write_inheritable_attribute('accept_key_auth_actions', actions) | 335 write_inheritable_attribute('accept_key_auth_actions', actions) |
331 end | 336 end |
332 | 337 |
333 def accept_key_auth_actions | 338 def accept_key_auth_actions |
334 self.class.read_inheritable_attribute('accept_key_auth_actions') || [] | 339 self.class.read_inheritable_attribute('accept_key_auth_actions') || [] |
335 end | 340 end |
336 | 341 |
337 # Returns the number of objects that should be displayed | 342 # Returns the number of objects that should be displayed |
338 # on the paginated list | 343 # on the paginated list |
339 def per_page_option | 344 def per_page_option |
340 per_page = nil | 345 per_page = nil |
341 if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i) | 346 if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i) |
367 if offset.nil? && options[:page].present? | 372 if offset.nil? && options[:page].present? |
368 offset = (options[:page].to_i - 1) * limit | 373 offset = (options[:page].to_i - 1) * limit |
369 offset = 0 if offset < 0 | 374 offset = 0 if offset < 0 |
370 end | 375 end |
371 offset ||= 0 | 376 offset ||= 0 |
372 | 377 |
373 [offset, limit] | 378 [offset, limit] |
374 end | 379 end |
375 | 380 |
376 # qvalues http header parser | 381 # qvalues http header parser |
377 # code taken from webrick | 382 # code taken from webrick |
378 def parse_qvalues(value) | 383 def parse_qvalues(value) |
379 tmp = [] | 384 tmp = [] |
380 if value | 385 if value |
391 end | 396 end |
392 return tmp | 397 return tmp |
393 rescue | 398 rescue |
394 nil | 399 nil |
395 end | 400 end |
396 | 401 |
397 # Returns a string that can be used as filename value in Content-Disposition header | 402 # Returns a string that can be used as filename value in Content-Disposition header |
398 def filename_for_content_disposition(name) | 403 def filename_for_content_disposition(name) |
399 request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name | 404 request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name |
400 end | 405 end |
401 | 406 |
402 def api_request? | 407 def api_request? |
403 %w(xml json).include? params[:format] | 408 %w(xml json).include? params[:format] |
404 end | 409 end |
405 | 410 |
406 # Returns the API key present in the request | 411 # Returns the API key present in the request |
407 def api_key_from_request | 412 def api_key_from_request |
408 if params[:key].present? | 413 if params[:key].present? |
409 params[:key] | 414 params[:key] |
410 elsif request.headers["X-Redmine-API-Key"].present? | 415 elsif request.headers["X-Redmine-API-Key"].present? |
457 raise "Unknown format #{params[:format]} in #render_validation_errors" | 462 raise "Unknown format #{params[:format]} in #render_validation_errors" |
458 end | 463 end |
459 ) | 464 ) |
460 render options | 465 render options |
461 end | 466 end |
462 | 467 |
463 # Overrides #default_template so that the api template | 468 # Overrides #default_template so that the api template |
464 # is used automatically if it exists | 469 # is used automatically if it exists |
465 def default_template(action_name = self.action_name) | 470 def default_template(action_name = self.action_name) |
466 if api_request? | 471 if api_request? |
467 begin | 472 begin |
471 # fallback to the default behaviour | 476 # fallback to the default behaviour |
472 end | 477 end |
473 end | 478 end |
474 super | 479 super |
475 end | 480 end |
476 | 481 |
477 # Overrides #pick_layout so that #render with no arguments | 482 # Overrides #pick_layout so that #render with no arguments |
478 # doesn't use the layout for api requests | 483 # doesn't use the layout for api requests |
479 def pick_layout(*args) | 484 def pick_layout(*args) |
480 api_request? ? nil : super | 485 api_request? ? nil : super |
481 end | 486 end |