Commit 90a1b0b2ea88df9903f56def63bf7498d3db93d9
1 parent
25df24bd
Exists in
master
and in
29 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 | 1 | class ChangePassword < Task |
2 | 2 | |
3 | - settings_items :field, :value | |
3 | + settings_items :value | |
4 | 4 | attr_accessor :password, :password_confirmation, :environment_id |
5 | 5 | |
6 | 6 | include Noosfero::Plugin::HotSpot |
7 | 7 | |
8 | 8 | def self.human_attribute_name(attrib) |
9 | 9 | case attrib.to_sym |
10 | - when :field | |
11 | - _('Field') | |
12 | 10 | when :value |
13 | 11 | _('Value') |
14 | 12 | when :password |
... | ... | @@ -20,49 +18,54 @@ class ChangePassword < Task |
20 | 18 | end |
21 | 19 | end |
22 | 20 | |
23 | - def plugins_fields | |
24 | - plugins.dispatch(:change_password_fields).inject({}) { |result, fields| result.merge!(fields)} | |
25 | - end | |
26 | - | |
27 | 21 | def environment |
28 | 22 | (requestor.environment if requestor) || Environment.find_by_id(environment_id) |
29 | 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 | 37 | def fields |
32 | - %w[login email] + plugins_fields.map { |field, name| field.to_s } | |
38 | + user_fields + person_fields | |
33 | 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 | 50 | end |
41 | 51 | |
42 | 52 | ################################################### |
43 | 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 | 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 | 62 | end |
60 | 63 | end |
61 | 64 | end |
62 | 65 | |
63 | 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 | 69 | end |
67 | 70 | |
68 | 71 | ################################################### |
... | ... | @@ -73,15 +76,18 @@ class ChangePassword < Task |
73 | 76 | validates_presence_of :password_confirmation, :on => :update, :if => lambda { |change| change.status != Task::Status::CANCELLED } |
74 | 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 | 91 | end |
86 | 92 | |
87 | 93 | def title | ... | ... |
app/views/account/forgot_password.rhtml
... | ... | @@ -4,8 +4,7 @@ |
4 | 4 | |
5 | 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 | 9 | <div> |
11 | 10 | <% button_bar do %> | ... | ... |
lib/noosfero/plugin.rb
... | ... | @@ -461,7 +461,7 @@ class Noosfero::Plugin |
461 | 461 | end |
462 | 462 | |
463 | 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 | 465 | def change_password_fields |
466 | 466 | nil |
467 | 467 | end | ... | ... |
plugins/stoa/lib/stoa_plugin.rb
plugins/stoa/test/functional/account_controller_test.rb
... | ... | @@ -67,7 +67,7 @@ class AccountControllerTest < ActionController::TestCase |
67 | 67 | end |
68 | 68 | |
69 | 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 | 71 | assert_template 'password_recovery_sent' |
72 | 72 | end |
73 | 73 | end | ... | ... |
test/functional/account_controller_test.rb
... | ... | @@ -217,19 +217,19 @@ class AccountControllerTest < ActionController::TestCase |
217 | 217 | |
218 | 218 | should 'respond to forgotten password change request with login' do |
219 | 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 | 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 | 224 | assert_template 'password_recovery_sent' |
225 | 225 | end |
226 | 226 | |
227 | 227 | should 'respond to forgotten password change request with email' do |
228 | 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 | 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 | 233 | assert_template 'password_recovery_sent' |
234 | 234 | end |
235 | 235 | |
... | ... | @@ -276,7 +276,7 @@ class AccountControllerTest < ActionController::TestCase |
276 | 276 | |
277 | 277 | should 'require password confirmation correctly to enter new pasword' do |
278 | 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 | 281 | post :new_password, :code => change.code, :change_password => { :password => 'onepass', :password_confirmation => 'another_pass' } |
282 | 282 | assert_response :success |
... | ... | @@ -862,7 +862,7 @@ class AccountControllerTest < ActionController::TestCase |
862 | 862 | assert_response :redirect |
863 | 863 | |
864 | 864 | #Redirect on post action |
865 | - post :forgot_password, :change_password => { :field => 'login', :value => 'test' } | |
865 | + post :forgot_password, :change_password => { :value => 'test' } | |
866 | 866 | assert_response :redirect |
867 | 867 | end |
868 | 868 | ... | ... |
test/unit/change_password_test.rb
... | ... | @@ -9,39 +9,7 @@ class ChangePasswordTest < ActiveSupport::TestCase |
9 | 9 | assert !data.valid? |
10 | 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 | 13 | User.destroy_all |
46 | 14 | create_user('testuser', :email => 'test@example.com') |
47 | 15 | |
... | ... | @@ -50,12 +18,10 @@ class ChangePasswordTest < ActiveSupport::TestCase |
50 | 18 | assert !data.valid? |
51 | 19 | assert data.errors.invalid?(:value) |
52 | 20 | |
53 | - data.field = 'login' | |
54 | 21 | data.value = 'testuser' |
55 | 22 | data.valid? |
56 | 23 | assert data.valid? |
57 | 24 | |
58 | - data.field = 'email' | |
59 | 25 | data.value = 'test@example.com' |
60 | 26 | assert data.valid? |
61 | 27 | end |
... | ... | @@ -65,7 +31,6 @@ class ChangePasswordTest < ActiveSupport::TestCase |
65 | 31 | |
66 | 32 | change = ChangePassword.new |
67 | 33 | change.environment_id = Environment.default.id |
68 | - change.field = 'login' | |
69 | 34 | change.value = 'testuser' |
70 | 35 | change.save! |
71 | 36 | |
... | ... | @@ -86,7 +51,6 @@ class ChangePasswordTest < ActiveSupport::TestCase |
86 | 51 | |
87 | 52 | change = ChangePassword.new |
88 | 53 | change.environment_id = Environment.default.id |
89 | - change.field = 'login' | |
90 | 54 | change.value = 'testuser' |
91 | 55 | change.save! |
92 | 56 | |
... | ... | @@ -105,7 +69,6 @@ class ChangePasswordTest < ActiveSupport::TestCase |
105 | 69 | |
106 | 70 | change = ChangePassword.new |
107 | 71 | change.environment_id = Environment.default.id |
108 | - change.field = 'login' | |
109 | 72 | change.value = 'testuser' |
110 | 73 | change.save! |
111 | 74 | |
... | ... | @@ -127,8 +90,8 @@ class ChangePasswordTest < ActiveSupport::TestCase |
127 | 90 | p1 = create_user('sample-user', :password => 'test', :password_confirmation => 'test', :email => 'sample-user@test.com', :environment => e1).person |
128 | 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 | 96 | assert_equal c1.requestor, p1 |
134 | 97 | assert_equal c2.requestor, p2 |
... | ... | @@ -137,7 +100,7 @@ class ChangePasswordTest < ActiveSupport::TestCase |
137 | 100 | should 'have target notification description' do |
138 | 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 | 105 | assert_match(/#{change.requestor.name} wants to change its password/, change.target_notification_description) |
143 | 106 | end |
... | ... | @@ -145,7 +108,7 @@ class ChangePasswordTest < ActiveSupport::TestCase |
145 | 108 | should 'deliver task created message' do |
146 | 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 | 113 | email = TaskMailer.deliver_task_created(task) |
151 | 114 | assert_match(/#{task.requestor.name} wants to change its password/, email.subject) |
... | ... | @@ -154,12 +117,13 @@ class ChangePasswordTest < ActiveSupport::TestCase |
154 | 117 | should 'allow extra fields provided by plugins' do |
155 | 118 | class Plugin1 < Noosfero::Plugin |
156 | 119 | def change_password_fields |
157 | - {:f1 => 'F1'} | |
120 | + {:field => 'f1', :name => 'F1', :model => 'person'} | |
158 | 121 | end |
159 | 122 | end |
160 | 123 | class Plugin2 < Noosfero::Plugin |
161 | 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 | 127 | end |
164 | 128 | end |
165 | 129 | ... | ... |