##// END OF EJS Templates
Improved user creation from incoming email....
Jean-Philippe Lang -
r7832:6076db74f179
parent child
Show More
@@ -61,7 +61,7 class MailHandler < ActionMailer::Base
61 when 'accept'
61 when 'accept'
62 @user = User.anonymous
62 @user = User.anonymous
63 when 'create'
63 when 'create'
64 @user = MailHandler.create_user_from_email(email)
64 @user = create_user_from_email(email)
65 if @user
65 if @user
66 logger.info "MailHandler: [#{@user.login}] account created" if logger && logger.info
66 logger.info "MailHandler: [#{@user.login}] account created" if logger && logger.info
67 Mailer.deliver_account_information(@user, @user.password)
67 Mailer.deliver_account_information(@user, @user.password)
@@ -322,22 +322,53 class MailHandler < ActionMailer::Base
322 @full_sanitizer ||= HTML::FullSanitizer.new
322 @full_sanitizer ||= HTML::FullSanitizer.new
323 end
323 end
324
324
325 # Creates a user account for the +email+ sender
325 def self.assign_string_attribute_with_limit(object, attribute, value)
326 def self.create_user_from_email(email)
326 limit = object.class.columns_hash[attribute.to_s].limit || 255
327 value = value.to_s.slice(0, limit)
328 object.send("#{attribute}=", value)
329 end
330
331 # Returns a User from an email address and a full name
332 def self.new_user_from_attributes(email_address, fullname=nil)
333 user = User.new
334
335 # Truncating the email address would result in an invalid format
336 user.mail = email_address
337 assign_string_attribute_with_limit(user, 'login', email_address)
338
339 names = fullname.blank? ? email_address.gsub(/@.*$/, '').split('.') : fullname.split
340 assign_string_attribute_with_limit(user, 'firstname', names.shift)
341 assign_string_attribute_with_limit(user, 'lastname', names.join(' '))
342 user.lastname = '-' if user.lastname.blank?
343
344 password_length = [Setting.password_min_length.to_i, 10].max
345 user.password = ActiveSupport::SecureRandom.hex(password_length / 2 + 1)
346 user.language = Setting.default_language
347
348 unless user.valid?
349 user.login = "user#{ActiveSupport::SecureRandom.hex(6)}" if user.errors.on(:login)
350 user.firstname = "-" if user.errors.on(:firstname)
351 user.lastname = "-" if user.errors.on(:lastname)
352 end
353
354 user
355 end
356
357 # Creates a User for the +email+ sender
358 # Returns the user or nil if it could not be created
359 def create_user_from_email(email)
327 addr = email.from_addrs.to_a.first
360 addr = email.from_addrs.to_a.first
328 if addr && !addr.spec.blank?
361 if addr && !addr.spec.blank?
329 user = User.new
362 user = self.class.new_user_from_attributes(addr.spec, addr.name)
330 user.mail = addr.spec
363 if user.save
331
364 user
332 names = addr.name.blank? ? addr.spec.gsub(/@.*$/, '').split('.') : addr.name.split
365 else
333 user.firstname = names.shift
366 logger.error "MailHandler: failed to create User: #{user.errors.full_messages}" if logger
334 user.lastname = names.join(' ')
367 nil
335 user.lastname = '-' if user.lastname.blank?
368 end
336
369 else
337 user.login = user.mail
370 logger.error "MailHandler: failed to create User: no FROM address found" if logger
338 user.password = ActiveSupport::SecureRandom.hex(5)
371 nil
339 user.language = Setting.default_language
340 user.save ? user : nil
341 end
372 end
342 end
373 end
343
374
@@ -485,6 +485,46 class MailHandlerTest < ActiveSupport::TestCase
485 assert_equal issue.subject, 'New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...'[0,255]
485 assert_equal issue.subject, 'New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...'[0,255]
486 end
486 end
487
487
488 def test_new_user_from_attributes_should_return_valid_user
489 to_test = {
490 # [address, name] => [login, firstname, lastname]
491 ['jsmith@example.net', nil] => ['jsmith@example.net', 'jsmith', '-'],
492 ['jsmith@example.net', 'John'] => ['jsmith@example.net', 'John', '-'],
493 ['jsmith@example.net', 'John Smith'] => ['jsmith@example.net', 'John', 'Smith'],
494 ['jsmith@example.net', 'John Paul Smith'] => ['jsmith@example.net', 'John', 'Paul Smith'],
495 ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsTheMaximumLength Smith'] => ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsT', 'Smith'],
496 ['jsmith@example.net', 'John AVeryLongLastnameThatExceedsTheMaximumLength'] => ['jsmith@example.net', 'John', 'AVeryLongLastnameThatExceedsTh'],
497 ['alongemailaddressthatexceedsloginlength@example.net', 'John Smith'] => ['alongemailaddressthatexceedslo', 'John', 'Smith']
498 }
499
500 to_test.each do |attrs, expected|
501 user = MailHandler.new_user_from_attributes(attrs.first, attrs.last)
502
503 assert user.valid?
504 assert_equal attrs.first, user.mail
505 assert_equal expected[0], user.login
506 assert_equal expected[1], user.firstname
507 assert_equal expected[2], user.lastname
508 end
509 end
510
511 def test_new_user_from_attributes_should_respect_minimum_password_length
512 with_settings :password_min_length => 15 do
513 user = MailHandler.new_user_from_attributes('jsmith@example.net')
514 assert user.valid?
515 assert user.password.length >= 15
516 end
517 end
518
519 def test_new_user_from_attributes_should_use_default_login_if_invalid
520 MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-1@example.net').save!
521
522 # another long address that would result in duplicate login
523 user = MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-2@example.net')
524 assert user.valid?
525 assert user.login =~ /^user[a-f0-9]+$/
526 end
527
488 private
528 private
489
529
490 def submit_email(filename, options={})
530 def submit_email(filename, options={})
General Comments 0
You need to be logged in to leave comments. Login now