I have a simple Rails app that I am close to deploying on our intranet. The security model is "either you are an admin or your are not," with the method of implementing this model being done by the login_generator 1.1.0. There is one account set up, ''admin'', with three of us having the ability to logon with this username (i.e. we know the password). I am looking to implement the following functionality: 1. Allow only 1 login at a time-- if ''admin'' is logged in and another person tries to log in with ''admin'', they are denied. 2. Have an ''auto-logout'' feature where if there is no activity after say, 15mins, the sesion expires and a new login is required to get back in. For [1], I''ve tried hacking the login method in app/controllers/account_controller.rb by adding: if !<at>session[:user].nil? render :text=>"already logged in!" else [...rest of stock login code...] Since there''s only one available username, I''m just checking to see if <at>session is not empty; if it is, then someone is logged in, so prevent the current user from doing so. Unfortunately, this has no effect-- I can still log in multiple times with the admin account. For [2], I''m assuming this would be done by setting a time limit on the session. Researching ActionController::Base#process_cgi (which apparently is just an alias for Ruby''s CGI::Session) turns up the :session_expires option which seems to be what I''m looking for. However, I see the following in the AWD book, pg.306: ":session_expires The absolute time of the expiry of this session. Like :new_session, this option should probably not be used under Rails." Hmmm. Any suggestions? -- Posted via http://www.ruby-forum.com/.
The session isn''t going to do anything for you, because one is created for each "browser" that hits the site. That''s why your experiment didn''t work - the session for your first admin login isn''t going to be visible from your second. Instead, you need a way to check, across sessions, if someone is logged is an admin. The only thing I can think of is to write the session_id (@ session.session_id) to a database table when an admin logs in. Then, if someone tries to login as an admin, check if their session_id matches the one in the table. If not, don''t let them in. When the admin logs out, clear the session_id from the table and you are set up for the next login. You can then store a timestamp in the same row that is updated via a before_filter method everytime the ''valid'' admin does an action. That way, you can easily check if session_id has been idle more than 15 minutes when a new admin comes along, and let them in if so. Honestly, though, I would look at yoru application model as a whole. Why are you writing a web application that needs to be single-user? Write a command line script instead and you don''t have to worry about this issue at all. Anyways, hope that helps. Justin On 3/15/06, dave davidson <datapanix@gmail.com> wrote:> > I have a simple Rails app that I am close to deploying on > our intranet. The security model is "either you are an admin > or your are not," with the method of implementing this model > being done by the login_generator 1.1.0. > > There is one account set up, ''admin'', with three of us > having the ability to logon with this username (i.e. we > know the password). I am looking to implement the > following functionality: > > 1. Allow only 1 login at a time-- if ''admin'' is logged > in and another person tries to log in with ''admin'', they > are denied. > > 2. Have an ''auto-logout'' feature where if there is no > activity after say, 15mins, the sesion expires and a new > login is required to get back in. > > For [1], I''ve tried hacking the login method in > app/controllers/account_controller.rb by adding: > > if !<at>session[:user].nil? > render :text=>"already logged in!" > else > [...rest of stock login code...] > > Since there''s only one available username, I''m just checking > to see if <at>session is not empty; if it is, then someone is > logged in, so prevent the current user from doing so. > Unfortunately, this has no effect-- I can still log in multiple > times with the admin account. > > For [2], I''m assuming this would be done by setting a time > limit on the session. Researching > ActionController::Base#process_cgi (which apparently is just > an alias for Ruby''s CGI::Session) turns up the :session_expires > option which seems to be what I''m looking for. However, I see > the following in the AWD book, pg.306: > > ":session_expires > The absolute time of the expiry of this session. Like > :new_session, this option should probably not be used > under Rails." > > Hmmm. Any suggestions? > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060315/a6d0b5ee/attachment-0001.html
Would a Class-level variable (e.g., @@logged_in) not work for this? Thanks, Bill ----- Original Message ----- From: Justin Bailey To: rails@lists.rubyonrails.org Sent: 2006-03-15 11:15 AM Subject: Re: [Rails] [login_generator] implementing login limits The session isn''t going to do anything for you, because one is created for each "browser" that hits the site. That''s why your experiment didn''t work - the session for your first admin login isn''t going to be visible from your second. Instead, you need a way to check, across sessions, if someone is logged is an admin. The only thing I can think of is to write the session_id (@session.session_id) to a database table when an admin logs in. Then, if someone tries to login as an admin, check if their session_id matches the one in the table. If not, don''t let them in. When the admin logs out, clear the session_id from the table and you are set up for the next login. You can then store a timestamp in the same row that is updated via a before_filter method everytime the ''valid'' admin does an action. That way, you can easily check if session_id has been idle more than 15 minutes when a new admin comes along, and let them in if so. Honestly, though, I would look at yoru application model as a whole. Why are you writing a web application that needs to be single-user? Write a command line script instead and you don''t have to worry about this issue at all. Anyways, hope that helps. Justin On 3/15/06, dave davidson <datapanix@gmail.com> wrote: I have a simple Rails app that I am close to deploying on our intranet. The security model is "either you are an admin or your are not," with the method of implementing this model being done by the login_generator 1.1.0. There is one account set up, ''admin'', with three of us having the ability to logon with this username ( i.e. we know the password). I am looking to implement the following functionality: 1. Allow only 1 login at a time-- if ''admin'' is logged in and another person tries to log in with ''admin'', they are denied. 2. Have an ''auto-logout'' feature where if there is no activity after say, 15mins, the sesion expires and a new login is required to get back in. For [1], I''ve tried hacking the login method in app/controllers/account_controller.rb by adding: if !<at>session[:user].nil? render :text=>"already logged in!" else [...rest of stock login code...] Since there''s only one available username, I''m just checking to see if <at>session is not empty; if it is, then someone is logged in, so prevent the current user from doing so. Unfortunately, this has no effect-- I can still log in multiple times with the admin account. For [2], I''m assuming this would be done by setting a time limit on the session. Researching ActionController::Base#process_cgi (which apparently is just an alias for Ruby''s CGI::Session) turns up the :session_expires option which seems to be what I''m looking for. However, I see the following in the AWD book, pg.306: ":session_expires The absolute time of the expiry of this session. Like :new_session, this option should probably not be used under Rails." Hmmm. Any suggestions? -- Posted via http://www.ruby-forum.com/. _______________________________________________ Rails mailing list Rails@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails ------------------------------------------------------------------------------ _______________________________________________ Rails mailing list Rails@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060315/88d98b90/attachment.html
dave davidson
2006-Mar-16 15:13 UTC
[Rails] Re: [login_generator] implementing login limits
Justin Bailey wrote:> The session isn''t going to do anything for you, because one is created > for > each "browser" that hits the site. That''s why your experiment didn''t > work - > the session for your first admin login isn''t going to be visible from > your > second. > > Instead, you need a way to check, across sessions, if someone is logged > is > an admin. The only thing I can think of is to write the session_id (@ > session.session_id) to a database table when an admin logs in. Then, if > someone tries to login as an admin, check if their session_id matches > the > one in the table. If not, don''t let them in. When the admin logs out, > clear > the session_id from the table and you are set up for the next login.Gotcha. So the way I see it, I should make a new table in the db, say admin_logins, with a corresponding AdminLogin model. When someone logs in as admin, create a new row with the session_id and timestamp it. If someone else tries to log in, check to see-- via AdminLogin.count-- if an admin is already logged in and if so, deny access. When the original admin logs out, clear the admin_logins table. The only issue I see with this method is the case of a "dirty" logout, i.e. if admin is logged in and closes the browser without logging out first. The data in admin_logins will still exist and subsequent attempts of others to log in as admin will fail. Although the login timeout feature should theoretically take care of this, if another admin tries to log in before the timeout period, they would not be able to.> You can then store a timestamp in the same row that is updated via a > before_filter method everytime the ''valid'' admin does an action. That > way, > you can easily check if session_id has been idle more than 15 minutes > when a > new admin comes along, and let them in if so.> > Honestly, though, I would look at yoru application model as a whole. Why > are > you writing a web application that needs to be single-user? Write a > command > line script instead and you don''t have to worry about this issue at all. >This is definitely a multi-user system; there will be dozens of non-admins that want to access the data contained in the database simultaneously. We just want to restrict the *modification* of this data to a few of us and let the rest of the world see the results. In this sense, it''s more of an "oligarchy". I just wanted to use that word to convince myself I didn''t sleep through Poli-Sci :)> Anyways, hope that helps.It did... thank you! -- Posted via http://www.ruby-forum.com/.