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,6 +150,7 @@ class AccountController < ApplicationController | ||
150 | session[:notice] = _("This environment doesn't allow password recovery.") | 150 | session[:notice] = _("This environment doesn't allow password recovery.") |
151 | end | 151 | end |
152 | @change_password = ChangePassword.new(params[:change_password]) | 152 | @change_password = ChangePassword.new(params[:change_password]) |
153 | + @change_password.environment_id = environment.id | ||
153 | 154 | ||
154 | if request.post? | 155 | if request.post? |
155 | begin | 156 | begin |
app/models/change_password.rb
@@ -3,6 +3,8 @@ class ChangePassword < Task | @@ -3,6 +3,8 @@ class ChangePassword < Task | ||
3 | settings_items :field, :value | 3 | settings_items :field, :value |
4 | attr_accessor :password, :password_confirmation, :environment_id | 4 | attr_accessor :password, :password_confirmation, :environment_id |
5 | 5 | ||
6 | + include Noosfero::Plugin::HotSpot | ||
7 | + | ||
6 | def self.human_attribute_name(attrib) | 8 | def self.human_attribute_name(attrib) |
7 | case attrib.to_sym | 9 | case attrib.to_sym |
8 | when :field | 10 | when :field |
@@ -18,18 +20,36 @@ class ChangePassword < Task | @@ -18,18 +20,36 @@ class ChangePassword < Task | ||
18 | end | 20 | end |
19 | end | 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 | [_('Username'), 'login'], | 37 | [_('Username'), 'login'], |
24 | [_('Email'), 'email'], | 38 | [_('Email'), 'email'], |
25 | - ] | 39 | + ] + plugins_fields.map { |field, name| [name, field] } |
26 | end | 40 | end |
27 | 41 | ||
28 | ################################################### | 42 | ################################################### |
29 | # validations for creating a ChangePassword task | 43 | # validations for creating a ChangePassword task |
30 | 44 | ||
31 | validates_presence_of :field, :value, :environment_id, :on => :create, :message => _('must be filled in') | 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 | validates_each :value, :on => :create do |data,attr,value| | 54 | validates_each :value, :on => :create do |data,attr,value| |
35 | unless data.field.blank? || data.value.blank? | 55 | unless data.field.blank? || data.value.blank? |
@@ -40,7 +60,7 @@ class ChangePassword < Task | @@ -40,7 +60,7 @@ class ChangePassword < Task | ||
40 | end | 60 | end |
41 | end | 61 | end |
42 | 62 | ||
43 | - before_validation_on_create do |change_password| | 63 | + before_validation do |change_password| |
44 | user = change_password.user_find | 64 | user = change_password.user_find |
45 | change_password.requestor = user.person if user | 65 | change_password.requestor = user.person if user |
46 | end | 66 | end |
@@ -56,9 +76,10 @@ class ChangePassword < Task | @@ -56,9 +76,10 @@ class ChangePassword < Task | ||
56 | def user_find | 76 | def user_find |
57 | begin | 77 | begin |
58 | method = "find_by_#{field}_and_environment_id" | 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 | rescue | 82 | rescue |
61 | - nil | ||
62 | end | 83 | end |
63 | user | 84 | user |
64 | end | 85 | end |
@@ -105,8 +126,4 @@ class ChangePassword < Task | @@ -105,8 +126,4 @@ class ChangePassword < Task | ||
105 | end | 126 | end |
106 | end | 127 | end |
107 | 128 | ||
108 | - def environment | ||
109 | - self.requestor.environment | ||
110 | - end | ||
111 | - | ||
112 | end | 129 | end |
app/views/account/forgot_password.rhtml
@@ -4,12 +4,9 @@ | @@ -4,12 +4,9 @@ | ||
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(_('Field'), f.select(:field, ChangePassword.fields_choice)) %> | ||
8 | - | 7 | + <%= labelled_form_field(_('Field'), f.select(:field, @change_password.fields_choice)) %> |
9 | <%= f.text_field :value %> | 8 | <%= f.text_field :value %> |
10 | 9 | ||
11 | - <%= f.hidden_field :environment_id, :value => environment.id %> | ||
12 | - | ||
13 | <div> | 10 | <div> |
14 | <% button_bar do %> | 11 | <% button_bar do %> |
15 | <%= submit_button('send', _('Send instructions')) %> | 12 | <%= submit_button('send', _('Send instructions')) %> |
lib/noosfero/plugin.rb
@@ -460,6 +460,12 @@ class Noosfero::Plugin | @@ -460,6 +460,12 @@ class Noosfero::Plugin | ||
460 | def find_by_contents(asset, scope, query, paginate_options={}, options={}) | 460 | def find_by_contents(asset, scope, query, paginate_options={}, options={}) |
461 | end | 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 | # -> Adds additional blocks to profiles and environments. | 469 | # -> Adds additional blocks to profiles and environments. |
464 | # Your plugin must implements a class method called 'extra_blocks' | 470 | # Your plugin must implements a class method called 'extra_blocks' |
465 | # that returns a hash with the following syntax. | 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,4 +66,8 @@ class AccountControllerTest < ActionController::TestCase | ||
66 | assert_equal @user.login, assigns(:current_user).login | 66 | assert_equal @user.login, assigns(:current_user).login |
67 | end | 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 | end | 73 | end |
test/unit/change_password_test.rb
@@ -5,12 +5,12 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -5,12 +5,12 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
5 | fixtures :environments | 5 | fixtures :environments |
6 | 6 | ||
7 | should 'validate' do | 7 | should 'validate' do |
8 | - data = ChangePassword.new | 8 | + data = ChangePassword.new(:environment_id => Environment.default) |
9 | assert !data.valid? | 9 | assert !data.valid? |
10 | end | 10 | end |
11 | 11 | ||
12 | should 'validate field is login or email' do | 12 | should 'validate field is login or email' do |
13 | - data = ChangePassword.new | 13 | + data = ChangePassword.new(:environment_id => Environment.default) |
14 | data.field = 'anything' | 14 | data.field = 'anything' |
15 | data.valid? | 15 | data.valid? |
16 | assert data.errors.invalid?(:field) | 16 | assert data.errors.invalid?(:field) |
@@ -151,4 +151,28 @@ class ChangePasswordTest < ActiveSupport::TestCase | @@ -151,4 +151,28 @@ class ChangePasswordTest < ActiveSupport::TestCase | ||
151 | assert_match(/#{task.requestor.name} wants to change its password/, email.subject) | 151 | assert_match(/#{task.requestor.name} wants to change its password/, email.subject) |
152 | end | 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 | end | 178 | end |