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