Topic: authlogic_rpx gem saves User even when it doesn't pass its validations

Hey there,

I've been having an issue with authlogic_rpx. My user model has a validation that should force it to only accept unique emails:

 acts_as_authentic do |c|
    c.merge_validates_uniqueness_of_email_field_options
 end

However, when I am logging in using any provider from RPX (facebook, google, etc), the gem completely ignores that validation and creates new users with duplicated email.

In other words, if I create an account with my-personal-email@gmail.com and afterwards try to login using that google account, the gem will create a new record in the User table, thus I'd have 2 records with the same email.

Is there any way to force it validate the uniqueness of that field?

Thanks!

Re: authlogic_rpx gem saves User even when it doesn't pass its validations

Do you have the authlogic_rpx configuration settings set to merge the two accounts?

I have something like:

# /app/model/user.rb
acts_as_authentic do |c|
  # enable Authlogic_RPX account merging (false by default, if this statement is not present)
  c.account_merge_enabled true
  
  # set Authlogic_RPX account mapping mode
  c.account_mapping_mode :internal
end

Re: authlogic_rpx gem saves User even when it doesn't pass its validations

I've added those lines of code, and it is still creating a duplicated account.

@jmesserer, do you have the 'usename' field in your user table or are you also using 'email' as your username?

Re: authlogic_rpx gem saves User even when it doesn't pass its validations

No, I only have the 'email' field.

  # schema.rb
  create_table "users", :force => true do |t|
    t.string   "email",                              :null => false
    t.string   "persistence_token",                  :null => false
    t.string   "single_access_token",                :null => false
    t.string   "perishable_token",                   :null => false
    t.integer  "login_count",         :default => 0, :null => false
    t.integer  "failed_login_count",  :default => 0, :null => false
    t.datetime "created_at"
    t.datetime "updated_at"
  end

Re: authlogic_rpx gem saves User even when it doesn't pass its validations

This is all I have in my User model related to that gem:

  acts_as_authentic do |c|
    c.merge_validates_length_of_email_field_options :if => Proc.new { |user| false }
    c.merge_validates_format_of_email_field_options :message => 'is not valid'
    c.merge_validates_length_of_password_field_options({:minimum => 6})
    c.merge_validates_length_of_password_confirmation_field_options({:minimum => 6})
    c.merge_validates_uniqueness_of_email_field_options
    c.validates_confirmation_of_password_field_options(:message => 'and Password confirmation do not match', :allow_blank => true)
  end

And this is my UserSession code:

class UserSession < Authlogic::Session::Base
  allow_http_basic_auth false

  rpx_key RPX_API_KEY
  
  private 
  
      def map_rpx_data
        self.attempted_record.first_name = @rpx_data['profile']['name']['givenName']
        self.attempted_record.last_name = @rpx_data['profile']['name']['familyName']
        self.attempted_record.email = @rpx_data['profile']['email']
      end
end

Do you see any significant difference between my code and yours?

Also, do you need to do the merge yourself, or does the gem do it automagically?

Re: authlogic_rpx gem saves User even when it doesn't pass its validations

# <APP>/app/models/user.rb
class User < ActiveRecord::Base  
  acts_as_authentic do |c|
    # enable Authlogic_RPX account merging (false by default, if this statement is not present)
    c.account_merge_enabled true
  
    # set Authlogic_RPX account mapping mode
    c.account_mapping_mode :internal
  end
end
# <APP>/app/models/user_session.rb
class UserSession < Authlogic::Session::Base
  rpx_key RPX_API_KEY
  auto_register true
  rpx_extended_info

private
  def map_rpx_data
    # map core profile data using authlogic indirect column names
    self.attempted_record.send("#{klass.email_field}=", @rpx_data['profile']['email']) if attempted_record.send(klass.email_field).blank?
  
    # map some extended attributes
    if rpx_extended_info?
    end
  end

  def map_rpx_data_each_login
  end
end