Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OPF#1314] Log out users with empty session activity time when session lifetime is ... #244

Merged
merged 7 commits into from
Jul 19, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def logged_user=(user)
if user && user.is_a?(User)
User.current = user
session[:user_id] = user.id
session[:updated_at] = Time.now
else
User.current = User.anonymous
end
Expand Down Expand Up @@ -616,27 +617,32 @@ def disable_api
ActiveSupport.run_load_hooks(:application_controller, self)

def check_session_lifetime
session_ttl_value = Setting.session_ttl.to_i

if Setting.session_ttl_enabled? && session_ttl_value >= 5
if session[:updated_at] && User.current.logged? && ((session[:updated_at] + (session_ttl_value * 60)) < Time.now)
self.logged_user = nil
if request.get?
url = url_for(params)
else
url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
end

flash[:warning] = I18n.t('notice_forced_logout', :ttl_time => Setting.session_ttl)
redirect_to(:controller => "account", :action => "login", :back_url => url)
if session_expired?
self.logged_user = nil
if request.get?
url = url_for(params)
else
session[:updated_at] = Time.now
url = url_for(:controller => params[:controller], :action => params[:action],
:id => params[:id], :project_id => params[:project_id])
end
flash[:warning] = I18n.t('notice_forced_logout', :ttl_time => Setting.session_ttl)
redirect_to(:controller => "account", :action => "login", :back_url => url)
end
session[:updated_at] = Time.now
end

private

def session_expired?
current_user.logged? &&
(session_ttl_enabled? && (session[:updated_at].nil? ||
(session[:updated_at] + Setting.session_ttl.to_i.minutes) < Time.now))
end

def session_ttl_enabled?
Setting.session_ttl_enabled? && Setting.session_ttl.to_i >= 5
end

def permitted_params
@permitted_params ||= PermittedParams.new(params, current_user)
end
Expand Down
1 change: 1 addition & 0 deletions doc/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Changelog

* `#1314` Always set last activity timestamp and check session expiry if ttl-setting is enabled
* `#1414` Remove start & due date requirement from planning elements

## 3.0.0pre8
Expand Down
49 changes: 49 additions & 0 deletions features/session/user_session.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#-- copyright
# OpenProject is a project management system.
#
# Copyright (C) 2012-2013 the OpenProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# See doc/COPYRIGHT.rdoc for more details.
#++

Feature: User session
Background:
Given there is 1 project with the following:
| name | Awesome Project |
| identifier | awesome-project |
And project "Awesome Project" uses the following modules:
| calendar |
And there is a role "member"
And the role "member" may have the following rights:
| view_calendar |
And there is 1 user with the following:
| login | bob |
And the user "bob" is a "member" in the project "Awesome Project"

Scenario: A user can log in
When I login as "bob"
Then I should be logged in as "bob"

Scenario: A user can log out
Given I am logged in as "bob"
When I logout
Then I should be logged out

Scenario: A user is logged out when their session is expired
Given the "session_ttl_enabled" setting is set to true
And the "session_ttl" setting is set to 5
When I login as "bob"
And I wait for "10" minutes
And I go to the home page
Then I should be logged out

Scenario: A user is logged in as long as their session is valid
Given the "session_ttl_enabled" setting is set to true
And the "session_ttl" setting is set to 5
When I login as "bob"
And I wait for "4" minutes
And I go to the home page
Then I should be logged in as "bob"
12 changes: 12 additions & 0 deletions features/step_definitions/general_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -366,13 +366,21 @@
login(username, password)
end

When "I logout" do
visit "/logout"
end

Then /^I should be logged in as "([^\"]*)"?$/ do |username|
user = User.find_by_login(username) || User.anonymous
page.should have_xpath("//div[contains(., 'Logged in as #{username}')] | //a[contains(.,'#{user.name}')]")

User.current = user
end

Then "I should be logged out" do
page.should have_css("a.login")
end

When /^I satisfy the "(.+)" plugin to (.+)$/ do |plugin_name, action|
if plugin_loaded?(plugin_name)
action_name = action.gsub("\"", "")
Expand Down Expand Up @@ -409,6 +417,10 @@
end
end

When(/^I wait for "(.*?)" minutes$/) do |number_of_minutes|
page.set_rack_session(updated_at: Time.now - number_of_minutes.to_i.minutes)
end

def get_project(project_name = nil)
if project_name.blank?
project = @project
Expand Down
21 changes: 17 additions & 4 deletions spec/controllers/users_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@
end
end

shared_examples_for 'index action with enabled session lifetime and inactivity exceeded' do
it "logs out the user and redirects with a warning that he has been locked out" do
response.redirect_url.should == (signin_url + "?back_url=" + CGI::escape(@controller.url_for(:controller => "users", :action => "index")))
User.current.should_not == admin
flash[:warning].should == I18n.t(:notice_forced_logout, :ttl_time => Setting.session_ttl)
end
end

context "disabled" do
before do
Setting.stub!(:session_ttl_enabled?).and_return(false)
Expand Down Expand Up @@ -272,11 +280,16 @@
session[:updated_at] = Time.now - 3.hours
get :index
end
it "logs out the user and redirects with a warning that he has been locked out" do
response.redirect_url.should == (signin_url + "?back_url=" + CGI::escape(@controller.url_for(:controller => "users", :action => "index")))
User.current.should_not == admin
flash[:warning].should == I18n.t(:notice_forced_logout, :ttl_time => Setting.session_ttl)
it_should_behave_like 'index action with enabled session lifetime and inactivity exceeded'
end

context "without last activity time in the session" do
before do
Setting.stub!(:session_ttl).and_return("60")
session[:updated_at] = nil
get :index
end
it_should_behave_like 'index action with enabled session lifetime and inactivity exceeded'
end

context "with ttl = 0" do
Expand Down