This question already has answers here:
How can I reset all devise sessions so every user has to login again?
(9 answers)
Closed 8 years ago.
I would like to build a rake task or a tool to destroy all active sessions that is called from CLI when I want and on every night at around 9:00 pm or so.
I found that Devise has the ability to specify a timeout. I use Devise for user sessions. About a third of my users' sessions never time out, despite their system remaining inactive for over one hour.
I don't know what kind of job I need. Feedback would be a plus. Also maybe some links to documentation. Additionally, I can't figure out how to target sessions to destroy them. Rails guides and so on are not clear regarding if it destroys one user's session or all server-client sessions. I need all client-server sessions to be de-activated. Documentation is great, but I like some good explanation.
You could store your secret_key in an ENV variable. In fact, you should try to keep your secret_token away from source control. So you should have an ENV variable that you can change at runtime. Like this:
YourApp::Application.config.secret_token = ENV['SECRET_TOKEN']
To create a secure token you should use SecureRandom.hex(64).
But anyway, if all you want is track when users visit the site, you could create a before_filter that runs before certain actions. A simple example would be:
class ApplicationController < ActionController::Base
before_filter :save_time_of_last_visit
def save_time_of_last_visit
current_user.touch(:last_sign_in_at) if user_signed_in?
end
end
If you use memcache to store the sessions you can create a cron task to restart it.
Related
I'm writing some end-to-end tests for my application using Cucumber and Selenium. I'm keeping every scenario totally independent of one another, as advised on the Cucumber website. However, my application has session based authentication, so every time a new scenario is run, it will required a login process in order to first access the site. Right now my approach is to put the login scenario as a background scenario for all other scenarios, like so:
Background: User is Logged In
Given I am on the login screen
When I enter my login details
And I click submit
Then I should be logged in
However, this feels like a lot of duplicated 'code'. Moreover, having each scenario run independently requires a new WebDriver instance being created and a browser being run for each scenario, which feels a bit inefficient?
Can anyone advise firstly on how I can avoid duplicating the background scenario in every other scenario (if possible) and secondly if having a separate WebDriver instance for each scenario is the correct approach?
First of all each of your scenarios is going to have to login and create a new session. Thats the price you pay to do end to end testing. The cost of this in runtime should be relatively small with a standard login process as most login screens are simple, and have short rendering times and very little db access. It really is a very bad idea to tray and save runtime here by trying to share sessions between scenarios.
To start tidying your cukes you could follow Daniel's answer, but instead of nesting the steps I would recommend extracting the code to a helper method and calling that instead.
To do this elegantly with power, i.e. deal with different users with roles and extra attributes you need to do a bit more. You can see a detailed example of this here (https://github.com/diabolo/cuke_up).
To use this effectively follow the commit history and focus mostly on the features folder.
This has some framework code that allows you to register/create users and then use them in lots of different configurations. There is some underlying code that is a little complex, which gives you the power to create users who know their own passwords, as well as add other attributes like roles.
The end result is that you can write a step definitions like
Given I am registered
Given I am an admin
Given I am logged in
Given I am logged in as an admin
which are implemented as
Given 'I am registered' do
#i = create_user
end
Given 'I am an admin' do
#i = create_user role: 'admin'
end
Given 'I am logged in' do
#i = create_user
login as: #i
end
Given 'I am logged in as an admin' do
#i = create_user role: 'admin'
login as: #i
end
note: the variable #i is used to pass the user from one step to the next
You don't have to worry about repetition here as all the steps make calls to the same helper methods. You can use the patterns shown here in a much wider context to simplify your features/
This example is in Ruby. You can group up the steps used for Login in login_steps.rb file.
In the .feature file you'll need to write a step like "Given the user is logged in". You can pass in login data in this step as well, if you want. Then in the login_steps.rb file, you create:
Given(/^the user is logged in$/) do
step('I am on the login screen')
step('I enter my login details')
step('I click submit')
step('I should be logged in')
end
I'm sure you can find the equivalent in any other language. Now you can write a the background like:
Background: Given the user is logged in
and it will be used before each scenario of that specific .feature file
As for the Webdriver, as far as I'm aware, you create a session when the test starts and you quit when it ends.
Hope it helps!
I need some help with the authorization. So far I was trying to solve it with the internal rails authorization combined with devise.
I have a user who is posting a request. If this request is private only a group of "reader" can see and answer the request. (This is number one)
Then the user give a rating to the answer of the reader. This should be accesible only for the user which received the answer and the "reader" who gave an answer.
So far I was using the following to limit access to the hidden requests:
before_filter :require_reader!, only: [:open_requests]
But if the request is not hidden, than still only the reader should be able to answer the request (but all can see it). Here I do not know how to manage this. Any Ideas?
To continue... I could not manage to solve the second problem (that the rating is seen only be the one who was placing the request and the reader).
Any ideas here?
Is cancancan maybe an option?
Best
witali
What you're doing does not quite follow the 'admin' pattern that's commonly setup with tools like Railsbricks. The 'admin' permissions pattern is typically a whole set of actions/views that are available only to admins, so often the entire Controller, or family of controllers, have the :require_admin! filter applied before every single action and view. Very simple permissions logic, and it depends only on the user and view.
Instead, what you've got is views with permissions that depend on your object's state as well as the user's status and the view. So you're going to have to write your own filter to use instead of using 'require_reader!'.
For example, you might have a RequestsController, and you could add to it:
before_action :must_be_able_to_view_request, except: [:index, :new, :create]
Then define that filter in the controller:
private
def must_be_able_to_view_request
if !current_user.is_reader? && !#request.ispublic
head :forbidden
end
end
If you need to use the same filter in other Controllers, then you can define it in your ApplicationController.
I'm new to building a rails 3 app with multiple language support. The product requires that the translation team should be able to updated phrases from web interface and see its effects on refresh. They are not concerned about the performance hit this model carries.
So i'm using the gem i18n-active_record and its backend with i18n. The problem is, that translations stored in the db are not fetched on every request. I want the system to query the translations table for each key every time it gets the rendering request.
We're to disable this later when the site is mature enough, but this is an essential feature for now. Any ideas?
You could add in your ApplicationController:
before_filter { I18n.reload! }
I'm afraid I can't really comment on using i18n-active_record, but we run a staging server with the localeapp gem running in daemon mode. This means that translations can be editing via a GUI by a translator and they appear instantly on the staging server. Might be something worth looking into for you.
Disclosure: I'm a developer for Locale
I am using 'plugins.spring-security-core' wondering is there any easy way to limit # of session from a given user to just 1. I tried 'HttpSessionBindingListener' but in the current plugin implementation looks like it just binds the user 'id' and not the full user session as such the appropriate events are not getting called.
I am wondering if any one has come across solution to the above problem.
Thanks in advance
-Amitabh
here is a good example
http://blog.block-consult.com/2012/01/restricting-concurrent-user-sessions-in-grails-2-using-spring-security-core-plugin/
/jörg
I'm looking for the way to restrict users access by time in my grails application. I mean that users will be able to use (not only login) application only in allowed timeframes defined by days of week and start & end hours.
Could anyone advise the best way of doing this?
I'm thinking about adding some set of tables to my domain model which will contain time access rules. This rules will be applied to roles and users. Users rules will override roles rules.
As I understand, I need to implement some Authorization (not Authentication) Filter, which will do the check of time restrictions.
Am I one the right way? If so, then could anyone provide some usefull links for this task?
Aha, I already answered this on the mailinglist.
What I wrote:
Possible solution (two-fold):
For login:
Custom UserDetails class that throws appropiate exception if outside
timeslot (not sure if it is the most semantically correct place to do
it, but it's easy there).
For people already logged in:
Quartz job that run at the boundaries (like 2pm if thats when a slot
ends) that run through active sessions and invalidate them.
You can keep a list of active sessions in various ways, one (one and a
half really, not sure if you can use Burt's plugin in a programmatic
way) are covered here:
In grails, how do I get a reference to all current sessions?
I see now that the AccessDecisionVoter is a better solution than the custom userdetails, but the answer still remains for the same for the already logged in people.