Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## payment_card.rb
- class PaymentCard < ActiveRecord::Base
- class CIMPaymentProfileCreationError < StandardError; end
- include SharedGateway
- include ActiveMerchant::RequiresParameters
- belongs_to :user
- attr_accessor :full_number, :cvs
- VALID_MONTHS = (1..12).collect{|m| [m, m]}
- VALID_YEARS = (Time.now.year..Time.now.year + 10).collect{|y| [y, y]}
- VALID_CARD_TYPES = %w(visa mastercard discover).collect{|c| [c.capitalize, c]}
- validates_presence_of :first_name, :last_name
- validates_presence_of :full_number, :on => :create
- after_save :deactivate_other_payment_cards
- after_create :create_payment_profile_id
- after_create :process_card
- def full_number_before_typecast
- self.full_number
- end
- def self.create_or_activate_payment_card(user, params)
- # If we have an existing card, activate it and return it
- logger.debug {"message here #{:number}"}
- existing_card = PaymentCard.find(:first, :conditions => {:user_id => user.id,
- :month => params[:month], :year => params[:year], :number => params[:full_number].to_s.last(4)
- })
- existing_card.activate! and return existing_card if existing_card
- else
- # Otherwise, create one and generate the CIM payment profile id for it
- new_card = user.payment_cards.build(params)
- begin
- new_card.save
- rescue CIMPaymentProfileCreationError => e
- Rails.logger.error e
- new_card.errors.add_to_base("Credit card is invalid.")
- end
- new_card
- end
- def activate!
- self.is_active = true
- self.save
- end
- private
- def deactivate_other_payment_cards
- if self.is_active == true
- self.user.payment_cards.reject{|c| c.id == self.id}.each do |card|
- card.update_attribute(:is_active, false)
- end
- end
- end
- def create_payment_profile_id
- # More magical dwarven knowledge here
- card = CreditCard.new(:year => self.year, :month => self.month, :number => self.full_number)
- profile = {
- :customer_type => 'individual', # Optional
- :payment => { :credit_card => card }
- }
- response = gateway.create_customer_payment_profile(:customer_profile_id => self.user.customer_profile_id, :payment_profile => profile)
- self.customer_payment_profile_id = response.params['customer_payment_profile_id']
- raise CIMPaymentProfileCreationError, "could not create a customer payment profile id for user #{self.inspect}" unless self.customer_payment_profile_id
- end
- def process_card
- if payment_card.valid?
- # Create a gateway object to the TrustCommerce service
- gateway = ActiveMerchant::Billing::AuthorizeNetCimGateway.new(
- :login => 'TestMerchant',
- :password => 'password'
- )
- # Authorize for $10 dollars (1000 cents)
- response = gateway.authorize(:amount, credit_card)
- if response.success?
- # Capture the money
- gateway.capture(:amount, response.authorization)
- else
- raise StandardError, response.message
- end
- end
- end
- end
- #
- # def set_new_payment_information(info)
- # requires!(info, :expiration_month, :expiration_year, :card_number)
- #
- # # if we have a matching card already, activate it and return true
- # existing_card = self.payment_cards.find(:first,
- # :conditions => {
- # :shadowed_card_number => shadow(info[:card_number]),
- # :expiration_year => info[:expiration_year].to_i,
- # :expiration_month => info[:expiration_month].to_i
- # })
- #
- # existing_card.activate! and return true if existing_card
- #
- # # else update remote payment_profile
- # card = CreditCard.new(:year => info[:expiration_year], :month => info[:expiration_month], :number => info[:card_number])
- # profile = {
- # :customer_type => 'individual', # Optional
- # :payment => {
- # :credit_card => card
- # }
- # }
- # response = gateway.create_customer_payment_profile(:customer_profile_id => self.customer_profile_id, :payment_profile => profile)
- # require 'pp'
- # pp response
- # new_customer_payment_profile_id = response.params['customer_payment_profile_id']
- # # return false if we couldn't create the remote payment profile
- #
- # Merb.logger.error("Could not create remote profile for billing_profile: #{self.inspect}") and return false unless new_customer_payment_profile_id
- #
- # shadowed_card = shadow(info[:card_number])
- # payment_card = self.payment_cards.build(:customer_payment_profile_id => new_customer_payment_profile_id,
- # :shadowed_card_number => shadowed_card,
- # :expiration_month => info[:expiration_month],
- # :expiration_year => info[:expiration_year])
- # # return false if we had an issue saving this payment card
- # unless payment_card.save
- # self.errors.add_to_base("Could not save the new payment card.")
- # return false
- # end
- #
- #
- # # create new payment_card, set payment_profile_id, set to active - this is now handled by acts as state machine
- # # loop through payment_cards, setting inactive - this is now handled by acts as state machine
- # payment_card.activate!
- # true
- # end
- ## user.rb
- require 'digest/sha1'
- require 'Teroformed'
- class User < ActiveRecord::Base
- RANDOM_LIMIT = 1000
- include SharedGateway
- class CIMProfileCreationError < StandardError; end
- # Virtual attribute for the unencrypted password
- attr_accessor :password
- validate :generate_unique_cim_key
- validates_presence_of :login
- validates_presence_of :email
- validates_presence_of :password, :if => :password_required?
- validates_presence_of :password_confirmation, :if => :password_required?
- validates_length_of :password, :within => 4..40, :if => :password_required?
- validates_confirmation_of :password, :if => :password_required?
- validates_presence_of :first_name, :last_name
- validates_length_of :login, :within => 3..40
- validates_length_of :email, :within => 3..100
- validates_uniqueness_of :login, :case_sensitive => false
- validates_format_of :email, :with => /(^([^@\s]+)@((?:[-_a-z0-9]+\.)+[a-z]{2,})$)|(^$)/i
- has_many :permissions
- has_many :roles, :through => :permissions
- belongs_to :sponsor,
- :class_name => "User",
- :foreign_key => "sponsor_id"
- has_many :sponsored,
- :class_name => "User",
- :foreign_key => "sponsor_id",
- :order => "created_at"
- has_many :subscriptions
- has_many :payment_cards
- before_save :encrypt_password
- before_create :make_activation_code
- before_create :set_sponsor_code
- after_create :create_tero_user
- after_update :update_tero_user
- after_create :persist_to_authorize_net
- # prevents a user from submitting a crafted form that bypasses activation
- # anything else you want your user to change should be added here.
- attr_accessible :login, :email, :password, :password_confirmation, :first_name, :last_name, :sponsor_code, :code_used, :company_name, :title, :website_address, :address_one, :address_two, :city, :state, :zip_code, :tel_num, :alt_tel_num, :fax_num, :ip_address
- class ActivationCodeNotFound < StandardError; end
- class AlreadyActivated < StandardError
- attr_reader :user, :message;
- def initialize(user, message=nil)
- @message, @user = message, user
- end
- end
- # Finds the user with the corresponding activation code, activates their account and returns the user.
- #
- # Raises:
- # +User::ActivationCodeNotFound+ if there is no user with the corresponding activation code
- # +User::AlreadyActivated+ if the user with the corresponding activation code has already activated their account
- def self.find_and_activate!(activation_code)
- raise ArgumentError if activation_code.nil?
- user = find_by_activation_code(activation_code)
- raise ActivationCodeNotFound if !user
- raise AlreadyActivated.new(user) if user.active?
- user.send(:activate!)
- user
- end
- def active?
- # the presence of an activation date means they have activated
- !activated_at.nil?
- end
- # Returns true if the user has just been activated.
- def pending?
- @activated
- end
- # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
- # Updated 2/20/08
- def self.authenticate(login, password)
- u = find :first, :conditions => ['login = ?', login] # need to get the salt
- u && u.authenticated?(password) ? u : nil
- end
- # Encrypts some data with the salt.
- def self.encrypt(password, salt)
- Digest::SHA1.hexdigest("–#{salt}–#{password}–")
- end
- # Encrypts the password with the user salt
- def encrypt(password)
- self.class.encrypt(password, salt)
- end
- def authenticated?(password)
- crypted_password == encrypt(password)
- end
- def remember_token?
- remember_token_expires_at && Time.now.utc < remember_token_expires_at
- end
- # These create and unset the fields required for remembering users between browser closes
- def remember_me
- remember_me_for 2.weeks
- end
- def remember_me_for(time)
- remember_me_until time.from_now.utc
- end
- def remember_me_until(time)
- self.remember_token_expires_at = time
- self.remember_token = encrypt("#{email}–#{remember_token_expires_at}")
- save(false)
- end
- def forget_me
- self.remember_token_expires_at = nil
- self.remember_token = nil
- save(false)
- end
- def forgot_password
- @forgotten_password = true
- self.make_password_reset_code
- end
- def reset_password
- # First update the password_reset_code before setting the
- # reset_password flag to avoid duplicate email notifications.
- update_attribute(:password_reset_code, nil)
- @reset_password = true
- end
- # used in user_observer
- def recently_forgot_password?
- @forgotten_password
- end
- def recently_reset_password?
- @reset_password
- end
- def self.find_for_forget(email)
- find :first, :conditions => ['email = ? and activated_at IS NOT NULL', email]
- end
- def has_role?(rolename)
- self.roles.find_by_rolename(rolename) ? true : false
- end
- def code_used=(code)
- self.sponsor = User.find_by_sponsor_code(code)
- write_attribute(:code_used, code)
- end
- def track_referrals
- @track_referrals ||= User.find_all_by_code_used(sponsor_code)
- end
- def second_level_referrals
- @second_level ||= self.track_referrals.map {|refs| refs.track_referrals}.flatten!
- end
- def full_name
- "#{last_name}, #{first_name}"
- end
- def create_or_set_payment_card(params)
- PaymentCard.create_or_activate_payment_card(self, params)
- end
- protected
- # before filter
- def encrypt_password
- return if password.blank?
- self.salt = Digest::SHA1.hexdigest("–#{Time.now.to_s}–#{login}–") if new_record?
- self.crypted_password = encrypt(password)
- end
- def password_required?
- crypted_password.blank? || !password.blank?
- end
- def make_activation_code
- self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
- end
- def make_password_reset_code
- self.password_reset_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
- end
- private
- def create_tero_user
- tero = Teroformed.new
- logger.info tero.add_user(:username => self.login, :new_password => self.password, :firstname => self.first_name, :lastname => self.last_name, :keyword_num => '1')
- end
- def update_tero_user
- tero = Teroformed.new
- logger.info tero.update_user(:username => self.login, :new_password => self.password, :firstname => self.first_name, :lastname => self.last_name, :keyword_num => '1')
- end
- def persist_to_authorize_net
- response = gateway.create_customer_profile({:profile =>{:merchant_customer_id => self.cim_key}})
- if response.authorization
- self.customer_profile_id = response.authorization
- self.save
- else
- Rails.logger.error response.message
- raise CIMProfileCreationError, "could not create CIM profile"
- end
- end
- def generate_unique_cim_key
- return true if self.cim_key?
- prefix = AppConfig.cim_prefix
- while true do
- digest = Digest::SHA1.hexdigest("--#{Time.now}--#{rand(RANDOM_LIMIT)}--").last(5)
- time = Time.now.to_i
- potential_key = "#{prefix}_#{digest}_#{time}"
- potential_dup = User.find_by_cim_key(potential_key)
- if potential_dup
- return true if potential_dup.id == self.id
- else
- self.cim_key = potential_key
- break
- end
- end
- true
- end
- def activate!
- @activated = true
- self.update_attribute(:activated_at, Time.now.utc)
- end
- def set_sponsor_code
- loop do
- self.sponsor_code = generate_sponsor_code
- break if sponsor_code_is_unique?
- end
- end
- def generate_sponsor_code
- rand(99999000) + 1000
- end
- def sponsor_code_is_unique?
- !User.find_by_sponsor_code(sponsor_code)
- end
- end
Add Comment
Please, Sign In to add comment