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 | ... | ... |