I want to create a model validation that ensures that the two passwords entered on the password creation page are equivalent. Sure I could put this into my controller but that wouldn't be as clean. So I created two attributes in my model for the hashed password entries...
password_hash and password1_hash...
then I created a custom validation called validates_equality_of that takes three arguments - the two attributes to compare and a descriptor of what those attributes are for the error code.
Now I think I'm a genius...only problem is when the validator executes I get a run time error stating that my 'errors' variable is undefined...this should not happen. Can someone look at this snippet of code and tell me what I've done wrong?
require 'digest/sha2' require 'rubygems' require 'breakpoint' require 'logger'
module ActiveRecord module Validations module ClassMethods def validates_equality_of(attr1, attr2, description) $LOG.debug( "In validates_equality_of") if $LOG != nil raise "description must be a string" if !description.is_a?( String) if ( attr1 != attr2) $LOG.debug( "attributes not the same") if $LOG != nil errors.add( attr2, "Both " + description + " must be the same") else $LOG.debug( "Attributes the same") if $LOG != nil end end end end end
class User < ActiveRecord::Base validates_uniqueness_of :username validates_equality_of :password_hash, :password1_hash, "passwords"
def self.authenticate( username, password) user = User.find( :first, :conditions => ['username = ?', username]) if user.blank? || Digest::SHA256.hexdigest(password + user.password_salt) != user.password_hash raise "Username or Password invalid" end user end
def password=(pass) $LOG.debug( "in password=") if !self.password_salt salt = [Array.new(6){rand(256).chr}.join].pack('m').chomp self.password_salt, self.password_hash = salt, Digest::SHA256.hexdigest(pass + salt) else self.password_hash = Digest::SHA256.hexdigest(pass + self.password_salt) end end
def password1=(pass) $LOG.debug( "in password1=") if !self.password_salt salt = [Array.new(6){rand(256).chr}.join].pack('m').chomp self.password_salt, self.password1_hash = salt, Digest::SHA256.hexdigest(pass + salt) else self.password1_hash = Digest::SHA256.hexdigest(pass + self.password_salt) end end end