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