I have a small inherited rails project that uses devise to authenticate.
Recently it has started making an incorrect query to the database if the user enters an invalid password, as set out below. Previously it works as expected. I must have changed something, but I do not know what.
With a VALID password
When the user logs in with a VALID password, the console log shows similar to this
Started POST "/users/sign_in" for 192.168.2.30 at 2015-07-13 08:13:39 -0400
Processing by Users::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"A_Long_Authenticity_Token_Goes_Here", "user"=>{"email"=>"m.mouse#disney.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["email", "m.mouse#disney.com"]]
(0.3ms) BEGIN
SQL (0.6ms) UPDATE "users" SET "last_sign_in_at" = $1, "current_sign_in_at" = $2, "sign_in_count" = $3, "updated_at" = $4 WHERE "users"."id" = $5 [["last_sign_in_at", "2015-07-10 21:17:12.592611"], ["current_sign_in_at", "2015-07-13 12:13:39.359997"], ["sign_in_count", 1000], ["updated_at", "2015-07-13 12:13:39.363621"], ["id", 22]]
(17.6ms) COMMIT
and the system carries on as normal.
With an INvalid password
When the user attempts to log in with an INVALID password, the console log shows similar to this
Started POST "/users/sign_in" for 192.168.2.30 at 2015-07-13 07:44:55 -0400
Processing by Users::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"A_Long_Authenticity_Token_Goes_Here", "user"=>{"email"=>"m.mouse#disney.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
User Load (53.0ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["email", "m.mouse#disney.com"]]
Completed 401 Unauthorized in 288ms (ActiveRecord: 53.4ms)
Processing by Users::SessionsController#new as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"A_Long_Authenticity_Token_Goes_Here", "user"=>{"email"=>"m.mouse#disney.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
User Load (2.2ms) SELECT "users".* FROM "users" WHERE "email"."email" = 'm.mouse#disney.com' AND "email"."password" = 'ThisIsAnInvalidPassword' AND "email"."remember_me" = '0' ORDER BY "users"."id" ASC LIMIT 1
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "email"
LINE 1: SELECT "users".* FROM "users" WHERE "email"."email" = 'm.mou....
: SELECT "users".* FROM "users" WHERE "email"."email" = 'm.mouse#disney.com' AND "email"."password" = 'ThisIsAnInvalidPassword' AND "email"."remember_me" = '0' ORDER BY "users"."id" ASC LIMIT 1
Completed 500 Internal Server Error in 19ms (ActiveRecord: 3.3ms)
<< Output standard rails error page >>
So far as I understand this, the system tries to read the user table as expected, but no row is found. Devise munges this into a 401 Unauthorized response. The system is then attempting to redirect back to the login page somehow using Users::SessionsController#new
The system then tries a completely new query trying to look up the user using a half formatted query. The query tries to include a table called email that does not exist in the database; the query syntax is not correct either.
Database: postgres
Rails: 2.1.2
Devise gem: 3.5.1 according to bundle show
There is no Users::SessionsController#create def, so presumably using the underlying devise version
There is a Users::SessionsController#new as follows
def new
if (Rails.env.development? || Rails.env.test?) && params[:user]
user = User.where(email: params[:user]).first
sign_in :user, user
redirect_to dashboard_home_path
else
super
end
end
The environment is development
Nothing appears to be being written to the sessions table whether the login is successful or not.
Where does that second malformed query even come from, and why does devise try to use/call Users::SessionsController#new after an invalid login attempt anyway?
Thanks in advance
Related
Created new ruby app
in my controller im trying to sign in a user like so
email = params[:email]
password = params[:password]
user = User.authenticate(email, password)
if user
sign_in(user)
redirect_to root_path
else
render json: {success: false}
end
The user is going into sign_in
console is printing:
Processing by AccountController#sign_in_user as */*
Parameters: {"password"=>"[FILTERED]", "email"=>"email#live.com", "subdomain"=>"app"}
User Load (1.9ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["email", "email#live.com"], ["LIMIT", 1]]
↳ app/models/user.rb:9
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 2], ["LIMIT", 1]]
↳ app/controllers/account_controller.rb:11
Redirected to http://app.lvh.me:3000/
Completed 200 OK in 131ms (ActiveRecord: 2.4ms)
It then redirects to my root path for authenticated users and gives me a 401
Started GET "/" for 127.0.0.1 at 2018-04-30 21:53:39 -0400
Processing by DashboardController#index as HTML
Parameters: {"subdomain"=>"app"}
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)
In the DB the user's current_sign_in, last_sign_in, ect.. are being updated
I've done this numerous times, i'm not sure why its not working, any ideas?
Well after an hour of going crazy
i had a random line in my routes
devise_for :users
with no end doing nothing and it was causing this issue.
after removing that everything is fine.
how can I manage and edit other users profiles as an admin since I have one model and controller (users) ?
I tried to add a new action called updateusers
def updateusers
#other_user=User.find(params[:id])
if #other_user.update_attributes(otherusers_params)
redirect_to '/'
else
redirect_to '/manage'
end
end
the problem here :it is updating my admin user with the other_user's
data
stack trace
Started GET "/manage" for ::1 at 2016-03-19 21:06:08 +0300 Processing by
UsersController#manage as HTML User Load (1.0ms) SELECT "users".* FROM
"users" Rendered users/manage.html.erb within layouts/application (5.0ms) User
Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1
[["id", 1]] Completed 200 OK in 53ms (Views: 51.0ms | ActiveRecord: 1.0ms)
'Started GET "/users/10" for ::1 at 2016-03-19 21:06:10 +0300 Processing by
UsersController#show as HTML Parameters: {"id"=>"10"} User Load (0.0ms) SELECT
"users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 10]] Rendered
users/show.html.erb within layouts/application (0.0ms) User Load (0.0ms) SELECT
"users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]] Completed 200
OK in 37ms (Views: 36.0ms | ActiveRecord: 0.0ms)
Started GET "/editusers/10" for ::1 at 2016-03-19 21:06:11 +0300 Processing
by UsersController#editusers as HTML Parameters: {"id"=>"10"} User Load (0.0ms)
SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 10]]
Rendered users/editusers.html.erb within layouts/application (4.0ms) User Load
(1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Completed 200 OK in 41ms (Views: 39.0ms | ActiveRecord: 1.0ms)
Started PATCH "/users/10" for ::1 at 2016-03-19 21:06:15 +0300 Processing by
UsersController#update as HTML Parameters: {"utf8"=>"✓",
"authenticity_token"=>"6M1TGLQUEhiezCCg9/rT5IofdroMiQ0sm+bYcihgGDxTjDdFGU2Riou2p
cRk5ncjCtFDGwfBj17Uq7gc0u329w==", "user"=>{"first_name"=>"g", "last_name"=>"g",
"email"=>"g#g.g", "role"=>"editor", "image"=>"pic.png", "admins"=>""},
"other"=>"update", "id"=>"10"} User Load (0.0ms) SELECT "users".* FROM "users"
WHERE "users"."id" = ? LIMIT 1 [["id", 1]] Unpermitted parameters: role, admins
(0.0ms) begin transaction SQL (1.0ms) UPDATE "users" SET "first_name" = ?,
"last_name" = ?, "email" = ?, "updated_at" = ? WHERE "users"."id" = ?
[["first_name", "g"], ["last_name", "g"], ["email", "g#g.g"], ["updated_at",
"2016-03-19 18:06:15.488284"], ["id", 1]] (47.0ms) commit transaction Redirected
to localhost:8080/profile Completed 302 Found in 54ms (ActiveRecord: 48.0ms)
The user ID of the form in "editusers" is set to your admin (or logged in user). It's hard to say without seeing the code but I think you've set up the editusers form incorrectly. Perhaps using a hidden field to hold the ID of the user you want to update.
Try to avoid that and set up the #user object in the 'editusers' action #user = User.find(10)
Then in your view use a form_for #user do |f| without any hidden fields for the ID.
after 10 days ,, Yes i did it - the solution is in the name of submit , I named the two submits with diffrent names <%= f.submit "update", name:"other" %> then i used the update action like this
def update
if params[:current]
#user = current_user
if #user.update_attributes(user_params)
redirect_to '/profile'
else
redirect_to '/edit'
end
elsif params[:other]
#other_user=User.find(params[:id])
if #other_user.update_attributes(otherusers_params)
redirect_to '/'
else
redirect_to '/manage'
end
end
end
I am using Rails 4.1.14, Ruby 2.1.6, Devise 3.2.4 and Devise_invitable 1.3.6.
The issue I am having is once a new user I invited presses the accept invitation link in the email they received, it gets stuck in a redirect loop. I can't figure out why.
These are the server logs for the entire operation (note that the bulk of the first part of the log corresponds to the logic I omit below - but I left it in case it tells something interesting) :
Started GET "/users/invitation/accept?invitation_token=qANzitr64dxzxG9dSsMU" for 127.0.0.1 at 2015-12-12 04:51:29 -0500
Processing by Users::InvitationsController#edit as HTML
Parameters: {"invitation_token"=>"qANzitr6"}
User Load (4.0ms) SELECT "users".* FROM "users" WHERE "users"."invitation_token" = 'qANzitr6' ORDER BY "users"."id" ASC LIMIT 1
User Load (1.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
Member Load (3.8ms) SELECT "members".* FROM "members" WHERE "members"."email" = 'def#test.com' LIMIT 1
Membership Load (88.3ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."member_id" = 115 LIMIT 1
Connection Load (14.8ms) SELECT "connections".* FROM "connections" WHERE "connections"."membership_id" = 173 ORDER BY "connections"."id" ASC LIMIT 1
(2.3ms) BEGIN
SQL (3.4ms) UPDATE "memberships" SET "invited_id" = $1, "member_id" = $2, "relative_type" = $3, "updated_at" = $4 WHERE "memberships"."id" = 173 [["invited_id", 83], ["member_id", nil], ["relative_type", 1], ["updated_at", "2015-12-12 09:51:30.038439"]]
(1.8ms) COMMIT
Membership Load (2.3ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = $1 AND "memberships"."invited_id" = 83 ORDER BY "memberships"."id" ASC LIMIT 1 [["user_id", 1]]
FamilyTree Load (1.7ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 83]]
Membership Load (3.7ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 83 AND "memberships"."invited_id" = 1 AND "memberships"."family_tree_id" = 85 AND "memberships"."relation" = 'wife' AND "memberships"."relative_type" = 1 LIMIT 1
(33.0ms) BEGIN
SQL (37.9ms) INSERT INTO "memberships" ("created_at", "family_tree_id", "invited_id", "relation", "relative_type", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["created_at", "2015-12-12 09:51:30.105734"], ["family_tree_id", 85], ["invited_id", 1], ["relation", "wife"], ["relative_type", 1], ["updated_at", "2015-12-12 09:51:30.105734"], ["user_id", 83]]
Connection Exists (11.7ms) SELECT 1 AS one FROM "connections" INNER JOIN "memberships" ON "memberships"."id" = "connections"."membership_id" WHERE (memberships.invited_id = 83) LIMIT 1
(2.1ms) COMMIT
(1.6ms) BEGIN
SQL (3.7ms) UPDATE "connections" SET "invited_membership_id" = $1, "invited_user_id" = $2, "request_status" = $3, "responded_at" = $4, "updated_at" = $5 WHERE "connections"."id" = 127 [["invited_membership_id", 174], ["invited_user_id", 83], ["request_status", 1], ["responded_at", "2015-12-12 09:51:30.167563"], ["updated_at", "2015-12-12 09:51:30.172215"]]
(1.9ms) COMMIT
SQL (2.3ms) DELETE FROM "members" WHERE "members"."id" = 115
Rendered shared/_footer.html.erb (4.5ms)
Rendered users/invitations/edit.html.erb within layouts/devise (48.6ms)
Completed 200 OK in 1689ms (Views: 1405.9ms | ActiveRecord: 222.2ms)
Started PUT "/users/invitation" for 127.0.0.1 at 2015-12-12 04:51:53 -0500
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "user"=>{"invitation_token"=>"qANzitr6", "gender"=>"female", "invitation_relation"=>"wife", "full_name"=>"My Wife", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Register", "id"=>"invitation"}
Completed 401 Unauthorized in 8ms (ActiveRecord: 0.0ms)
Started GET "/users/login" for 127.0.0.1 at 2015-12-12 04:51:53 -0500
Processing by UsersController#show as HTML
Parameters: {"id"=>"login"}
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)
Started GET "/users/login" for 127.0.0.1 at 2015-12-12 04:51:53 -0500
Processing by UsersController#show as HTML
Parameters: {"id"=>"login"}
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)
This is my Users::InvitationsController#Edit
def edit
# Some logic that I know works and is irrelevant to this question.
# below is lifted directly from the `edit` action within the gem itself.
set_minimum_password_length if respond_to? :set_minimum_password_length
resource.invitation_token = params[:invitation_token]
render :edit
end
Then I specified an accept_resource method like the docs suggested I do if I want anything special to happen after or before the invitation is sent.
def accept_resource
resource = resource_class.accept_invitation!(update_resource_params)
resource.confirm!
resource
end
I assumed that part of the reason this must be happening is that I am stuck in a loop where the user's account wasn't confirmed after they accepted....hence that override.
Here is my User.rb:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :invitable, :confirmable
end
What could be causing this?
I want to debug my application and check what values are submitted on the form object in my controller class via logger ? How can it be done? Is there any better practice to debug rails application?
Your rails log (eg log/development.log) should already show everything that the form submitted, in the "Parameters". It will look like this:
Processing MusicServiceAdmin::UsersController#edit (for 127.0.0.1 at 2014-07-31 10:34:16) [GET]
Session ID: 3c0cfbe7ff23f8f718f6626748a4a
Parameters: {"id"=>"35363"}
Params
Each request in Rails is tracked using the console - you should examine the params which come through from there:
Started POST "/admin/login" for 127.0.0.1 at 2014-04-26 16:25:34 +0100
Processing by Admin::Users::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"+I1TKfc1YDuil7EI1frrFIoerNg5uonB1CIiujJO0jo=", "user"=>{"email"=>"*********", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign In"}
[1m[36mUser Load (482.0ms)[0m [1mSELECT `users`.* FROM `users` WHERE `users`.`email` = 'rpeck#frontlineutilities.co.uk' ORDER BY `users`.`id` ASC LIMIT 1[0m
[1m[35m (435.0ms)[0m BEGIN
[1m[36mSQL (439.0ms)[0m [1mUPDATE `users` SET `current_sign_in_at` = '2014-04-26 15:25:35', `last_sign_in_at` = '2014-04-04 12:08:45', `sign_in_count` = 51, `updated_at` = '2014-04-26 15:25:36' WHERE `users`.`id` = 2[0m
[1m[35m (448.0ms)[0m COMMIT
[1m[36mOption Load (404.0ms)[0m [1mSELECT `options`.* FROM `options` WHERE `options`.`name` = 'site_robots' LIMIT 1[0m
[1m[35mOption Load (357.0ms)[0m SELECT `options`.* FROM `options` WHERE `options`.`name` = 'site_title' LIMIT 1
[1m[36mOption Load (428.0ms)[0m [1mSELECT `options`.* FROM `options` WHERE `options`.`name` = 'site_description' LIMIT 1[0m
Redirected to http://lvh.me:3000/****
Completed 302 Found in 3165ms (ActiveRecord: 2993.2ms)
If you want to "debug", you just have to examine the various params / actions which are rendered in the console. Alternatively, you may also wish to the use the Rails.logger.info method for specific data:
#app/controllers/your_controller.rb
Class YourController < ApplicationController
def index
Rails.logger.info("Test")
end
end
I have the following:
class User < ActiveRecord::Base
before_update :guest_upgrade
def guest_upgrade
# If the user changed their email that means they were a guest, and are no longer.
# Likely triggered from the Registrations#Update controller
if self.email_changed?
self.guest = false
end
end
This is causing rollbacks, here is the log with the above in play:
Started POST "/users" for 127.0.0.1 at 2011-07-18 14:54:00 -0700
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x+u1DSDanU2QXK/q0=", "user"=>{"fname"=>"xxxxx", "lname"=>"xxxx", "email"=>"xxxxxxx#gmail.com", "password"=>"[FILTERED]", "remember_me"=>"1"}, "commit"=>"Create my account", "fb_access_token"=>"", "fb_uuid"=>""}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
SQL (0.1ms) BEGIN
User Load (0.5ms) SELECT "users"."id" FROM "users" WHERE ("users"."email" = 'xxxxxxx#gmail.com') AND ("users".id <> 5) LIMIT 1
SQL (0.2ms) ROLLBACK
Authentication Load (0.5ms) SELECT "authentications".* FROM "authentications" WHERE "authentications"."provider" = 'facebook' AND ("authentications".user_id = 5) LIMIT 1
Rendered layouts/_header.html.erb (3.9ms)
CACHE (0.0ms) SELECT "authentications".* FROM "authentications" WHERE "authentications"."provider" = 'facebook' AND ("authentications".user_id = 5) LIMIT 1
Rendered registrations/edit.html.erb within layouts/application (107.0ms)
Completed 200 OK in 484ms (Views: 111.7ms | ActiveRecord: 6.0ms)
Yet if I comment out the guest_upgrade it works fine:
Started POST "/users" for 127.0.0.1 at 2011-07-18 14:55:23 -0700
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxxxx+u1DSDanU2QXK/q0=", "user"=>{"fname"=>"XXXX", "lname"=>"XXXX", "email"=>"xxxx#gmail.com"}, "commit"=>"Save Changes"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
SQL (0.1ms) BEGIN
User Load (0.4ms) SELECT "users"."id" FROM "users" WHERE ("users"."email" = 'xxxx#gmail.com') AND ("users".id <> 5) LIMIT 1
AREL (0.7ms) UPDATE "users" SET "fname" = 'XXXX', "lname" = 'XXXX', "email" = 'xxxx#gmail.com', "updated_at" = '2011-07-18 21:55:23.817142' WHERE "users"."id" = 5
[paperclip] Saving attachments.
SQL (37.9ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 780ms
Am I using the dirty objects incorrectly?
All I want to do is, when User is updated, if the user changes there email, change the user.guest field to false.
Suggestions? Thanks
I think I've had this problem before. I believe what's happening is it's returning false; try adding an explicit return like so:
if self.email_changed?
self.guest = false
return true
end
Check out the section marked Canceling Callbacks at ruby on rails.org api. It reads:
Canceling callbacks
If a before_* callback returns false, all the later callbacks and the
associated action are cancelled. If an after_* callback returns false,
all the later callbacks are cancelled. Callbacks are generally run in
the order they are defined, with the exception of callbacks defined as
methods on the model, which are called last.
I know I'm late but I hope this helps!