Commit 1b99bd87e63329a913a89620b1f7981c4182b679

Authored by Rodrigo Souto
1 parent c31513a2

stoa: recover password through usp_id too

Also provides hotspot for plugins to add new fields for password
recovery

(ActionItem2827)
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
... ... @@ -120,4 +120,8 @@ class StoaPlugin &lt; Noosfero::Plugin
120 120 true
121 121 end
122 122  
  123 + def change_password_fields
  124 + {:usp_id => _('USP Number')}
  125 + end
  126 +
123 127 end
... ...
plugins/stoa/test/functional/account_controller_test.rb
... ... @@ -66,4 +66,8 @@ class AccountControllerTest &lt; 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 &lt; 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 &lt; 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
... ...