before_fail doesn't track which user, so an alternative has_many is:..
RobertLowe opened this issue · comments
https://github.com/ankane/authtrail/blob/master/lib/auth_trail/manager.rb#L20-L33
before_fail
doesn't track which user, so an alternative has_many is:
has_many :login_activities, class_name: "LoginActivity", primary_key: 'email', foreign_key: "identity"
the docs should mention this, I think it's a reasonable addition
Hey @RobertLowe, thanks for the suggestion, but it's typically better to record the user directly (documented in the readme), since many apps allow users to change email addresses.
Thanks, Im not sure those calls would cover it.
Existing:
def before_failure(env, opts)
AuthTrail.safely do
request = ActionDispatch::Request.new(env)
AuthTrail.track(
strategy: detect_strategy(env["warden"]),
scope: opts[:scope].to_s,
identity: AuthTrail.identity_method.call(request, opts, nil),
success: false,
request: request,
failure_reason: opts[:message].to_s
)
end
end
Ugly POC Idea, there's probably much more elegant way to handle this:
def before_failure(env, opts)
AuthTrail.safely do
request = ActionDispatch::Request.new(env)
user_input = env["rack.request.form_hash"][opts[:scope].to_s]
if(user_input && user_input["email"])
user_klass = env["devise.mapping"].class_name
klass = eval(user_klass);
user = klass.where(email: user_input["email"]).limit(1).first
end
AuthTrail.track(
strategy: detect_strategy(env["warden"]),
scope: opts[:scope].to_s,
identity: AuthTrail.identity_method.call(request, opts, nil),
user: user,
success: false,
request: request,
failure_reason: opts[:message].to_s
)
end
end
At the time of failure we could at least do a look up to match it with the user that current holds that email. So even if they change it in the future it will still track to the user.
Additionally, while user
is polymorphic, it does not work with polymorphic user models, always appearing as User
, even if the polymorphic model was Employee < User
for example, while technically still correct it feels like another area of improvement.
Cheers
My bad, it looks like it never made it to the docs. I just added it and pushed out a new release, so users can do:
AuthTrail.transform_method = lambda do |data, request|
data[:user] ||= User.find_by(email: data[:identity])
end
Re polymorphic issue: AuthTrail just sets the user
attribute on the LoginActivity
model, so the behavior you're seeing should just be standard Rails.
Lines 52 to 55 in d28f07e
Sweet, thanks, closing.