##// END OF EJS Templates
Send password reset email to the email used in lost password form (#4244)....
Jean-Philippe Lang -
r13506:a3a8fee8adf8
parent child
Show More
@@ -1,351 +1,354
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 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 class AccountController < ApplicationController
19 19 helper :custom_fields
20 20 include CustomFieldsHelper
21 21
22 22 # prevents login action to be filtered by check_if_login_required application scope filter
23 23 skip_before_filter :check_if_login_required, :check_password_change
24 24
25 25 # Overrides ApplicationController#verify_authenticity_token to disable
26 26 # token verification on openid callbacks
27 27 def verify_authenticity_token
28 28 unless using_open_id?
29 29 super
30 30 end
31 31 end
32 32
33 33 # Login request and validation
34 34 def login
35 35 if request.get?
36 36 if User.current.logged?
37 37 redirect_back_or_default home_url, :referer => true
38 38 end
39 39 else
40 40 authenticate_user
41 41 end
42 42 rescue AuthSourceException => e
43 43 logger.error "An error occured when authenticating #{params[:username]}: #{e.message}"
44 44 render_error :message => e.message
45 45 end
46 46
47 47 # Log out current user and redirect to welcome page
48 48 def logout
49 49 if User.current.anonymous?
50 50 redirect_to home_url
51 51 elsif request.post?
52 52 logout_user
53 53 redirect_to home_url
54 54 end
55 55 # display the logout form
56 56 end
57 57
58 58 # Lets user choose a new password
59 59 def lost_password
60 60 (redirect_to(home_url); return) unless Setting.lost_password?
61 61 if params[:token]
62 62 @token = Token.find_token("recovery", params[:token].to_s)
63 63 if @token.nil? || @token.expired?
64 64 redirect_to home_url
65 65 return
66 66 end
67 67 @user = @token.user
68 68 unless @user && @user.active?
69 69 redirect_to home_url
70 70 return
71 71 end
72 72 if request.post?
73 73 @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
74 74 if @user.save
75 75 @token.destroy
76 76 flash[:notice] = l(:notice_account_password_updated)
77 77 redirect_to signin_path
78 78 return
79 79 end
80 80 end
81 81 render :template => "account/password_recovery"
82 82 return
83 83 else
84 84 if request.post?
85 user = User.find_by_mail(params[:mail].to_s)
85 email = params[:mail].to_s
86 user = User.find_by_mail(email)
86 87 # user not found
87 88 unless user
88 89 flash.now[:error] = l(:notice_account_unknown_email)
89 90 return
90 91 end
91 92 unless user.active?
92 93 handle_inactive_user(user, lost_password_path)
93 94 return
94 95 end
95 96 # user cannot change its password
96 97 unless user.change_password_allowed?
97 98 flash.now[:error] = l(:notice_can_t_change_password)
98 99 return
99 100 end
100 101 # create a new token for password recovery
101 102 token = Token.new(:user => user, :action => "recovery")
102 103 if token.save
103 Mailer.lost_password(token).deliver
104 # Don't use the param to send the email
105 recipent = user.mails.detect {|e| e.downcase == email.downcase} || user.mail
106 Mailer.lost_password(token, recipent).deliver
104 107 flash[:notice] = l(:notice_account_lost_email_sent)
105 108 redirect_to signin_path
106 109 return
107 110 end
108 111 end
109 112 end
110 113 end
111 114
112 115 # User self-registration
113 116 def register
114 117 (redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration]
115 118 if request.get?
116 119 session[:auth_source_registration] = nil
117 120 @user = User.new(:language => current_language.to_s)
118 121 else
119 122 user_params = params[:user] || {}
120 123 @user = User.new
121 124 @user.safe_attributes = user_params
122 125 @user.admin = false
123 126 @user.register
124 127 if session[:auth_source_registration]
125 128 @user.activate
126 129 @user.login = session[:auth_source_registration][:login]
127 130 @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
128 131 if @user.save
129 132 session[:auth_source_registration] = nil
130 133 self.logged_user = @user
131 134 flash[:notice] = l(:notice_account_activated)
132 135 redirect_to my_account_path
133 136 end
134 137 else
135 138 @user.login = params[:user][:login]
136 139 unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank?
137 140 @user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation]
138 141 end
139 142
140 143 case Setting.self_registration
141 144 when '1'
142 145 register_by_email_activation(@user)
143 146 when '3'
144 147 register_automatically(@user)
145 148 else
146 149 register_manually_by_administrator(@user)
147 150 end
148 151 end
149 152 end
150 153 end
151 154
152 155 # Token based account activation
153 156 def activate
154 157 (redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present?
155 158 token = Token.find_token('register', params[:token].to_s)
156 159 (redirect_to(home_url); return) unless token and !token.expired?
157 160 user = token.user
158 161 (redirect_to(home_url); return) unless user.registered?
159 162 user.activate
160 163 if user.save
161 164 token.destroy
162 165 flash[:notice] = l(:notice_account_activated)
163 166 end
164 167 redirect_to signin_path
165 168 end
166 169
167 170 # Sends a new account activation email
168 171 def activation_email
169 172 if session[:registered_user_id] && Setting.self_registration == '1'
170 173 user_id = session.delete(:registered_user_id).to_i
171 174 user = User.find_by_id(user_id)
172 175 if user && user.registered?
173 176 register_by_email_activation(user)
174 177 return
175 178 end
176 179 end
177 180 redirect_to(home_url)
178 181 end
179 182
180 183 private
181 184
182 185 def authenticate_user
183 186 if Setting.openid? && using_open_id?
184 187 open_id_authenticate(params[:openid_url])
185 188 else
186 189 password_authentication
187 190 end
188 191 end
189 192
190 193 def password_authentication
191 194 user = User.try_to_login(params[:username], params[:password], false)
192 195
193 196 if user.nil?
194 197 invalid_credentials
195 198 elsif user.new_record?
196 199 onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
197 200 else
198 201 # Valid user
199 202 if user.active?
200 203 successful_authentication(user)
201 204 else
202 205 handle_inactive_user(user)
203 206 end
204 207 end
205 208 end
206 209
207 210 def open_id_authenticate(openid_url)
208 211 back_url = signin_url(:autologin => params[:autologin])
209 212 authenticate_with_open_id(
210 213 openid_url, :required => [:nickname, :fullname, :email],
211 214 :return_to => back_url, :method => :post
212 215 ) do |result, identity_url, registration|
213 216 if result.successful?
214 217 user = User.find_or_initialize_by_identity_url(identity_url)
215 218 if user.new_record?
216 219 # Self-registration off
217 220 (redirect_to(home_url); return) unless Setting.self_registration?
218 221 # Create on the fly
219 222 user.login = registration['nickname'] unless registration['nickname'].nil?
220 223 user.mail = registration['email'] unless registration['email'].nil?
221 224 user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
222 225 user.random_password
223 226 user.register
224 227 case Setting.self_registration
225 228 when '1'
226 229 register_by_email_activation(user) do
227 230 onthefly_creation_failed(user)
228 231 end
229 232 when '3'
230 233 register_automatically(user) do
231 234 onthefly_creation_failed(user)
232 235 end
233 236 else
234 237 register_manually_by_administrator(user) do
235 238 onthefly_creation_failed(user)
236 239 end
237 240 end
238 241 else
239 242 # Existing record
240 243 if user.active?
241 244 successful_authentication(user)
242 245 else
243 246 handle_inactive_user(user)
244 247 end
245 248 end
246 249 end
247 250 end
248 251 end
249 252
250 253 def successful_authentication(user)
251 254 logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
252 255 # Valid user
253 256 self.logged_user = user
254 257 # generate a key and set cookie if autologin
255 258 if params[:autologin] && Setting.autologin?
256 259 set_autologin_cookie(user)
257 260 end
258 261 call_hook(:controller_account_success_authentication_after, {:user => user })
259 262 redirect_back_or_default my_page_path
260 263 end
261 264
262 265 def set_autologin_cookie(user)
263 266 token = Token.create(:user => user, :action => 'autologin')
264 267 cookie_options = {
265 268 :value => token.value,
266 269 :expires => 1.year.from_now,
267 270 :path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
268 271 :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
269 272 :httponly => true
270 273 }
271 274 cookies[autologin_cookie_name] = cookie_options
272 275 end
273 276
274 277 # Onthefly creation failed, display the registration form to fill/fix attributes
275 278 def onthefly_creation_failed(user, auth_source_options = { })
276 279 @user = user
277 280 session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
278 281 render :action => 'register'
279 282 end
280 283
281 284 def invalid_credentials
282 285 logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
283 286 flash.now[:error] = l(:notice_account_invalid_creditentials)
284 287 end
285 288
286 289 # Register a user for email activation.
287 290 #
288 291 # Pass a block for behavior when a user fails to save
289 292 def register_by_email_activation(user, &block)
290 293 token = Token.new(:user => user, :action => "register")
291 294 if user.save and token.save
292 295 Mailer.register(token).deliver
293 296 flash[:notice] = l(:notice_account_register_done, :email => user.mail)
294 297 redirect_to signin_path
295 298 else
296 299 yield if block_given?
297 300 end
298 301 end
299 302
300 303 # Automatically register a user
301 304 #
302 305 # Pass a block for behavior when a user fails to save
303 306 def register_automatically(user, &block)
304 307 # Automatic activation
305 308 user.activate
306 309 user.last_login_on = Time.now
307 310 if user.save
308 311 self.logged_user = user
309 312 flash[:notice] = l(:notice_account_activated)
310 313 redirect_to my_account_path
311 314 else
312 315 yield if block_given?
313 316 end
314 317 end
315 318
316 319 # Manual activation by the administrator
317 320 #
318 321 # Pass a block for behavior when a user fails to save
319 322 def register_manually_by_administrator(user, &block)
320 323 if user.save
321 324 # Sends an email to the administrators
322 325 Mailer.account_activation_request(user).deliver
323 326 account_pending(user)
324 327 else
325 328 yield if block_given?
326 329 end
327 330 end
328 331
329 332 def handle_inactive_user(user, redirect_path=signin_path)
330 333 if user.registered?
331 334 account_pending(user, redirect_path)
332 335 else
333 336 account_locked(user, redirect_path)
334 337 end
335 338 end
336 339
337 340 def account_pending(user, redirect_path=signin_path)
338 341 if Setting.self_registration == '1'
339 342 flash[:error] = l(:notice_account_not_activated_yet, :url => activation_email_path)
340 343 session[:registered_user_id] = user.id
341 344 else
342 345 flash[:error] = l(:notice_account_pending)
343 346 end
344 347 redirect_to redirect_path
345 348 end
346 349
347 350 def account_locked(user, redirect_path=signin_path)
348 351 flash[:error] = l(:notice_account_locked)
349 352 redirect_to redirect_path
350 353 end
351 354 end
@@ -1,522 +1,523
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 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 class Mailer < ActionMailer::Base
19 19 layout 'mailer'
20 20 helper :application
21 21 helper :issues
22 22 helper :custom_fields
23 23
24 24 include Redmine::I18n
25 25
26 26 def self.default_url_options
27 27 { :host => Setting.host_name, :protocol => Setting.protocol }
28 28 end
29 29
30 30 # Builds a mail for notifying to_users and cc_users about a new issue
31 31 def issue_add(issue, to_users, cc_users)
32 32 redmine_headers 'Project' => issue.project.identifier,
33 33 'Issue-Id' => issue.id,
34 34 'Issue-Author' => issue.author.login
35 35 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
36 36 message_id issue
37 37 references issue
38 38 @author = issue.author
39 39 @issue = issue
40 40 @users = to_users + cc_users
41 41 @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue)
42 42 mail :to => to_users,
43 43 :cc => cc_users,
44 44 :subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
45 45 end
46 46
47 47 # Notifies users about a new issue
48 48 def self.deliver_issue_add(issue)
49 49 to = issue.notified_users
50 50 cc = issue.notified_watchers - to
51 51 issue.each_notification(to + cc) do |users|
52 52 Mailer.issue_add(issue, to & users, cc & users).deliver
53 53 end
54 54 end
55 55
56 56 # Builds a mail for notifying to_users and cc_users about an issue update
57 57 def issue_edit(journal, to_users, cc_users)
58 58 issue = journal.journalized
59 59 redmine_headers 'Project' => issue.project.identifier,
60 60 'Issue-Id' => issue.id,
61 61 'Issue-Author' => issue.author.login
62 62 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
63 63 message_id journal
64 64 references issue
65 65 @author = journal.user
66 66 s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
67 67 s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
68 68 s << issue.subject
69 69 @issue = issue
70 70 @users = to_users + cc_users
71 71 @journal = journal
72 72 @journal_details = journal.visible_details(@users.first)
73 73 @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
74 74 mail :to => to_users,
75 75 :cc => cc_users,
76 76 :subject => s
77 77 end
78 78
79 79 # Notifies users about an issue update
80 80 def self.deliver_issue_edit(journal)
81 81 issue = journal.journalized.reload
82 82 to = journal.notified_users
83 83 cc = journal.notified_watchers - to
84 84 journal.each_notification(to + cc) do |users|
85 85 issue.each_notification(users) do |users2|
86 86 Mailer.issue_edit(journal, to & users2, cc & users2).deliver
87 87 end
88 88 end
89 89 end
90 90
91 91 def reminder(user, issues, days)
92 92 set_language_if_valid user.language
93 93 @issues = issues
94 94 @days = days
95 95 @issues_url = url_for(:controller => 'issues', :action => 'index',
96 96 :set_filter => 1, :assigned_to_id => user.id,
97 97 :sort => 'due_date:asc')
98 98 mail :to => user,
99 99 :subject => l(:mail_subject_reminder, :count => issues.size, :days => days)
100 100 end
101 101
102 102 # Builds a Mail::Message object used to email users belonging to the added document's project.
103 103 #
104 104 # Example:
105 105 # document_added(document) => Mail::Message object
106 106 # Mailer.document_added(document).deliver => sends an email to the document's project recipients
107 107 def document_added(document)
108 108 redmine_headers 'Project' => document.project.identifier
109 109 @author = User.current
110 110 @document = document
111 111 @document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
112 112 mail :to => document.notified_users,
113 113 :subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
114 114 end
115 115
116 116 # Builds a Mail::Message object used to email recipients of a project when an attachements are added.
117 117 #
118 118 # Example:
119 119 # attachments_added(attachments) => Mail::Message object
120 120 # Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients
121 121 def attachments_added(attachments)
122 122 container = attachments.first.container
123 123 added_to = ''
124 124 added_to_url = ''
125 125 @author = attachments.first.author
126 126 case container.class.name
127 127 when 'Project'
128 128 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
129 129 added_to = "#{l(:label_project)}: #{container}"
130 130 recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
131 131 when 'Version'
132 132 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
133 133 added_to = "#{l(:label_version)}: #{container.name}"
134 134 recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
135 135 when 'Document'
136 136 added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
137 137 added_to = "#{l(:label_document)}: #{container.title}"
138 138 recipients = container.notified_users
139 139 end
140 140 redmine_headers 'Project' => container.project.identifier
141 141 @attachments = attachments
142 142 @added_to = added_to
143 143 @added_to_url = added_to_url
144 144 mail :to => recipients,
145 145 :subject => "[#{container.project.name}] #{l(:label_attachment_new)}"
146 146 end
147 147
148 148 # Builds a Mail::Message object used to email recipients of a news' project when a news item is added.
149 149 #
150 150 # Example:
151 151 # news_added(news) => Mail::Message object
152 152 # Mailer.news_added(news).deliver => sends an email to the news' project recipients
153 153 def news_added(news)
154 154 redmine_headers 'Project' => news.project.identifier
155 155 @author = news.author
156 156 message_id news
157 157 references news
158 158 @news = news
159 159 @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
160 160 mail :to => news.notified_users,
161 161 :cc => news.notified_watchers_for_added_news,
162 162 :subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
163 163 end
164 164
165 165 # Builds a Mail::Message object used to email recipients of a news' project when a news comment is added.
166 166 #
167 167 # Example:
168 168 # news_comment_added(comment) => Mail::Message object
169 169 # Mailer.news_comment_added(comment) => sends an email to the news' project recipients
170 170 def news_comment_added(comment)
171 171 news = comment.commented
172 172 redmine_headers 'Project' => news.project.identifier
173 173 @author = comment.author
174 174 message_id comment
175 175 references news
176 176 @news = news
177 177 @comment = comment
178 178 @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
179 179 mail :to => news.notified_users,
180 180 :cc => news.notified_watchers,
181 181 :subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
182 182 end
183 183
184 184 # Builds a Mail::Message object used to email the recipients of the specified message that was posted.
185 185 #
186 186 # Example:
187 187 # message_posted(message) => Mail::Message object
188 188 # Mailer.message_posted(message).deliver => sends an email to the recipients
189 189 def message_posted(message)
190 190 redmine_headers 'Project' => message.project.identifier,
191 191 'Topic-Id' => (message.parent_id || message.id)
192 192 @author = message.author
193 193 message_id message
194 194 references message.root
195 195 recipients = message.notified_users
196 196 cc = ((message.root.notified_watchers + message.board.notified_watchers).uniq - recipients)
197 197 @message = message
198 198 @message_url = url_for(message.event_url)
199 199 mail :to => recipients,
200 200 :cc => cc,
201 201 :subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
202 202 end
203 203
204 204 # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added.
205 205 #
206 206 # Example:
207 207 # wiki_content_added(wiki_content) => Mail::Message object
208 208 # Mailer.wiki_content_added(wiki_content).deliver => sends an email to the project's recipients
209 209 def wiki_content_added(wiki_content)
210 210 redmine_headers 'Project' => wiki_content.project.identifier,
211 211 'Wiki-Page-Id' => wiki_content.page.id
212 212 @author = wiki_content.author
213 213 message_id wiki_content
214 214 recipients = wiki_content.notified_users
215 215 cc = wiki_content.page.wiki.notified_watchers - recipients
216 216 @wiki_content = wiki_content
217 217 @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
218 218 :project_id => wiki_content.project,
219 219 :id => wiki_content.page.title)
220 220 mail :to => recipients,
221 221 :cc => cc,
222 222 :subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
223 223 end
224 224
225 225 # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was updated.
226 226 #
227 227 # Example:
228 228 # wiki_content_updated(wiki_content) => Mail::Message object
229 229 # Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients
230 230 def wiki_content_updated(wiki_content)
231 231 redmine_headers 'Project' => wiki_content.project.identifier,
232 232 'Wiki-Page-Id' => wiki_content.page.id
233 233 @author = wiki_content.author
234 234 message_id wiki_content
235 235 recipients = wiki_content.notified_users
236 236 cc = wiki_content.page.wiki.notified_watchers + wiki_content.page.notified_watchers - recipients
237 237 @wiki_content = wiki_content
238 238 @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
239 239 :project_id => wiki_content.project,
240 240 :id => wiki_content.page.title)
241 241 @wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff',
242 242 :project_id => wiki_content.project, :id => wiki_content.page.title,
243 243 :version => wiki_content.version)
244 244 mail :to => recipients,
245 245 :cc => cc,
246 246 :subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
247 247 end
248 248
249 249 # Builds a Mail::Message object used to email the specified user their account information.
250 250 #
251 251 # Example:
252 252 # account_information(user, password) => Mail::Message object
253 253 # Mailer.account_information(user, password).deliver => sends account information to the user
254 254 def account_information(user, password)
255 255 set_language_if_valid user.language
256 256 @user = user
257 257 @password = password
258 258 @login_url = url_for(:controller => 'account', :action => 'login')
259 259 mail :to => user.mail,
260 260 :subject => l(:mail_subject_register, Setting.app_title)
261 261 end
262 262
263 263 # Builds a Mail::Message object used to email all active administrators of an account activation request.
264 264 #
265 265 # Example:
266 266 # account_activation_request(user) => Mail::Message object
267 267 # Mailer.account_activation_request(user).deliver => sends an email to all active administrators
268 268 def account_activation_request(user)
269 269 # Send the email to all active administrators
270 270 recipients = User.active.where(:admin => true)
271 271 @user = user
272 272 @url = url_for(:controller => 'users', :action => 'index',
273 273 :status => User::STATUS_REGISTERED,
274 274 :sort_key => 'created_on', :sort_order => 'desc')
275 275 mail :to => recipients,
276 276 :subject => l(:mail_subject_account_activation_request, Setting.app_title)
277 277 end
278 278
279 279 # Builds a Mail::Message object used to email the specified user that their account was activated by an administrator.
280 280 #
281 281 # Example:
282 282 # account_activated(user) => Mail::Message object
283 283 # Mailer.account_activated(user).deliver => sends an email to the registered user
284 284 def account_activated(user)
285 285 set_language_if_valid user.language
286 286 @user = user
287 287 @login_url = url_for(:controller => 'account', :action => 'login')
288 288 mail :to => user.mail,
289 289 :subject => l(:mail_subject_register, Setting.app_title)
290 290 end
291 291
292 def lost_password(token)
292 def lost_password(token, recipient=nil)
293 293 set_language_if_valid(token.user.language)
294 recipient ||= token.user.mail
294 295 @token = token
295 296 @url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
296 mail :to => token.user.mail,
297 mail :to => recipient,
297 298 :subject => l(:mail_subject_lost_password, Setting.app_title)
298 299 end
299 300
300 301 def register(token)
301 302 set_language_if_valid(token.user.language)
302 303 @token = token
303 304 @url = url_for(:controller => 'account', :action => 'activate', :token => token.value)
304 305 mail :to => token.user.mail,
305 306 :subject => l(:mail_subject_register, Setting.app_title)
306 307 end
307 308
308 309 def test_email(user)
309 310 set_language_if_valid(user.language)
310 311 @url = url_for(:controller => 'welcome')
311 312 mail :to => user.mail,
312 313 :subject => 'Redmine test'
313 314 end
314 315
315 316 # Sends reminders to issue assignees
316 317 # Available options:
317 318 # * :days => how many days in the future to remind about (defaults to 7)
318 319 # * :tracker => id of tracker for filtering issues (defaults to all trackers)
319 320 # * :project => id or identifier of project to process (defaults to all projects)
320 321 # * :users => array of user/group ids who should be reminded
321 322 def self.reminders(options={})
322 323 days = options[:days] || 7
323 324 project = options[:project] ? Project.find(options[:project]) : nil
324 325 tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
325 326 user_ids = options[:users]
326 327
327 328 scope = Issue.open.where("#{Issue.table_name}.assigned_to_id IS NOT NULL" +
328 329 " AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
329 330 " AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date
330 331 )
331 332 scope = scope.where(:assigned_to_id => user_ids) if user_ids.present?
332 333 scope = scope.where(:project_id => project.id) if project
333 334 scope = scope.where(:tracker_id => tracker.id) if tracker
334 335 issues_by_assignee = scope.includes(:status, :assigned_to, :project, :tracker).
335 336 group_by(&:assigned_to)
336 337 issues_by_assignee.keys.each do |assignee|
337 338 if assignee.is_a?(Group)
338 339 assignee.users.each do |user|
339 340 issues_by_assignee[user] ||= []
340 341 issues_by_assignee[user] += issues_by_assignee[assignee]
341 342 end
342 343 end
343 344 end
344 345
345 346 issues_by_assignee.each do |assignee, issues|
346 347 reminder(assignee, issues, days).deliver if assignee.is_a?(User) && assignee.active?
347 348 end
348 349 end
349 350
350 351 # Activates/desactivates email deliveries during +block+
351 352 def self.with_deliveries(enabled = true, &block)
352 353 was_enabled = ActionMailer::Base.perform_deliveries
353 354 ActionMailer::Base.perform_deliveries = !!enabled
354 355 yield
355 356 ensure
356 357 ActionMailer::Base.perform_deliveries = was_enabled
357 358 end
358 359
359 360 # Sends emails synchronously in the given block
360 361 def self.with_synched_deliveries(&block)
361 362 saved_method = ActionMailer::Base.delivery_method
362 363 if m = saved_method.to_s.match(%r{^async_(.+)$})
363 364 synched_method = m[1]
364 365 ActionMailer::Base.delivery_method = synched_method.to_sym
365 366 ActionMailer::Base.send "#{synched_method}_settings=", ActionMailer::Base.send("async_#{synched_method}_settings")
366 367 end
367 368 yield
368 369 ensure
369 370 ActionMailer::Base.delivery_method = saved_method
370 371 end
371 372
372 373 def mail(headers={}, &block)
373 374 headers.reverse_merge! 'X-Mailer' => 'Redmine',
374 375 'X-Redmine-Host' => Setting.host_name,
375 376 'X-Redmine-Site' => Setting.app_title,
376 377 'X-Auto-Response-Suppress' => 'OOF',
377 378 'Auto-Submitted' => 'auto-generated',
378 379 'From' => Setting.mail_from,
379 380 'List-Id' => "<#{Setting.mail_from.to_s.gsub('@', '.')}>"
380 381
381 382 # Replaces users with their email addresses
382 383 [:to, :cc, :bcc].each do |key|
383 384 if headers[key].present?
384 385 headers[key] = self.class.email_addresses(headers[key])
385 386 end
386 387 end
387 388
388 389 # Removes the author from the recipients and cc
389 390 # if the author does not want to receive notifications
390 391 # about what the author do
391 392 if @author && @author.logged? && @author.pref.no_self_notified
392 393 addresses = @author.mails
393 394 headers[:to] -= addresses if headers[:to].is_a?(Array)
394 395 headers[:cc] -= addresses if headers[:cc].is_a?(Array)
395 396 end
396 397
397 398 if @author && @author.logged?
398 399 redmine_headers 'Sender' => @author.login
399 400 end
400 401
401 402 # Blind carbon copy recipients
402 403 if Setting.bcc_recipients?
403 404 headers[:bcc] = [headers[:to], headers[:cc]].flatten.uniq.reject(&:blank?)
404 405 headers[:to] = nil
405 406 headers[:cc] = nil
406 407 end
407 408
408 409 if @message_id_object
409 410 headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>"
410 411 end
411 412 if @references_objects
412 413 headers[:references] = @references_objects.collect {|o| "<#{self.class.references_for(o)}>"}.join(' ')
413 414 end
414 415
415 416 m = if block_given?
416 417 super headers, &block
417 418 else
418 419 super headers do |format|
419 420 format.text
420 421 format.html unless Setting.plain_text_mail?
421 422 end
422 423 end
423 424 set_language_if_valid @initial_language
424 425
425 426 m
426 427 end
427 428
428 429 def initialize(*args)
429 430 @initial_language = current_language
430 431 set_language_if_valid Setting.default_language
431 432 super
432 433 end
433 434
434 435 def self.deliver_mail(mail)
435 436 return false if mail.to.blank? && mail.cc.blank? && mail.bcc.blank?
436 437 begin
437 438 # Log errors when raise_delivery_errors is set to false, Rails does not
438 439 mail.raise_delivery_errors = true
439 440 super
440 441 rescue Exception => e
441 442 if ActionMailer::Base.raise_delivery_errors
442 443 raise e
443 444 else
444 445 Rails.logger.error "Email delivery error: #{e.message}"
445 446 end
446 447 end
447 448 end
448 449
449 450 def self.method_missing(method, *args, &block)
450 451 if m = method.to_s.match(%r{^deliver_(.+)$})
451 452 ActiveSupport::Deprecation.warn "Mailer.deliver_#{m[1]}(*args) is deprecated. Use Mailer.#{m[1]}(*args).deliver instead."
452 453 send(m[1], *args).deliver
453 454 else
454 455 super
455 456 end
456 457 end
457 458
458 459 # Returns an array of email addresses to notify by
459 460 # replacing users in arg with their notified email addresses
460 461 #
461 462 # Example:
462 463 # Mailer.email_addresses(users)
463 464 # => ["foo@example.net", "bar@example.net"]
464 465 def self.email_addresses(arg)
465 466 arr = Array.wrap(arg)
466 467 mails = arr.reject {|a| a.is_a? Principal}
467 468 users = arr - mails
468 469 if users.any?
469 470 mails += EmailAddress.
470 471 where(:user_id => users.map(&:id)).
471 472 where("is_default = ? OR notify = ?", true, true).
472 473 pluck(:address)
473 474 end
474 475 mails
475 476 end
476 477
477 478 private
478 479
479 480 # Appends a Redmine header field (name is prepended with 'X-Redmine-')
480 481 def redmine_headers(h)
481 482 h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
482 483 end
483 484
484 485 def self.token_for(object, rand=true)
485 486 timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
486 487 hash = [
487 488 "redmine",
488 489 "#{object.class.name.demodulize.underscore}-#{object.id}",
489 490 timestamp.strftime("%Y%m%d%H%M%S")
490 491 ]
491 492 if rand
492 493 hash << Redmine::Utils.random_hex(8)
493 494 end
494 495 host = Setting.mail_from.to_s.strip.gsub(%r{^.*@|>}, '')
495 496 host = "#{::Socket.gethostname}.redmine" if host.empty?
496 497 "#{hash.join('.')}@#{host}"
497 498 end
498 499
499 500 # Returns a Message-Id for the given object
500 501 def self.message_id_for(object)
501 502 token_for(object, true)
502 503 end
503 504
504 505 # Returns a uniq token for a given object referenced by all notifications
505 506 # related to this object
506 507 def self.references_for(object)
507 508 token_for(object, false)
508 509 end
509 510
510 511 def message_id(object)
511 512 @message_id_object = object
512 513 end
513 514
514 515 def references(object)
515 516 @references_objects ||= []
516 517 @references_objects << object
517 518 end
518 519
519 520 def mylogger
520 521 Rails.logger
521 522 end
522 523 end
@@ -1,410 +1,424
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 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 File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class AccountControllerTest < ActionController::TestCase
21 21 fixtures :users, :roles
22 22
23 23 def setup
24 24 User.current = nil
25 25 end
26 26
27 27 def test_get_login
28 28 get :login
29 29 assert_response :success
30 30 assert_template 'login'
31 31
32 32 assert_select 'input[name=username]'
33 33 assert_select 'input[name=password]'
34 34 end
35 35
36 36 def test_get_login_while_logged_in_should_redirect_to_back_url_if_present
37 37 @request.session[:user_id] = 2
38 38 @request.env["HTTP_REFERER"] = 'http://test.host/issues/show/1'
39 39
40 40 get :login, :back_url => 'http://test.host/issues/show/1'
41 41 assert_redirected_to '/issues/show/1'
42 42 assert_equal 2, @request.session[:user_id]
43 43 end
44 44
45 45 def test_get_login_while_logged_in_should_redirect_to_referer_without_back_url
46 46 @request.session[:user_id] = 2
47 47 @request.env["HTTP_REFERER"] = 'http://test.host/issues/show/1'
48 48
49 49 get :login
50 50 assert_redirected_to '/issues/show/1'
51 51 assert_equal 2, @request.session[:user_id]
52 52 end
53 53
54 54 def test_get_login_while_logged_in_should_redirect_to_home_by_default
55 55 @request.session[:user_id] = 2
56 56
57 57 get :login
58 58 assert_redirected_to '/'
59 59 assert_equal 2, @request.session[:user_id]
60 60 end
61 61
62 62 def test_login_should_redirect_to_back_url_param
63 63 # request.uri is "test.host" in test environment
64 64 back_urls = [
65 65 'http://test.host/issues/show/1',
66 66 '/'
67 67 ]
68 68 back_urls.each do |back_url|
69 69 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url
70 70 assert_redirected_to back_url
71 71 end
72 72 end
73 73
74 74 def test_login_with_suburi_should_redirect_to_back_url_param
75 75 @relative_url_root = Redmine::Utils.relative_url_root
76 76 Redmine::Utils.relative_url_root = '/redmine'
77 77
78 78 back_urls = [
79 79 'http://test.host/redmine/issues/show/1',
80 80 '/redmine'
81 81 ]
82 82 back_urls.each do |back_url|
83 83 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url
84 84 assert_redirected_to back_url
85 85 end
86 86 ensure
87 87 Redmine::Utils.relative_url_root = @relative_url_root
88 88 end
89 89
90 90 def test_login_should_not_redirect_to_another_host
91 91 back_urls = [
92 92 'http://test.foo/fake',
93 93 '//test.foo/fake'
94 94 ]
95 95 back_urls.each do |back_url|
96 96 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url
97 97 assert_redirected_to '/my/page'
98 98 end
99 99 end
100 100
101 101 def test_login_with_suburi_should_not_redirect_to_another_suburi
102 102 @relative_url_root = Redmine::Utils.relative_url_root
103 103 Redmine::Utils.relative_url_root = '/redmine'
104 104
105 105 back_urls = [
106 106 'http://test.host/',
107 107 'http://test.host/fake',
108 108 'http://test.host/fake/issues',
109 109 'http://test.host/redmine/../fake',
110 110 'http://test.host/redmine/../fake/issues',
111 111 'http://test.host/redmine/%2e%2e/fake'
112 112 ]
113 113 back_urls.each do |back_url|
114 114 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url
115 115 assert_redirected_to '/my/page'
116 116 end
117 117 ensure
118 118 Redmine::Utils.relative_url_root = @relative_url_root
119 119 end
120 120
121 121 def test_login_with_wrong_password
122 122 post :login, :username => 'admin', :password => 'bad'
123 123 assert_response :success
124 124 assert_template 'login'
125 125
126 126 assert_select 'div.flash.error', :text => /Invalid user or password/
127 127 assert_select 'input[name=username][value=admin]'
128 128 assert_select 'input[name=password]'
129 129 assert_select 'input[name=password][value]', 0
130 130 end
131 131
132 132 def test_login_with_locked_account_should_fail
133 133 User.find(2).update_attribute :status, User::STATUS_LOCKED
134 134
135 135 post :login, :username => 'jsmith', :password => 'jsmith'
136 136 assert_redirected_to '/login'
137 137 assert_include 'locked', flash[:error]
138 138 assert_nil @request.session[:user_id]
139 139 end
140 140
141 141 def test_login_as_registered_user_with_manual_activation_should_inform_user
142 142 User.find(2).update_attribute :status, User::STATUS_REGISTERED
143 143
144 144 with_settings :self_registration => '2', :default_language => 'en' do
145 145 post :login, :username => 'jsmith', :password => 'jsmith'
146 146 assert_redirected_to '/login'
147 147 assert_include 'pending administrator approval', flash[:error]
148 148 end
149 149 end
150 150
151 151 def test_login_as_registered_user_with_email_activation_should_propose_new_activation_email
152 152 User.find(2).update_attribute :status, User::STATUS_REGISTERED
153 153
154 154 with_settings :self_registration => '1', :default_language => 'en' do
155 155 post :login, :username => 'jsmith', :password => 'jsmith'
156 156 assert_redirected_to '/login'
157 157 assert_equal 2, @request.session[:registered_user_id]
158 158 assert_include 'new activation email', flash[:error]
159 159 end
160 160 end
161 161
162 162 def test_login_should_rescue_auth_source_exception
163 163 source = AuthSource.create!(:name => 'Test')
164 164 User.find(2).update_attribute :auth_source_id, source.id
165 165 AuthSource.any_instance.stubs(:authenticate).raises(AuthSourceException.new("Something wrong"))
166 166
167 167 post :login, :username => 'jsmith', :password => 'jsmith'
168 168 assert_response 500
169 169 assert_select_error /Something wrong/
170 170 end
171 171
172 172 def test_login_should_reset_session
173 173 @controller.expects(:reset_session).once
174 174
175 175 post :login, :username => 'jsmith', :password => 'jsmith'
176 176 assert_response 302
177 177 end
178 178
179 179 def test_get_logout_should_not_logout
180 180 @request.session[:user_id] = 2
181 181 get :logout
182 182 assert_response :success
183 183 assert_template 'logout'
184 184
185 185 assert_equal 2, @request.session[:user_id]
186 186 end
187 187
188 188 def test_get_logout_with_anonymous_should_redirect
189 189 get :logout
190 190 assert_redirected_to '/'
191 191 end
192 192
193 193 def test_logout
194 194 @request.session[:user_id] = 2
195 195 post :logout
196 196 assert_redirected_to '/'
197 197 assert_nil @request.session[:user_id]
198 198 end
199 199
200 200 def test_logout_should_reset_session
201 201 @controller.expects(:reset_session).once
202 202
203 203 @request.session[:user_id] = 2
204 204 post :logout
205 205 assert_response 302
206 206 end
207 207
208 208 def test_get_register_with_registration_on
209 209 with_settings :self_registration => '3' do
210 210 get :register
211 211 assert_response :success
212 212 assert_template 'register'
213 213 assert_not_nil assigns(:user)
214 214
215 215 assert_select 'input[name=?]', 'user[password]'
216 216 assert_select 'input[name=?]', 'user[password_confirmation]'
217 217 end
218 218 end
219 219
220 220 def test_get_register_should_detect_user_language
221 221 with_settings :self_registration => '3' do
222 222 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
223 223 get :register
224 224 assert_response :success
225 225 assert_not_nil assigns(:user)
226 226 assert_equal 'fr', assigns(:user).language
227 227 assert_select 'select[name=?]', 'user[language]' do
228 228 assert_select 'option[value=fr][selected=selected]'
229 229 end
230 230 end
231 231 end
232 232
233 233 def test_get_register_with_registration_off_should_redirect
234 234 with_settings :self_registration => '0' do
235 235 get :register
236 236 assert_redirected_to '/'
237 237 end
238 238 end
239 239
240 240 # See integration/account_test.rb for the full test
241 241 def test_post_register_with_registration_on
242 242 with_settings :self_registration => '3' do
243 243 assert_difference 'User.count' do
244 244 post :register, :user => {
245 245 :login => 'register',
246 246 :password => 'secret123',
247 247 :password_confirmation => 'secret123',
248 248 :firstname => 'John',
249 249 :lastname => 'Doe',
250 250 :mail => 'register@example.com'
251 251 }
252 252 assert_redirected_to '/my/account'
253 253 end
254 254 user = User.order('id DESC').first
255 255 assert_equal 'register', user.login
256 256 assert_equal 'John', user.firstname
257 257 assert_equal 'Doe', user.lastname
258 258 assert_equal 'register@example.com', user.mail
259 259 assert user.check_password?('secret123')
260 260 assert user.active?
261 261 end
262 262 end
263 263
264 264 def test_post_register_with_registration_off_should_redirect
265 265 with_settings :self_registration => '0' do
266 266 assert_no_difference 'User.count' do
267 267 post :register, :user => {
268 268 :login => 'register',
269 269 :password => 'test',
270 270 :password_confirmation => 'test',
271 271 :firstname => 'John',
272 272 :lastname => 'Doe',
273 273 :mail => 'register@example.com'
274 274 }
275 275 assert_redirected_to '/'
276 276 end
277 277 end
278 278 end
279 279
280 280 def test_get_lost_password_should_display_lost_password_form
281 281 get :lost_password
282 282 assert_response :success
283 283 assert_select 'input[name=mail]'
284 284 end
285 285
286 286 def test_lost_password_for_active_user_should_create_a_token
287 287 Token.delete_all
288 288 ActionMailer::Base.deliveries.clear
289 289 assert_difference 'ActionMailer::Base.deliveries.size' do
290 290 assert_difference 'Token.count' do
291 291 with_settings :host_name => 'mydomain.foo', :protocol => 'http' do
292 292 post :lost_password, :mail => 'JSmith@somenet.foo'
293 293 assert_redirected_to '/login'
294 294 end
295 295 end
296 296 end
297 297
298 298 token = Token.order('id DESC').first
299 299 assert_equal User.find(2), token.user
300 300 assert_equal 'recovery', token.action
301 301
302 302 assert_select_email do
303 303 assert_select "a[href=?]", "http://mydomain.foo/account/lost_password?token=#{token.value}"
304 304 end
305 305 end
306 306
307 def test_lost_password_using_additional_email_address_should_send_email_to_the_address
308 EmailAddress.create!(:user_id => 2, :address => 'anotherAddress@foo.bar')
309 Token.delete_all
310
311 assert_difference 'ActionMailer::Base.deliveries.size' do
312 assert_difference 'Token.count' do
313 post :lost_password, :mail => 'ANOTHERaddress@foo.bar'
314 assert_redirected_to '/login'
315 end
316 end
317 mail = ActionMailer::Base.deliveries.last
318 assert_equal ['anotherAddress@foo.bar'], mail.bcc
319 end
320
307 321 def test_lost_password_for_unknown_user_should_fail
308 322 Token.delete_all
309 323 assert_no_difference 'Token.count' do
310 324 post :lost_password, :mail => 'invalid@somenet.foo'
311 325 assert_response :success
312 326 end
313 327 end
314 328
315 329 def test_lost_password_for_non_active_user_should_fail
316 330 Token.delete_all
317 331 assert User.find(2).lock!
318 332
319 333 assert_no_difference 'Token.count' do
320 334 post :lost_password, :mail => 'JSmith@somenet.foo'
321 335 assert_redirected_to '/account/lost_password'
322 336 end
323 337 end
324 338
325 339 def test_lost_password_for_user_who_cannot_change_password_should_fail
326 340 User.any_instance.stubs(:change_password_allowed?).returns(false)
327 341
328 342 assert_no_difference 'Token.count' do
329 343 post :lost_password, :mail => 'JSmith@somenet.foo'
330 344 assert_response :success
331 345 end
332 346 end
333 347
334 348 def test_get_lost_password_with_token_should_display_the_password_recovery_form
335 349 user = User.find(2)
336 350 token = Token.create!(:action => 'recovery', :user => user)
337 351
338 352 get :lost_password, :token => token.value
339 353 assert_response :success
340 354 assert_template 'password_recovery'
341 355
342 356 assert_select 'input[type=hidden][name=token][value=?]', token.value
343 357 end
344 358
345 359 def test_get_lost_password_with_invalid_token_should_redirect
346 360 get :lost_password, :token => "abcdef"
347 361 assert_redirected_to '/'
348 362 end
349 363
350 364 def test_post_lost_password_with_token_should_change_the_user_password
351 365 user = User.find(2)
352 366 token = Token.create!(:action => 'recovery', :user => user)
353 367
354 368 post :lost_password, :token => token.value, :new_password => 'newpass123', :new_password_confirmation => 'newpass123'
355 369 assert_redirected_to '/login'
356 370 user.reload
357 371 assert user.check_password?('newpass123')
358 372 assert_nil Token.find_by_id(token.id), "Token was not deleted"
359 373 end
360 374
361 375 def test_post_lost_password_with_token_for_non_active_user_should_fail
362 376 user = User.find(2)
363 377 token = Token.create!(:action => 'recovery', :user => user)
364 378 user.lock!
365 379
366 380 post :lost_password, :token => token.value, :new_password => 'newpass123', :new_password_confirmation => 'newpass123'
367 381 assert_redirected_to '/'
368 382 assert ! user.check_password?('newpass123')
369 383 end
370 384
371 385 def test_post_lost_password_with_token_and_password_confirmation_failure_should_redisplay_the_form
372 386 user = User.find(2)
373 387 token = Token.create!(:action => 'recovery', :user => user)
374 388
375 389 post :lost_password, :token => token.value, :new_password => 'newpass', :new_password_confirmation => 'wrongpass'
376 390 assert_response :success
377 391 assert_template 'password_recovery'
378 392 assert_not_nil Token.find_by_id(token.id), "Token was deleted"
379 393
380 394 assert_select 'input[type=hidden][name=token][value=?]', token.value
381 395 end
382 396
383 397 def test_post_lost_password_with_invalid_token_should_redirect
384 398 post :lost_password, :token => "abcdef", :new_password => 'newpass', :new_password_confirmation => 'newpass'
385 399 assert_redirected_to '/'
386 400 end
387 401
388 402 def test_activation_email_should_send_an_activation_email
389 403 User.find(2).update_attribute :status, User::STATUS_REGISTERED
390 404 @request.session[:registered_user_id] = 2
391 405
392 406 with_settings :self_registration => '1' do
393 407 assert_difference 'ActionMailer::Base.deliveries.size' do
394 408 get :activation_email
395 409 assert_redirected_to '/login'
396 410 end
397 411 end
398 412 end
399 413
400 414 def test_activation_email_without_session_data_should_fail
401 415 User.find(2).update_attribute :status, User::STATUS_REGISTERED
402 416
403 417 with_settings :self_registration => '1' do
404 418 assert_no_difference 'ActionMailer::Base.deliveries.size' do
405 419 get :activation_email
406 420 assert_redirected_to '/'
407 421 end
408 422 end
409 423 end
410 424 end
General Comments 0
You need to be logged in to leave comments. Login now