Commit 90a1b0b2ea88df9903f56def63bf7498d3db93d9
1 parent
25df24bd
Exists in
master
and in
28 other branches
forgot_password: search by all fields instead of field selection
Showing
7 changed files
with
60 additions
and
91 deletions
Show diff stats
app/models/change_password.rb
| 1 | class ChangePassword < Task | 1 | class ChangePassword < Task |
| 2 | 2 | ||
| 3 | - settings_items :field, :value | 3 | + settings_items :value |
| 4 | attr_accessor :password, :password_confirmation, :environment_id | 4 | attr_accessor :password, :password_confirmation, :environment_id |
| 5 | 5 | ||
| 6 | include Noosfero::Plugin::HotSpot | 6 | include Noosfero::Plugin::HotSpot |
| 7 | 7 | ||
| 8 | def self.human_attribute_name(attrib) | 8 | def self.human_attribute_name(attrib) |
| 9 | case attrib.to_sym | 9 | case attrib.to_sym |
| 10 | - when :field | ||
| 11 | - _('Field') | ||
| 12 | when :value | 10 | when :value |
| 13 | _('Value') | 11 | _('Value') |
| 14 | when :password | 12 | when :password |
| @@ -20,49 +18,54 @@ class ChangePassword < Task | @@ -20,49 +18,54 @@ class ChangePassword < Task | ||
| 20 | end | 18 | end |
| 21 | end | 19 | end |
| 22 | 20 | ||
| 23 | - def plugins_fields | ||
| 24 | - plugins.dispatch(:change_password_fields).inject({}) { |result, fields| result.merge!(fields)} | ||
| 25 | - end | ||
| 26 | - | ||
| 27 | def environment | 21 | def environment |
| 28 | (requestor.environment if requestor) || Environment.find_by_id(environment_id) | 22 | (requestor.environment if requestor) || Environment.find_by_id(environment_id) |
| 29 | end | 23 | end |
| 30 | 24 | ||
| 25 | + def plugins_options | ||
| 26 | + plugins.dispatch(:change_password_fields) | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + def user_fields | ||
| 30 | + %w[login email] + plugins_options.select {|options| options[:model].to_sym == :user }.map { |options| options[:field].to_s } | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + def person_fields | ||
| 34 | + %w[] + plugins_options.select {|options| options[:model].to_sym == :person }.map { |options| options[:field].to_s } | ||
| 35 | + end | ||
| 36 | + | ||
| 31 | def fields | 37 | def fields |
| 32 | - %w[login email] + plugins_fields.map { |field, name| field.to_s } | 38 | + user_fields + person_fields |
| 33 | end | 39 | end |
| 34 | 40 | ||
| 35 | - def fields_choice | ||
| 36 | - [ | ||
| 37 | - [_('Username'), 'login'], | ||
| 38 | - [_('Email'), 'email'], | ||
| 39 | - ] + plugins_fields.map { |field, name| [name, field] } | 41 | + def fields_label |
| 42 | + labels = [ | ||
| 43 | + _('Username'), | ||
| 44 | + _('Email'), | ||
| 45 | + ] + plugins_options.map { |options| options[:name] } | ||
| 46 | + | ||
| 47 | + last = labels.pop | ||
| 48 | + label = labels.join(', ') | ||
| 49 | + "#{label} #{_('or')} #{last}" | ||
| 40 | end | 50 | end |
| 41 | 51 | ||
| 42 | ################################################### | 52 | ################################################### |
| 43 | # validations for creating a ChangePassword task | 53 | # validations for creating a ChangePassword task |
| 44 | 54 | ||
| 45 | - validates_presence_of :field, :value, :environment_id, :on => :create, :message => _('must be filled in') | ||
| 46 | - # TODO Only on rails3 | ||
| 47 | - # validates_inclusion_of :field, :in => lambda { |data| data.fields } | ||
| 48 | - validates_each :field do |data, attr, value| | ||
| 49 | - unless data.fields.include?(value) | ||
| 50 | - data.errors.add(attr, _('is not in the list of valid fields.')) | ||
| 51 | - end | ||
| 52 | - end | 55 | + validates_presence_of :value, :environment_id, :on => :create, :message => _('must be filled in') |
| 53 | 56 | ||
| 54 | validates_each :value, :on => :create do |data,attr,value| | 57 | validates_each :value, :on => :create do |data,attr,value| |
| 55 | - unless data.field.blank? || data.value.blank? | ||
| 56 | - user = data.user_find | ||
| 57 | - if user.nil? | ||
| 58 | - data.errors.add(:value, _('"%s" is not a valid %s.') % [value.to_s, human_attribute_name(data.field)]) | 58 | + unless data.value.blank? |
| 59 | + users = data.find_users | ||
| 60 | + if users.blank? | ||
| 61 | + data.errors.add(:value, _('"%s" is not valid.') % value.to_s) | ||
| 59 | end | 62 | end |
| 60 | end | 63 | end |
| 61 | end | 64 | end |
| 62 | 65 | ||
| 63 | before_validation do |change_password| | 66 | before_validation do |change_password| |
| 64 | - user = change_password.user_find | ||
| 65 | - change_password.requestor = user.person if user | 67 | + users = change_password.find_users |
| 68 | + change_password.requestor ||= users.first.person if users.present? | ||
| 66 | end | 69 | end |
| 67 | 70 | ||
| 68 | ################################################### | 71 | ################################################### |
| @@ -73,15 +76,18 @@ class ChangePassword < Task | @@ -73,15 +76,18 @@ class ChangePassword < Task | ||
| 73 | validates_presence_of :password_confirmation, :on => :update, :if => lambda { |change| change.status != Task::Status::CANCELLED } | 76 | validates_presence_of :password_confirmation, :on => :update, :if => lambda { |change| change.status != Task::Status::CANCELLED } |
| 74 | validates_confirmation_of :password, :if => lambda { |change| change.status != Task::Status::CANCELLED } | 77 | validates_confirmation_of :password, :if => lambda { |change| change.status != Task::Status::CANCELLED } |
| 75 | 78 | ||
| 76 | - def user_find | ||
| 77 | - begin | ||
| 78 | - method = "find_by_#{field}_and_environment_id" | ||
| 79 | - user = nil | ||
| 80 | - user = User.send(method, value, environment_id) if User.respond_to?(method) | ||
| 81 | - user = Person.send(method, value, environment_id).user if user.nil? && Person.respond_to?(method) | ||
| 82 | - rescue | ||
| 83 | - end | ||
| 84 | - user | 79 | + def build_query(fields) |
| 80 | + fields.map {|field| "#{field} = '#{value}'"}.join(' OR ') | ||
| 81 | + end | ||
| 82 | + | ||
| 83 | + def find_users | ||
| 84 | + results = [] | ||
| 85 | + person_query = build_query(person_fields) | ||
| 86 | + user_query = build_query(user_fields) | ||
| 87 | + | ||
| 88 | + results += Person.where(person_query).where(:environment_id => environment.id).map(&:user) | ||
| 89 | + results += User.where(user_query).where(:environment_id => environment.id) | ||
| 90 | + results | ||
| 85 | end | 91 | end |
| 86 | 92 | ||
| 87 | def title | 93 | def title |
app/views/account/forgot_password.rhtml
| @@ -4,8 +4,7 @@ | @@ -4,8 +4,7 @@ | ||
| 4 | 4 | ||
| 5 | <% labelled_form_for :change_password, @change_password, :url => { :action => 'forgot_password' } do |f| %> | 5 | <% labelled_form_for :change_password, @change_password, :url => { :action => 'forgot_password' } do |f| %> |
| 6 | 6 | ||
| 7 | - <%= labelled_form_field(_('What do you remember?'), f.select(:field, @change_password.fields_choice)) %> | ||
| 8 | - <%= text_field_tag('change_password[value]') %> | 7 | + <%= labelled_form_field @change_password.fields_label, text_field_tag('change_password[value]') %> |
| 9 | 8 | ||
| 10 | <div> | 9 | <div> |
| 11 | <% button_bar do %> | 10 | <% button_bar do %> |
lib/noosfero/plugin.rb
| @@ -461,7 +461,7 @@ class Noosfero::Plugin | @@ -461,7 +461,7 @@ class Noosfero::Plugin | ||
| 461 | end | 461 | end |
| 462 | 462 | ||
| 463 | # -> Adds aditional fields for change_password | 463 | # -> Adds aditional fields for change_password |
| 464 | - # returns = {:field1 => 'field1 name', :field2 => 'field2 name' ... } | 464 | + # returns = [{:field => 'field1', :name => 'field 1 name', :model => 'person'}, {...}] |
| 465 | def change_password_fields | 465 | def change_password_fields |
| 466 | nil | 466 | nil |
| 467 | end | 467 | end |
plugins/stoa/lib/stoa_plugin.rb
| @@ -121,7 +121,7 @@ class StoaPlugin < Noosfero::Plugin | @@ -121,7 +121,7 @@ class StoaPlugin < Noosfero::Plugin | ||
| 121 | end | 121 | end |
| 122 | 122 | ||
| 123 | def change_password_fields | 123 | def change_password_fields |
| 124 | - {:usp_id => _('USP Number')} | 124 | + {:field => :usp_id, :name => _('USP Number'), :model => 'person'} |
| 125 | end | 125 | end |
| 126 | 126 | ||
| 127 | end | 127 | end |
plugins/stoa/test/functional/account_controller_test.rb
| @@ -67,7 +67,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -67,7 +67,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 67 | end | 67 | end |
| 68 | 68 | ||
| 69 | should 'be able to recover password with usp_id' do | 69 | should 'be able to recover password with usp_id' do |
| 70 | - post :forgot_password, :change_password => { :field => 'usp_id', :value => '87654321' } | 70 | + post :forgot_password, :change_password => { :value => '87654321' } |
| 71 | assert_template 'password_recovery_sent' | 71 | assert_template 'password_recovery_sent' |
| 72 | end | 72 | end |
| 73 | end | 73 | end |
test/functional/account_controller_test.rb
| @@ -217,19 +217,19 @@ class AccountControllerTest < ActionController::TestCase | @@ -217,19 +217,19 @@ class AccountControllerTest < ActionController::TestCase | ||
| 217 | 217 | ||
| 218 | should 'respond to forgotten password change request with login' do | 218 | should 'respond to forgotten password change request with login' do |
| 219 | change = ChangePassword.new | 219 | change = ChangePassword.new |
| 220 | - ChangePassword.expects(:new).with('field' => 'login', 'value' => 'test').returns(change) | 220 | + ChangePassword.expects(:new).with('value' => 'test').returns(change) |
| 221 | change.expects(:save!).returns(true) | 221 | change.expects(:save!).returns(true) |
| 222 | 222 | ||
| 223 | - post :forgot_password, :change_password => { :field => 'login', :value => 'test' } | 223 | + post :forgot_password, :change_password => { :value => 'test' } |
| 224 | assert_template 'password_recovery_sent' | 224 | assert_template 'password_recovery_sent' |
| 225 | end | 225 | end |
| 226 | 226 | ||
| 227 | should 'respond to forgotten password change request with email' do | 227 | should 'respond to forgotten password change request with email' do |
| 228 | change = ChangePassword.new | 228 | change = ChangePassword.new |
| 229 | - ChangePassword.expects(:new).with('field' => 'email', 'value' => 'test@localhost.localdomain').returns(change) | 229 | + ChangePassword.expects(:new).with('value' => 'test@localhost.localdomain').returns(change) |
| 230 | change.expects(:save!).returns(true) | 230 | change.expects(:save!).returns(true) |
| 231 | 231 | ||
| 232 | - post :forgot_password, :change_password => { :field => 'email', :value => 'test@localhost.localdomain' } | 232 | + post :forgot_password, :change_password => { :value => 'test@localhost.localdomain' } |
| 233 | assert_template 'password_recovery_sent' | 233 | assert_template 'password_recovery_sent' |
| 234 | end | 234 | end |
| 235 | 235 | ||
| @@ -276,7 +276,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -276,7 +276,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 276 | 276 | ||
| 277 | should 'require password confirmation correctly to enter new pasword' do | 277 | should 'require password confirmation correctly to enter new pasword' do |
| 278 | user = create_user('testuser', :email => 'testuser@example.com', :password => 'test', :password_confirmation => 'test') | 278 | user = create_user('testuser', :email => 'testuser@example.com', :password => 'test', :password_confirmation => 'test') |
| 279 | - change = ChangePassword.create!(:field => 'login', :value => 'testuser', :environment_id => Environment.default.id) | 279 | + change = ChangePassword.create!(:value => 'testuser', :environment_id => Environment.default.id) |
| 280 | 280 | ||
| 281 | post :new_password, :code => change.code, :change_password => { :password => 'onepass', :password_confirmation => 'another_pass' } | 281 | post :new_password, :code => change.code, :change_password => { :password => 'onepass', :password_confirmation => 'another_pass' } |
| 282 | assert_response :success | 282 | assert_response :success |
| @@ -862,7 +862,7 @@ class AccountControllerTest < ActionController::TestCase | @@ -862,7 +862,7 @@ class AccountControllerTest < ActionController::TestCase | ||
| 862 | assert_response :redirect | 862 | assert_response :redirect |
| 863 | 863 | ||
| 864 | #Redirect on post action | 864 | #Redirect on post action |
| 865 | - post :forgot_password, :change_password => { :field => 'login', :value => 'test' } | 865 | + post :forgot_password, :change_password => { :value => 'test' } |
| 866 | assert_response :redirect | 866 | assert_response :redirect |
| 867 | end | 867 | end |
| 868 | 868 |
test/unit/change_password_test.rb
| @@ -9,39 +9,7 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -9,39 +9,7 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 9 | assert !data.valid? | 9 | assert !data.valid? |
| 10 | end | 10 | end |
| 11 | 11 | ||
| 12 | - should 'validate field is login or email' do | ||
| 13 | - data = ChangePassword.new(:environment_id => Environment.default) | ||
| 14 | - data.field = 'anything' | ||
| 15 | - data.valid? | ||
| 16 | - assert data.errors.invalid?(:field) | ||
| 17 | - | ||
| 18 | - data.field = 'login' | ||
| 19 | - data.valid? | ||
| 20 | - assert !data.errors.invalid?(:field) | ||
| 21 | - | ||
| 22 | - data.field = 'email' | ||
| 23 | - data.valid? | ||
| 24 | - assert !data.errors.invalid?(:field) | ||
| 25 | - end | ||
| 26 | - | ||
| 27 | - should 'refuse invalid field' do | ||
| 28 | - User.destroy_all | ||
| 29 | - | ||
| 30 | - data = ChangePassword.new | ||
| 31 | - data.environment_id = Environment.default.id | ||
| 32 | - | ||
| 33 | - data.field = 'login' | ||
| 34 | - data.value = 'unexisting' | ||
| 35 | - data.valid? | ||
| 36 | - assert data.errors.invalid?(:value) | ||
| 37 | - | ||
| 38 | - data.field = 'email' | ||
| 39 | - data.value = 'example@example.com' | ||
| 40 | - data.valid? | ||
| 41 | - assert data.errors.invalid?(:value) | ||
| 42 | - end | ||
| 43 | - | ||
| 44 | - should 'require only a valid field-value' do | 12 | + should 'require only a valid value' do |
| 45 | User.destroy_all | 13 | User.destroy_all |
| 46 | create_user('testuser', :email => 'test@example.com') | 14 | create_user('testuser', :email => 'test@example.com') |
| 47 | 15 | ||
| @@ -50,12 +18,10 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -50,12 +18,10 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 50 | assert !data.valid? | 18 | assert !data.valid? |
| 51 | assert data.errors.invalid?(:value) | 19 | assert data.errors.invalid?(:value) |
| 52 | 20 | ||
| 53 | - data.field = 'login' | ||
| 54 | data.value = 'testuser' | 21 | data.value = 'testuser' |
| 55 | data.valid? | 22 | data.valid? |
| 56 | assert data.valid? | 23 | assert data.valid? |
| 57 | 24 | ||
| 58 | - data.field = 'email' | ||
| 59 | data.value = 'test@example.com' | 25 | data.value = 'test@example.com' |
| 60 | assert data.valid? | 26 | assert data.valid? |
| 61 | end | 27 | end |
| @@ -65,7 +31,6 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -65,7 +31,6 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 65 | 31 | ||
| 66 | change = ChangePassword.new | 32 | change = ChangePassword.new |
| 67 | change.environment_id = Environment.default.id | 33 | change.environment_id = Environment.default.id |
| 68 | - change.field = 'login' | ||
| 69 | change.value = 'testuser' | 34 | change.value = 'testuser' |
| 70 | change.save! | 35 | change.save! |
| 71 | 36 | ||
| @@ -86,7 +51,6 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -86,7 +51,6 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 86 | 51 | ||
| 87 | change = ChangePassword.new | 52 | change = ChangePassword.new |
| 88 | change.environment_id = Environment.default.id | 53 | change.environment_id = Environment.default.id |
| 89 | - change.field = 'login' | ||
| 90 | change.value = 'testuser' | 54 | change.value = 'testuser' |
| 91 | change.save! | 55 | change.save! |
| 92 | 56 | ||
| @@ -105,7 +69,6 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -105,7 +69,6 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 105 | 69 | ||
| 106 | change = ChangePassword.new | 70 | change = ChangePassword.new |
| 107 | change.environment_id = Environment.default.id | 71 | change.environment_id = Environment.default.id |
| 108 | - change.field = 'login' | ||
| 109 | change.value = 'testuser' | 72 | change.value = 'testuser' |
| 110 | change.save! | 73 | change.save! |
| 111 | 74 | ||
| @@ -127,8 +90,8 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -127,8 +90,8 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 127 | p1 = create_user('sample-user', :password => 'test', :password_confirmation => 'test', :email => 'sample-user@test.com', :environment => e1).person | 90 | p1 = create_user('sample-user', :password => 'test', :password_confirmation => 'test', :email => 'sample-user@test.com', :environment => e1).person |
| 128 | p2 = create_user('sample-user', :password => 'test', :password_confirmation => 'test', :email => 'sample-user@test.com', :environment => e2).person | 91 | p2 = create_user('sample-user', :password => 'test', :password_confirmation => 'test', :email => 'sample-user@test.com', :environment => e2).person |
| 129 | 92 | ||
| 130 | - c1 = ChangePassword.create!(:field => 'login', :value => 'sample-user', :environment_id => e1.id) | ||
| 131 | - c2 = ChangePassword.create!(:field => 'login', :value => 'sample-user', :environment_id => e2.id) | 93 | + c1 = ChangePassword.create!(:value => 'sample-user', :environment_id => e1.id) |
| 94 | + c2 = ChangePassword.create!(:value => 'sample-user', :environment_id => e2.id) | ||
| 132 | 95 | ||
| 133 | assert_equal c1.requestor, p1 | 96 | assert_equal c1.requestor, p1 |
| 134 | assert_equal c2.requestor, p2 | 97 | assert_equal c2.requestor, p2 |
| @@ -137,7 +100,7 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -137,7 +100,7 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 137 | should 'have target notification description' do | 100 | should 'have target notification description' do |
| 138 | person = create_user('testuser').person | 101 | person = create_user('testuser').person |
| 139 | 102 | ||
| 140 | - change = ChangePassword.create(:field => 'login', :value => 'testuser', :environment_id => Environment.default.id) | 103 | + change = ChangePassword.create(:value => 'testuser', :environment_id => Environment.default.id) |
| 141 | 104 | ||
| 142 | assert_match(/#{change.requestor.name} wants to change its password/, change.target_notification_description) | 105 | assert_match(/#{change.requestor.name} wants to change its password/, change.target_notification_description) |
| 143 | end | 106 | end |
| @@ -145,7 +108,7 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -145,7 +108,7 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 145 | should 'deliver task created message' do | 108 | should 'deliver task created message' do |
| 146 | person = create_user('testuser').person | 109 | person = create_user('testuser').person |
| 147 | 110 | ||
| 148 | - task = ChangePassword.create(:field => 'login', :value => 'testuser', :environment_id => Environment.default.id) | 111 | + task = ChangePassword.create(:value => 'testuser', :environment_id => Environment.default.id) |
| 149 | 112 | ||
| 150 | email = TaskMailer.deliver_task_created(task) | 113 | email = TaskMailer.deliver_task_created(task) |
| 151 | assert_match(/#{task.requestor.name} wants to change its password/, email.subject) | 114 | assert_match(/#{task.requestor.name} wants to change its password/, email.subject) |
| @@ -154,12 +117,13 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -154,12 +117,13 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
| 154 | should 'allow extra fields provided by plugins' do | 117 | should 'allow extra fields provided by plugins' do |
| 155 | class Plugin1 < Noosfero::Plugin | 118 | class Plugin1 < Noosfero::Plugin |
| 156 | def change_password_fields | 119 | def change_password_fields |
| 157 | - {:f1 => 'F1'} | 120 | + {:field => 'f1', :name => 'F1', :model => 'person'} |
| 158 | end | 121 | end |
| 159 | end | 122 | end |
| 160 | class Plugin2 < Noosfero::Plugin | 123 | class Plugin2 < Noosfero::Plugin |
| 161 | def change_password_fields | 124 | def change_password_fields |
| 162 | - {:f2 => 'F2', :f3 => 'F3'} | 125 | + [{:field => 'f2', :name => 'F2', :model => 'person'}, |
| 126 | + {:field => 'f3', :name => 'F3', :model => 'person'}] | ||
| 163 | end | 127 | end |
| 164 | end | 128 | end |
| 165 | 129 |