Xavier N. wrote:
On Apr 14, 2008, at 21:47 , Carlos R. wrote:
�C�mo est�s manejando las sesiones por usuario y la
autenticaci�n?�Est�s usando alg�n plugin o escribiste tu
mismo el sistema?
Estoy manejando el plugin Restful authentication, y no estoy manejando
ninguna especie de manejo de IP de por medio.
Puedes enviar los filtros relacionados con autenticacion, accion de
login, y metodos propios del usuario relevantes por favor?
Tiene que tratarse de un error de programacion en algun lugar. No del
plugin en principio, sino del codigo propio lo usa.
– fxn
Bueno este es el controlador de las sessiones:
/app/controller/sessions_controller.rb
class SessionsController < ApplicationController
layout ‘login’
skip_before_filter :login_required
filter_parameter_logging :password
render new.rhtml
def new
respond_to do |format|
format.html # index.html.erb
format.js {}
end
end
def create
self.current_user = User.authenticate(params[:login],
params[:password])
if logged_in?
if params[:remember_me] == “1”
self.current_user.remember_me
cookies[:auth_token] = { :value =>
self.current_user.remember_token , :expires =>
self.current_user.remember_token_expires_at }
end
current_user.update_attribute(:total, current_user.total + 1)
redirect_back_or_default(‘/’)
flash[:notice] = “Usted ingreso satisfactoriamente”
else
flash[:notice] = “Usuario o contreseña incorrectos.”
redirect_to(params[:url])
end
end
def destroy
self.current_user.forget_me if logged_in?
cookies.delete :auth_token
reset_session
flash[:notice] = “Usted salio del Banco Temático
satisfactoriamente.”
redirect_back_or_default(‘/’)
end
end
El modelo del usuario.
/app/model/user.rb
require ‘digest/sha1’
class User < ActiveRecord::Base
---------------------------------------
The following code has been generated by role_requirement.
You may wish to modify it to suit your need
has_and_belongs_to_many :roles
has_role? simply needs to return true or false whether a user has a
role or not.
It may be a good idea to have “admin” roles return true always
def has_role?(role_in_question)
@_list ||= self.roles.collect(&:name)
return true if @_list.include?(“admin”)
(@_list.include?(role_in_question.to_s) )
end
---------------------------------------
Virtual attribute for the unencrypted password
attr_accessor :password
Cada usuario activado tiene una profesion registrada
belongs_to :profesion
validates_presence_of :login, :email, :message => “No puede estar
en blanco”
validates_presence_of :password, :if =>
:password_required?, :message => “Debe de introducir su
contraseña”
validates_presence_of :password_confirmation, :if =>
:password_required?, :message => “Debe de ser igual a la
contraseña”
validates_length_of :password, :within => 4…40, :if =>
:password_required?, :message => “Contraseña muy corta (minimo es
cuatro caracteres).”
validates_confirmation_of :password, :if =>
:password_required?
validates_length_of :login, :within => 3…40, :message => “Su
nombre de usuario, debe de ser mas grande (minimo es tres caracteres).”
validates_length_of :email, :within => 3…100, :message =>
“Correo electronico invalido.”
validates_uniqueness_of :login, :email, :case_sensitive => false,
:message => “Ya existe el registro.”
before_save :encrypt_password
before_create :make_activation_code
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,
:nombre, :apellido, :profesion_id
Activates the user in the database.
def activate
@activated = true
self.activated_at = Time.now.utc
self.activation_code = nil
save(false)
end
def active?
# the existence of an activation code means they have not activated
yet
activation_code.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.
def self.authenticate(login, password)
u = find :first, :conditions => [‘login = ? and activated_at IS NOT
NULL’, 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
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
end
/lib/authenticated_system.rb
module AuthenticatedSystem
protected
# Returns true or false if the user is logged in.
# Preloads @current_user with the user model if they’re logged in.
def logged_in?
current_user != :false
end
# Accesses the current user from the session. Set it to :false if
login fails
# so that future calls do not hit the database.
def current_user
@current_user ||= (login_from_session || login_from_basic_auth ||
login_from_cookie || :false)
end
# Store the given user id in the session.
def current_user=(new_user)
session[:user_id] = (new_user.nil? || new_user.is_a?(Symbol)) ?
nil : new_user.id
@current_user = new_user || :false
end
# Check if the user is authorized
#
# Override this method in your controllers if you want to restrict
access
# to only a few actions or if you want to check if the user
# has the correct rights.
#
# Example:
#
# # only allow nonbobs
# def authorized?
# current_user.login != “bob”
# end
def authorized?
logged_in?
end
# Filter method to enforce a login requirement.
#
# To require logins for all actions, use this in your controllers:
#
# before_filter :login_required
#
# To require logins for specific actions, use this in your
controllers:
#
# before_filter :login_required, :only => [ :edit, :update ]
#
# To skip this in a subclassed controller:
#
# skip_before_filter :login_required
#
def login_required
authorized? || access_denied
end
# Redirect as appropriate when an access request fails.
#
# The default action is to redirect to the login screen.
#
# Override this method in your controllers if you want to have
special
# behavior in case the user is not authorized
# to access the requested action. For example, a popup window might
# simply close itself.
def access_denied
respond_to do |format|
format.html do
store_location
flash[:notice] = “Debe de estar registrado para ingresar a
este recurso.
Regístrese es
fácil y rápido.”
redirect_to new_session_path
end
format.any do
request_http_basic_authentication ‘Web Password’
end
end
end
# Store the URI of the current request in the session.
#
# We can return to this location by calling
#redirect_back_or_default.
def store_location
session[:return_to] = request.request_uri
end
# Redirect to the URI stored by the most recent store_location call
or
# to the passed default.
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
# Inclusion hook to make #current_user and #logged_in?
# available as ActionView helper methods.
def self.included(base)
base.send :helper_method, :current_user, :logged_in?
end
# Called from #current_user. First attempt to login by the user id
stored in the session.
def login_from_session
self.current_user = User.find(session[:user_id]) if
session[:user_id]
end
# Called from #current_user. Now, attempt to login by basic
authentication information.
def login_from_basic_auth
authenticate_with_http_basic do |username, password|
self.current_user = User.authenticate(username, password)
end
end
# Called from #current_user. Finaly, attempt to login by an
expiring token in the cookie.
def login_from_cookie
user = cookies[:auth_token] &&
User.find_by_remember_token(cookies[:auth_token])
if user && user.remember_token?
user.remember_me
cookies[:auth_token] = { :value => user.remember_token, :expires
=> user.remember_token_expires_at }
self.current_user = user
end
end
end
/lib/role_requirement_system.rb
Main module for authentication.
Include this in ApplicationController to activate RoleRequirement
See RoleSecurityClassMethods for some methods it provides.
module RoleRequirementSystem
def self.included(klass)
klass.send :class_inheritable_array, :role_requirements
klass.send :include, RoleSecurityInstanceMethods
klass.send :extend, RoleSecurityClassMethods
klass.send :helper_method, :url_options_authenticate?
klass.send :role_requirements=, []
end
module RoleSecurityClassMethods
def reset_role_requirements!
self.role_requirements.clear
end
# Add this to the top of your controller to require a role in order
to access it.
# Example Usage:
#
# require_role “contractor”
# require_role “admin”, :only => :destroy # don’t allow
contractors to destroy
# require_role “admin”, :only => :update, :unless =>
"current_user.authorized_for_listing?(params[:id]) "
#
# Valid options
#
# * :only - Only require the role for the given actions
# * :except - Require the role for everything but
# * :if - a Proc or a string to evaluate. If it evaluates to true,
the role is required.
# * :unless - The inverse of :if
#
def require_role(roles, options = {})
options.assert_valid_keys(:if, :unless,
:for, :only,
:for_all_except, :except
)
# only declare that before filter once
unless (@before_filter_declared||=false)
@before_filter_declared=true
before_filter :check_roles
end
# convert to an array if it isn't already
roles = [roles] unless Array===roles
options[:only] ||= options[:for] if options[:for]
options[:except] ||= options[:for_all_except] if
options[:for_all_except]
# convert any actions into symbols
for key in [:only, :except]
if options.has_key?(key)
options[key] = [options[key]] unless Array === options[key]
options[key] = options[key].compact.collect{|v| v.to_sym}
end
end
self.role_requirements||=[]
self.role_requirements << {:roles => roles, :options => options }
end
# This is the core of RoleRequirement. Here is where it discerns if
a user can access a controller or not./
def user_authorized_for?(user, params = {}, binding = self.binding)
return true unless Array===self.role_requirements
self.role_requirements.each{| role_requirement|
roles = role_requirement[:roles]
options = role_requirement[:options]
# do the options match the params?
# check the action
if options.has_key?(:only)
next unless options[:only].include?(
(params[:action]||“index”).to_sym )
end
if options.has_key?(:except)
next if options[:except].include?(
(params[:action]||“index”).to_sym)
end
if options.has_key?(:if)
# execute the proc. if the procedure returns false, we don't
need to authenticate these roles
next unless ( String===options[:if] ? eval(options[:if],
binding) : options[:if].call(params) )
end
if options.has_key?(:unless)
# execute the proc. if the procedure returns true, we don't
need to authenticate these roles
next if ( String===options[:unless] ? eval(options[:unless],
binding) : options[:unless].call(params) )
end
# check to see if they have one of the required roles
passed = false
roles.each { |role|
passed = true if user.has_role?(role)
} unless (user==:false || user==false)
return false unless passed
}
return true
end
end
module RoleSecurityInstanceMethods
def self.included(klass)
raise “Because role_requirement extends acts_as_authenticated, You
must include AuthenticatedSystem first before including
RoleRequirementSystem!” unless
klass.included_modules.include?(AuthenticatedSystem)
end
def access_denied
if logged_in?
render :nothing => true, :status => 401
return false
else
super
end
end
def check_roles
return access_denied unless
self.class.user_authorized_for?(current_user, params, binding)
true
end
protected
# receives a :controller, :action, and :params. Finds the given
controller and runs user_authorized_for? on it.
# This can be called in your views, and is for advanced users only.
If you are using :if / :unless eval expressions,
# then this may or may not work (eval strings use the current
binding to execute, not the binding of the target
# controller)
def url_options_authenticate?(params = {})
params = params.symbolize_keys
if params[:controller]
# find the controller class
klass = eval(“#{params[:controller]}_controller”.classify)
else
klass = self.class
end
klass.user_authorized_for?(current_user, params, binding)
end
end
end
Estoy manejando el plugin Role requirement, espero su ayuda.