I started having problems with admins "Signing in" on some of my apps. I have no idea why. I started a new app from scratch to try and see why this might be happening. Even in the new app it happened. The only app of mine which allows admins to sign in is the oldest app I have, and I cross examined the controllers, helpers, models and even the views, just to check the differences between the one app that allows admins to sign in and the others that don't. There are no differences.
Anyone got any ideas why?
I create a user - works perfectly. I can sign in and out as many times as I please. I toggle the user admin, and then I can not longer sign in anymore. It just redirects to the sign in page, which means that the session failed. I think it is a problem with password encryption - but honestly don't have a clue.
class ApplicationController < ActionController::Base
include SessionsHelper
protect_from_forgery
end
class SessionsController < ApplicationController
def new
@title = "Sign in"
end
def create
user = User.authenticate(params[:session][:email],
params[:session][:password])
if user.nil?
flash.now[:error] = "Invalid email/password combination."
@title = "Sign in"
render 'new'
else
sign_in user
redirect_back_or user
end
end
def destroy
sign_out
redirect_to root_path
end
end
class UsersController < ApplicationController
before_filter :authenticate, :only => [:index, :edit, :update, :destroy]
before_filter :correct_user, :only => [:edit, :update]
before_filter :admin_user, :only => [:index, :destroy]
def index
@title = "All users"
@users = User.paginate(:page => params[:page])
end
def show
@user = User.find(params[:id])
@title = @user.name
end
def new
@user = User.new
@title = "Sign up"
end
def create
@user = User.new(params[:user])
if @user.save
sign_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
@title = "Sign up"
render 'new'
end
end
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
flash[:success] = "Profile updated."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
def edit
@title = "Edit user"
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to users_path
end
private
def correct_user
@user = User.find(params[:id])
redirect_to(root_path) unless current_user?(@user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
end
module SessionsHelper
def sign_in(user)
开发者_开发知识库 cookies.permanent.signed[:remember_token] = [user.id, user.salt]
self.current_user = user
end
def current_user=(user)
@current_user = user
end
def current_user
@current_user ||= user_from_remember_token
end
def signed_in?
!current_user.nil?
end
def sign_out
cookies.delete(:remember_token)
self.current_user = nil
end
def current_user?(user)
user == current_user
end
def authenticate
deny_access unless signed_in?
end
def deny_access
store_location
redirect_to signin_path, :notice => "Please sign in to access this page."
end
def redirect_back_or(default)
redirect_to(session[:return_to] || default)
clear_return_to
end
private
def user_from_remember_token
User.authenticate_with_salt(*remember_token)
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
def store_location
session[:return_to] = request.fullpath
end
def clear_return_to
session[:return_to] = nil
end
end
module UsersHelper
def gravatar_for(user, options = { :size => 50 })
gravatar_image_tag(user.email.downcase, :alt => user.name,
:class => 'gravatar',
:gravatar => options)
end
end
require 'digest'
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :email, :password, :password_confirmation
has_many :investments, :dependent => :destroy
email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :email, :presence => true,
:format => { :with => email_regex },
:uniqueness => { :case_sensitive => false }
validates :password, :presence => true,
:confirmation => true,
:length => { :within => 6..40 }
before_save :encrypt_password
def has_password?(submitted_password)
encrypted_password == encrypt(submitted_password)
end
def self.authenticate(email, submitted_password)
user = find_by_email(email)
return nil if user.nil?
return user if user.has_password?(submitted_password)
end
def self.authenticate_with_salt(id, cookie_salt)
user = find_by_id(id)
(user && user.salt == cookie_salt) ? user : nil
end
def feed
# This is preliminary. See Chapter 12 for the full implementation.
Investment.where("user_id = ?", id)
end
private
def encrypt_password
self.salt = make_salt if new_record?
self.encrypted_password = encrypt(password)
end
def encrypt(string)
secure_hash("#{salt}--#{string}")
end
def make_salt
secure_hash("#{Time.now.utc}--#{password}")
end
def secure_hash(string)
Digest::SHA2.hexdigest(string)
end
end
#routes
resources :users
resources :sessions, :only => [:new, :create, :destroy]
match '/signup', :to => 'users#new'
match '/signin', :to => 'sessions#new'
match '/signout', :to => 'sessions#destroy'
match '/contact', :to => 'pages#contact'
match '/about', :to => 'pages#about'
match '/help', :to => 'pages#help'
root :to => "pages#home"
#Gems
Using rake (0.9.2)
Using abstract (1.0.0)
Using activesupport (3.0.9)
Using builder (2.1.2)
Using i18n (0.5.0)
Using activemodel (3.0.9)
Using erubis (2.6.6)
Using rack (1.2.3)
Using rack-mount (0.6.14)
Using rack-test (0.5.7)
Using tzinfo (0.3.29)
Using actionpack (3.0.9)
Using mime-types (1.16)
Using polyglot (0.3.1)
Using treetop (1.4.9)
Using mail (2.2.19)
Using actionmailer (3.0.9)
Using arel (2.0.10)
Using activerecord (3.0.9)
Using activeresource (3.0.9)
Using bundler (1.0.10)
Using rdoc (3.8)
Using thor (0.14.6)
Using railties (3.0.9)
Using rails (3.0.9)
Using sqlite3 (1.3.3)
As you can see, exactly the same as the rails tutorial by Michael Hartl. And my other app that actually works.
Thanks
This answer was simple. As soon as I asked the question, I relaxed and waited for help from stackoverflow, right then I had an idea.
When you 'toggle' a user 'admin', you should do the following:
$ rails console
>> user = User.first
>> user.admin?
=> false
>> user.password = "foobar"
>> user.toggle!(:admin)
=> true
>> user.admin?
=> true
Taken from the Rails tutorial by Michael Hartl
Its important to put in the password. I had forgotten to do this because I was trying to learn the process without looking at the tutorial every time, and forgot the password part. So just as I supected, I could log into my admin accounts without a password, then go to edit user and change the password back to what it was.
精彩评论