Commit 1b99bd87e63329a913a89620b1f7981c4182b679
1 parent
c31513a2
Exists in
master
and in
29 other branches
stoa: recover password through usp_id too
Also provides hotspot for plugins to add new fields for password recovery (ActionItem2827)
Showing
7 changed files
with
69 additions
and
16 deletions
Show diff stats
app/controllers/public/account_controller.rb
... | ... | @@ -150,6 +150,7 @@ class AccountController < ApplicationController |
150 | 150 | session[:notice] = _("This environment doesn't allow password recovery.") |
151 | 151 | end |
152 | 152 | @change_password = ChangePassword.new(params[:change_password]) |
153 | + @change_password.environment_id = environment.id | |
153 | 154 | |
154 | 155 | if request.post? |
155 | 156 | begin | ... | ... |
app/models/change_password.rb
... | ... | @@ -3,6 +3,8 @@ class ChangePassword < Task |
3 | 3 | settings_items :field, :value |
4 | 4 | attr_accessor :password, :password_confirmation, :environment_id |
5 | 5 | |
6 | + include Noosfero::Plugin::HotSpot | |
7 | + | |
6 | 8 | def self.human_attribute_name(attrib) |
7 | 9 | case attrib.to_sym |
8 | 10 | when :field |
... | ... | @@ -18,18 +20,36 @@ class ChangePassword < Task |
18 | 20 | end |
19 | 21 | end |
20 | 22 | |
21 | - def self.fields_choice | |
23 | + def plugins_fields | |
24 | + plugins.dispatch(:change_password_fields).inject({}) { |result, fields| result.merge!(fields)} | |
25 | + end | |
26 | + | |
27 | + def environment | |
28 | + (requestor.environment if requestor) || Environment.find_by_id(environment_id) | |
29 | + end | |
30 | + | |
31 | + def fields | |
32 | + %w[login email] + plugins_fields.map { |field, name| field.to_s } | |
33 | + end | |
34 | + | |
35 | + def fields_choice | |
22 | 36 | [ |
23 | 37 | [_('Username'), 'login'], |
24 | 38 | [_('Email'), 'email'], |
25 | - ] | |
39 | + ] + plugins_fields.map { |field, name| [name, field] } | |
26 | 40 | end |
27 | 41 | |
28 | 42 | ################################################### |
29 | 43 | # validations for creating a ChangePassword task |
30 | 44 | |
31 | 45 | validates_presence_of :field, :value, :environment_id, :on => :create, :message => _('must be filled in') |
32 | - validates_inclusion_of :field, :in => %w[login email] | |
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 | |
33 | 53 | |
34 | 54 | validates_each :value, :on => :create do |data,attr,value| |
35 | 55 | unless data.field.blank? || data.value.blank? |
... | ... | @@ -40,7 +60,7 @@ class ChangePassword < Task |
40 | 60 | end |
41 | 61 | end |
42 | 62 | |
43 | - before_validation_on_create do |change_password| | |
63 | + before_validation do |change_password| | |
44 | 64 | user = change_password.user_find |
45 | 65 | change_password.requestor = user.person if user |
46 | 66 | end |
... | ... | @@ -56,9 +76,10 @@ class ChangePassword < Task |
56 | 76 | def user_find |
57 | 77 | begin |
58 | 78 | method = "find_by_#{field}_and_environment_id" |
59 | - user = User.send(method, value, 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) | |
60 | 82 | rescue |
61 | - nil | |
62 | 83 | end |
63 | 84 | user |
64 | 85 | end |
... | ... | @@ -105,8 +126,4 @@ class ChangePassword < Task |
105 | 126 | end |
106 | 127 | end |
107 | 128 | |
108 | - def environment | |
109 | - self.requestor.environment | |
110 | - end | |
111 | - | |
112 | 129 | end | ... | ... |
app/views/account/forgot_password.rhtml
... | ... | @@ -4,12 +4,9 @@ |
4 | 4 | |
5 | 5 | <% labelled_form_for :change_password, @change_password, :url => { :action => 'forgot_password' } do |f| %> |
6 | 6 | |
7 | - <%= labelled_form_field(_('Field'), f.select(:field, ChangePassword.fields_choice)) %> | |
8 | - | |
7 | + <%= labelled_form_field(_('Field'), f.select(:field, @change_password.fields_choice)) %> | |
9 | 8 | <%= f.text_field :value %> |
10 | 9 | |
11 | - <%= f.hidden_field :environment_id, :value => environment.id %> | |
12 | - | |
13 | 10 | <div> |
14 | 11 | <% button_bar do %> |
15 | 12 | <%= submit_button('send', _('Send instructions')) %> | ... | ... |
lib/noosfero/plugin.rb
... | ... | @@ -460,6 +460,12 @@ class Noosfero::Plugin |
460 | 460 | def find_by_contents(asset, scope, query, paginate_options={}, options={}) |
461 | 461 | end |
462 | 462 | |
463 | + # -> Adds aditional fields for change_password | |
464 | + # returns = {:field1 => 'field1 name', :field2 => 'field2 name' ... } | |
465 | + def change_password_fields | |
466 | + nil | |
467 | + end | |
468 | + | |
463 | 469 | # -> Adds additional blocks to profiles and environments. |
464 | 470 | # Your plugin must implements a class method called 'extra_blocks' |
465 | 471 | # that returns a hash with the following syntax. | ... | ... |
plugins/stoa/lib/stoa_plugin.rb
plugins/stoa/test/functional/account_controller_test.rb
... | ... | @@ -66,4 +66,8 @@ class AccountControllerTest < ActionController::TestCase |
66 | 66 | assert_equal @user.login, assigns(:current_user).login |
67 | 67 | end |
68 | 68 | |
69 | + should 'be able to recover password with usp_id' do | |
70 | + post :forgot_password, :change_password => { :field => 'usp_id', :value => '87654321' } | |
71 | + assert_template 'password_recovery_sent' | |
72 | + end | |
69 | 73 | end | ... | ... |
test/unit/change_password_test.rb
... | ... | @@ -5,12 +5,12 @@ class ChangePasswordTest < ActiveSupport::TestCase |
5 | 5 | fixtures :environments |
6 | 6 | |
7 | 7 | should 'validate' do |
8 | - data = ChangePassword.new | |
8 | + data = ChangePassword.new(:environment_id => Environment.default) | |
9 | 9 | assert !data.valid? |
10 | 10 | end |
11 | 11 | |
12 | 12 | should 'validate field is login or email' do |
13 | - data = ChangePassword.new | |
13 | + data = ChangePassword.new(:environment_id => Environment.default) | |
14 | 14 | data.field = 'anything' |
15 | 15 | data.valid? |
16 | 16 | assert data.errors.invalid?(:field) |
... | ... | @@ -151,4 +151,28 @@ class ChangePasswordTest < ActiveSupport::TestCase |
151 | 151 | assert_match(/#{task.requestor.name} wants to change its password/, email.subject) |
152 | 152 | end |
153 | 153 | |
154 | + should 'allow extra fields provided by plugins' do | |
155 | + class Plugin1 < Noosfero::Plugin | |
156 | + def change_password_fields | |
157 | + {:f1 => 'F1'} | |
158 | + end | |
159 | + end | |
160 | + class Plugin2 < Noosfero::Plugin | |
161 | + def change_password_fields | |
162 | + {:f2 => 'F2', :f3 => 'F3'} | |
163 | + end | |
164 | + end | |
165 | + | |
166 | + environment = Environment.default | |
167 | + environment.enable_plugin(Plugin1) | |
168 | + environment.enable_plugin(Plugin2) | |
169 | + person = create_user('testuser').person | |
170 | + | |
171 | + change_password = ChangePassword.new(:environment_id => environment.id) | |
172 | + | |
173 | + assert_includes change_password.fields, 'f1' | |
174 | + assert_includes change_password.fields, 'f2' | |
175 | + assert_includes change_password.fields, 'f3' | |
176 | + end | |
177 | + | |
154 | 178 | end | ... | ... |