SitePoint Sponsor

User Tag List

Results 1 to 4 of 4

Hybrid View

  1. #1
    SitePoint Enthusiast
    Join Date
    Aug 2011
    Posts
    97
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    NameError in AccessController

    I have been learning Rails 3 from a video on Lynda.com, and it has been going well up until lately. What i'm trying to do currently is restrict access to certain pages unless a session is present where the user is authorized (has logged in). This is working correctly because when I try to access the pages that I want restricted, I get redirected to the login form. The problem comes up when I try to login. I put the correct username in, but when I put the password in, any password at all, it doesn't even need to be the correct one, I get an error page I made a user admin account for development purposes, and when I login I get this error:

    NameError in AccessController#attempt_login
    undefined local variable or method `salt' for #<AdminUser:0x41a6a68>

    Application Trace:
    app/models/admin_user.rb:62:in `password_match?'
    app/models/admin_user.rb:52:in `authenticate'
    app/controllers/access_controller.rb:19:in `attempt_login'


    Now, I don't know a ton about debugging as of right now, but based on the trace the method attempt_login in the access controller is the following:

    Code Ruby:
    def attempt_login
        authorized_user = AdminUser.authenticate(params[:username], params[:password])
        if authorized_user
          session[:user_id] = authorized_user.id
          session[:username] = authorized_user.username
          flash[:notice] = "You are now logged in."
          redirect_to(:action => 'menu')
        else
          flash[:notice] = "Invalid username/password combination."
          redirect_to(:action => 'login')
        end
     
      end

    I don't know if there is an error in there that I am missing?

    Anyway thanks in advance, and let me know if you need more of my code to find a solution because I am totally stuck at this point.

    Elementax

  2. #2
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,049
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hi,

    Let's look at your error message:

    Code:
    Application Trace:
    app/models/admin_user.rb:62:in `password_match?'
    app/models/admin_user.rb:52:in `authenticate'
    app/controllers/access_controller.rb:19:in `attempt_login'
    You are correct that the original error is being triggered by the method attempt_login in access_controller.rb.

    However, when we inspect that, we see:

    Code Ruby:
    authorized_user = AdminUser.authenticate(params[:username], params[:password])
    This line is calling the authenticate method on your AdminUser object.

    The authenticate method seems to be defined here: app/models/admin_user.rb:52
    And this method is in turn calling the password_match? method defined here: app/models/admin_user.rb:62

    It is the password_match? method that is triggering the error:

    Code:
    undefined local variable or method `salt' for #<AdminUser:0x41a6a68>
    There could be a number of reasons for this happening.
    Could you post the complete code from admin_user.rb and we'll see if we can get to the bottom of it.

  3. #3
    SitePoint Enthusiast
    Join Date
    Aug 2011
    Posts
    97
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    Hi,

    Let's look at your error message:

    Code:
    Application Trace:
    app/models/admin_user.rb:62:in `password_match?'
    app/models/admin_user.rb:52:in `authenticate'
    app/controllers/access_controller.rb:19:in `attempt_login'
    You are correct that the original error is being triggered by the method attempt_login in access_controller.rb.

    However, when we inspect that, we see:

    Code Ruby:
    authorized_user = AdminUser.authenticate(params[:username], params[:password])
    This line is calling the authenticate method on your AdminUser object.

    The authenticate method seems to be defined here: app/models/admin_user.rb:52
    And this method is in turn calling the password_match? method defined here: app/models/admin_user.rb:62

    It is the password_match? method that is triggering the error:

    Code:
    undefined local variable or method `salt' for #<AdminUser:0x41a6a68>
    There could be a number of reasons for this happening.
    Could you post the complete code from admin_user.rb and we'll see if we can get to the bottom of it.
    Thanks a lot, here is the complete admin_user.rb. I'm assuming I just made a foolish error somewhere, but I still cant seem to find out where:

    Code Ruby:
    require 'digest/sha1'
    class AdminUser < ActiveRecord::Base
     
      has_and_belongs_to_many :pages
      has_many :section_edits
      has_many :sections, :through => :section_edits
     
      attr_accessor :password
     
      EMAIL_REGEX = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
     
      validates :first_name, :presence => true, :length => { :maximum => 25 }
      validates :last_name, :presence => true, :length => { :maximum => 50 }
      validates :username, :length => { :within => 8..25 }, :uniqueness => true
      validates :email, :presence => true, :length => { :maximum => 100 }, 
        :format => EMAIL_REGEX, :confirmation => true
     
     
      validates_length_of :password, :within => 8..25, :on => :create
     
      before_save :create_hashed_password
      after_save :clear_password
     
      scope :named, lambda {|first,last| where(:first_name => first, :last_name => last)}
      scope :sorted, order("admin_users.last_name ASC, admin_users.first_name ASC")
     
      attr_protected :hashed_password, :salt
     
      def name
        "#{first_name} #{last_name}"
      end
     
      def self.authenticate(username="", password="")
        user = AdminUser.find_by_username(username)
        if user && user.password_match?(password)
          return user
        else
          return false
        end
      end
     
      def password_match?(password="")
        hashed_password == AdminUser.hash_with_salt(password, salt)
      end
     
      def self.make_salt(username="")
        Digest::SHA1.hexdigest("Use #{username} with #{Time.now} to make salt")
      end
     
      def self.hash_with_salt(password="", salt="")
        Digest::SHA1.hexdigest("Put #{salt} on the #{password}")
      end
     
      private
     
      def create_hashed_password
        unless password.blank?
          self.salt = AdminUser.make_salt(username) if salt.blank?
          self.hashed_password = AdminUser.hash_with_salt(password, salt)
        end
      end
     
      def clear_password
        self.password = nil
      end
     
    end

  4. #4
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,049
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    It seems the error is being thrown by this line:

    Code Ruby:
    hashed_password == AdminUser.hash_with_salt(password, salt)

    Do you have a "salt" field in your "adminusers" database table?
    If so, are there any pending migrations that you have forgotten to carry out?

    Failing those two things, what is your adminusers table structure?


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •