##// END OF EJS Templates
Fixed: login filter providing incorrect back_url for Redmine installed in sub-directory (#1900)....
Jean-Philippe Lang -
r1888:7afdb01f0065
parent child
Show More
@@ -1,225 +1,225
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
19
20 class ApplicationController < ActionController::Base
20 class ApplicationController < ActionController::Base
21 layout 'base'
21 layout 'base'
22
22
23 before_filter :user_setup, :check_if_login_required, :set_localization
23 before_filter :user_setup, :check_if_login_required, :set_localization
24 filter_parameter_logging :password
24 filter_parameter_logging :password
25
25
26 include Redmine::MenuManager::MenuController
26 include Redmine::MenuManager::MenuController
27 helper Redmine::MenuManager::MenuHelper
27 helper Redmine::MenuManager::MenuHelper
28
28
29 REDMINE_SUPPORTED_SCM.each do |scm|
29 REDMINE_SUPPORTED_SCM.each do |scm|
30 require_dependency "repository/#{scm.underscore}"
30 require_dependency "repository/#{scm.underscore}"
31 end
31 end
32
32
33 def current_role
33 def current_role
34 @current_role ||= User.current.role_for_project(@project)
34 @current_role ||= User.current.role_for_project(@project)
35 end
35 end
36
36
37 def user_setup
37 def user_setup
38 # Check the settings cache for each request
38 # Check the settings cache for each request
39 Setting.check_cache
39 Setting.check_cache
40 # Find the current user
40 # Find the current user
41 User.current = find_current_user
41 User.current = find_current_user
42 end
42 end
43
43
44 # Returns the current user or nil if no user is logged in
44 # Returns the current user or nil if no user is logged in
45 def find_current_user
45 def find_current_user
46 if session[:user_id]
46 if session[:user_id]
47 # existing session
47 # existing session
48 (User.find_active(session[:user_id]) rescue nil)
48 (User.find_active(session[:user_id]) rescue nil)
49 elsif cookies[:autologin] && Setting.autologin?
49 elsif cookies[:autologin] && Setting.autologin?
50 # auto-login feature
50 # auto-login feature
51 User.find_by_autologin_key(cookies[:autologin])
51 User.find_by_autologin_key(cookies[:autologin])
52 elsif params[:key] && accept_key_auth_actions.include?(params[:action])
52 elsif params[:key] && accept_key_auth_actions.include?(params[:action])
53 # RSS key authentication
53 # RSS key authentication
54 User.find_by_rss_key(params[:key])
54 User.find_by_rss_key(params[:key])
55 end
55 end
56 end
56 end
57
57
58 # check if login is globally required to access the application
58 # check if login is globally required to access the application
59 def check_if_login_required
59 def check_if_login_required
60 # no check needed if user is already logged in
60 # no check needed if user is already logged in
61 return true if User.current.logged?
61 return true if User.current.logged?
62 require_login if Setting.login_required?
62 require_login if Setting.login_required?
63 end
63 end
64
64
65 def set_localization
65 def set_localization
66 User.current.language = nil unless User.current.logged?
66 User.current.language = nil unless User.current.logged?
67 lang = begin
67 lang = begin
68 if !User.current.language.blank? && GLoc.valid_language?(User.current.language)
68 if !User.current.language.blank? && GLoc.valid_language?(User.current.language)
69 User.current.language
69 User.current.language
70 elsif request.env['HTTP_ACCEPT_LANGUAGE']
70 elsif request.env['HTTP_ACCEPT_LANGUAGE']
71 accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.downcase
71 accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.downcase
72 if !accept_lang.blank? && (GLoc.valid_language?(accept_lang) || GLoc.valid_language?(accept_lang = accept_lang.split('-').first))
72 if !accept_lang.blank? && (GLoc.valid_language?(accept_lang) || GLoc.valid_language?(accept_lang = accept_lang.split('-').first))
73 User.current.language = accept_lang
73 User.current.language = accept_lang
74 end
74 end
75 end
75 end
76 rescue
76 rescue
77 nil
77 nil
78 end || Setting.default_language
78 end || Setting.default_language
79 set_language_if_valid(lang)
79 set_language_if_valid(lang)
80 end
80 end
81
81
82 def require_login
82 def require_login
83 if !User.current.logged?
83 if !User.current.logged?
84 redirect_to :controller => "account", :action => "login", :back_url => request.request_uri
84 redirect_to :controller => "account", :action => "login", :back_url => (request.relative_url_root + request.request_uri)
85 return false
85 return false
86 end
86 end
87 true
87 true
88 end
88 end
89
89
90 def require_admin
90 def require_admin
91 return unless require_login
91 return unless require_login
92 if !User.current.admin?
92 if !User.current.admin?
93 render_403
93 render_403
94 return false
94 return false
95 end
95 end
96 true
96 true
97 end
97 end
98
98
99 def deny_access
99 def deny_access
100 User.current.logged? ? render_403 : require_login
100 User.current.logged? ? render_403 : require_login
101 end
101 end
102
102
103 # Authorize the user for the requested action
103 # Authorize the user for the requested action
104 def authorize(ctrl = params[:controller], action = params[:action])
104 def authorize(ctrl = params[:controller], action = params[:action])
105 allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project)
105 allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project)
106 allowed ? true : deny_access
106 allowed ? true : deny_access
107 end
107 end
108
108
109 # make sure that the user is a member of the project (or admin) if project is private
109 # make sure that the user is a member of the project (or admin) if project is private
110 # used as a before_filter for actions that do not require any particular permission on the project
110 # used as a before_filter for actions that do not require any particular permission on the project
111 def check_project_privacy
111 def check_project_privacy
112 if @project && @project.active?
112 if @project && @project.active?
113 if @project.is_public? || User.current.member_of?(@project) || User.current.admin?
113 if @project.is_public? || User.current.member_of?(@project) || User.current.admin?
114 true
114 true
115 else
115 else
116 User.current.logged? ? render_403 : require_login
116 User.current.logged? ? render_403 : require_login
117 end
117 end
118 else
118 else
119 @project = nil
119 @project = nil
120 render_404
120 render_404
121 false
121 false
122 end
122 end
123 end
123 end
124
124
125 def redirect_back_or_default(default)
125 def redirect_back_or_default(default)
126 back_url = params[:back_url]
126 back_url = params[:back_url]
127 if !back_url.blank?
127 if !back_url.blank?
128 uri = URI.parse(back_url)
128 uri = URI.parse(back_url)
129 # do not redirect user to another host
129 # do not redirect user to another host
130 if uri.relative? || (uri.host == request.host)
130 if uri.relative? || (uri.host == request.host)
131 redirect_to(back_url) and return
131 redirect_to(back_url) and return
132 end
132 end
133 end
133 end
134 redirect_to default
134 redirect_to default
135 end
135 end
136
136
137 def render_403
137 def render_403
138 @project = nil
138 @project = nil
139 render :template => "common/403", :layout => !request.xhr?, :status => 403
139 render :template => "common/403", :layout => !request.xhr?, :status => 403
140 return false
140 return false
141 end
141 end
142
142
143 def render_404
143 def render_404
144 render :template => "common/404", :layout => !request.xhr?, :status => 404
144 render :template => "common/404", :layout => !request.xhr?, :status => 404
145 return false
145 return false
146 end
146 end
147
147
148 def render_error(msg)
148 def render_error(msg)
149 flash.now[:error] = msg
149 flash.now[:error] = msg
150 render :nothing => true, :layout => !request.xhr?, :status => 500
150 render :nothing => true, :layout => !request.xhr?, :status => 500
151 end
151 end
152
152
153 def render_feed(items, options={})
153 def render_feed(items, options={})
154 @items = items || []
154 @items = items || []
155 @items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
155 @items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
156 @items = @items.slice(0, Setting.feeds_limit.to_i)
156 @items = @items.slice(0, Setting.feeds_limit.to_i)
157 @title = options[:title] || Setting.app_title
157 @title = options[:title] || Setting.app_title
158 render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml'
158 render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml'
159 end
159 end
160
160
161 def self.accept_key_auth(*actions)
161 def self.accept_key_auth(*actions)
162 actions = actions.flatten.map(&:to_s)
162 actions = actions.flatten.map(&:to_s)
163 write_inheritable_attribute('accept_key_auth_actions', actions)
163 write_inheritable_attribute('accept_key_auth_actions', actions)
164 end
164 end
165
165
166 def accept_key_auth_actions
166 def accept_key_auth_actions
167 self.class.read_inheritable_attribute('accept_key_auth_actions') || []
167 self.class.read_inheritable_attribute('accept_key_auth_actions') || []
168 end
168 end
169
169
170 # TODO: move to model
170 # TODO: move to model
171 def attach_files(obj, attachments)
171 def attach_files(obj, attachments)
172 attached = []
172 attached = []
173 if attachments && attachments.is_a?(Hash)
173 if attachments && attachments.is_a?(Hash)
174 attachments.each_value do |attachment|
174 attachments.each_value do |attachment|
175 file = attachment['file']
175 file = attachment['file']
176 next unless file && file.size > 0
176 next unless file && file.size > 0
177 a = Attachment.create(:container => obj,
177 a = Attachment.create(:container => obj,
178 :file => file,
178 :file => file,
179 :description => attachment['description'].to_s.strip,
179 :description => attachment['description'].to_s.strip,
180 :author => User.current)
180 :author => User.current)
181 attached << a unless a.new_record?
181 attached << a unless a.new_record?
182 end
182 end
183 end
183 end
184 attached
184 attached
185 end
185 end
186
186
187 # Returns the number of objects that should be displayed
187 # Returns the number of objects that should be displayed
188 # on the paginated list
188 # on the paginated list
189 def per_page_option
189 def per_page_option
190 per_page = nil
190 per_page = nil
191 if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
191 if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
192 per_page = params[:per_page].to_s.to_i
192 per_page = params[:per_page].to_s.to_i
193 session[:per_page] = per_page
193 session[:per_page] = per_page
194 elsif session[:per_page]
194 elsif session[:per_page]
195 per_page = session[:per_page]
195 per_page = session[:per_page]
196 else
196 else
197 per_page = Setting.per_page_options_array.first || 25
197 per_page = Setting.per_page_options_array.first || 25
198 end
198 end
199 per_page
199 per_page
200 end
200 end
201
201
202 # qvalues http header parser
202 # qvalues http header parser
203 # code taken from webrick
203 # code taken from webrick
204 def parse_qvalues(value)
204 def parse_qvalues(value)
205 tmp = []
205 tmp = []
206 if value
206 if value
207 parts = value.split(/,\s*/)
207 parts = value.split(/,\s*/)
208 parts.each {|part|
208 parts.each {|part|
209 if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
209 if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
210 val = m[1]
210 val = m[1]
211 q = (m[2] or 1).to_f
211 q = (m[2] or 1).to_f
212 tmp.push([val, q])
212 tmp.push([val, q])
213 end
213 end
214 }
214 }
215 tmp = tmp.sort_by{|val, q| -q}
215 tmp = tmp.sort_by{|val, q| -q}
216 tmp.collect!{|val, q| val}
216 tmp.collect!{|val, q| val}
217 end
217 end
218 return tmp
218 return tmp
219 end
219 end
220
220
221 # Returns a string that can be used as filename value in Content-Disposition header
221 # Returns a string that can be used as filename value in Content-Disposition header
222 def filename_for_content_disposition(name)
222 def filename_for_content_disposition(name)
223 request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
223 request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
224 end
224 end
225 end
225 end
General Comments 0
You need to be logged in to leave comments. Login now