Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 144 lines (116 sloc) 3.387 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
require 'digest/sha1'

module Clearance
  module User

    def self.included(model)
      model.extend(ClassMethods)

      model.send(:include, InstanceMethods)
      model.send(:include, AttrAccessible)
      model.send(:include, AttrAccessor)
      model.send(:include, Validations)
      model.send(:include, Callbacks)
    end

    module AttrAccessible
      def self.included(model)
        model.class_eval do
          attr_accessible :email, :password, :password_confirmation
        end
      end
    end

    module AttrAccessor
      def self.included(model)
        model.class_eval do
          attr_accessor :password, :password_confirmation
        end
      end
    end

    module Validations
      def self.included(model)
        model.class_eval do
          validates_presence_of :email
          validates_uniqueness_of :email, :case_sensitive => false
          validates_format_of :email, :with => %r{.+@.+\..+}

          validates_presence_of :password, :if => :password_required?
          validates_confirmation_of :password, :if => :password_required?
        end
      end
    end

    module Callbacks
      def self.included(model)
        model.class_eval do
          before_save :initialize_salt, :encrypt_password, :initialize_token
        end
      end
    end

    module InstanceMethods
      def authenticated?(password)
        encrypted_password == encrypt(password)
      end

      def encrypt(string)
        generate_hash("--#{salt}--#{string}--")
      end

      def remember?
        token_expires_at && Time.now.utc < token_expires_at
      end

      def remember_me!
        remember_me_until! 2.weeks.from_now.utc
      end

      def forget_me!
        clear_token
        save(false)
      end

      def confirm_email!
        self.email_confirmed = true
        self.token = nil
        save(false)
      end

      def forgot_password!
        generate_token
        save(false)
      end

      def update_password(new_password, new_password_confirmation)
        self.password = new_password
        self.password_confirmation = new_password_confirmation
        clear_token if valid?
        save
      end

      protected

      def generate_hash(string)
        Digest::SHA1.hexdigest(string)
      end

      def initialize_salt
        if new_record?
          self.salt = generate_hash("--#{Time.now.utc.to_s}--#{password}--")
        end
      end

      def encrypt_password
        return if password.blank?
        self.encrypted_password = encrypt(password)
      end

      def generate_token
        self.token = encrypt("--#{Time.now.utc.to_s}--#{password}--")
        self.token_expires_at = nil
      end

      def clear_token
        self.token = nil
        self.token_expires_at = nil
      end

      def initialize_token
        generate_token if new_record?
      end

      def password_required?
        encrypted_password.blank? || !password.blank?
      end

      def remember_me_until!(time)
        self.token_expires_at = time
        self.token = encrypt("--#{token_expires_at}--#{password}--")
        save(false)
      end
    end

    module ClassMethods
      def authenticate(email, password)
        return nil unless user = find_by_email(email)
        return user if user.authenticated?(password)
      end
    end

  end
end
Something went wrong with that request. Please try again.