Merge pull request #7067 from owncloud/core-sessionheartbeatconfig

Core sessionheartbeatconfig
This commit is contained in:
Vincent Petry 2014-02-05 10:03:36 +01:00
commit 3d88b10f20
5 changed files with 142 additions and 16 deletions

View File

@ -184,6 +184,13 @@ $CONFIG = array(
/* Life time of a session after inactivity */ /* Life time of a session after inactivity */
"session_lifetime" => 60 * 60 * 24, "session_lifetime" => 60 * 60 * 24,
/*
* Enable/disable session keep alive when a user is logged in in the Web UI.
* This is achieved by sending a "heartbeat" to the server to prevent
* the session timing out.
*/
"session_keepalive" => true,
/* Custom CSP policy, changing this will overwrite the standard policy */ /* Custom CSP policy, changing this will overwrite the standard policy */
"custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *", "custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *",

View File

@ -55,6 +55,12 @@ $array = array(
) )
), ),
"firstDay" => json_encode($l->l('firstday', 'firstday')) , "firstDay" => json_encode($l->l('firstday', 'firstday')) ,
"oc_config" => json_encode(
array(
'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', 60 * 60 * 24),
'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true)
)
)
); );
// Echo it // Echo it

View File

@ -11,6 +11,8 @@ var oc_webroot;
var oc_current_user = document.getElementsByTagName('head')[0].getAttribute('data-user'); var oc_current_user = document.getElementsByTagName('head')[0].getAttribute('data-user');
var oc_requesttoken = document.getElementsByTagName('head')[0].getAttribute('data-requesttoken'); var oc_requesttoken = document.getElementsByTagName('head')[0].getAttribute('data-requesttoken');
window.oc_config = window.oc_config || {};
if (typeof oc_webroot === "undefined") { if (typeof oc_webroot === "undefined") {
oc_webroot = location.pathname; oc_webroot = location.pathname;
var pos = oc_webroot.indexOf('/index.php/'); var pos = oc_webroot.indexOf('/index.php/');
@ -742,8 +744,39 @@ function fillWindow(selector) {
console.warn("This function is deprecated! Use CSS instead"); console.warn("This function is deprecated! Use CSS instead");
} }
$(document).ready(function(){ /**
sessionHeartBeat(); * Initializes core
*/
function initCore() {
/**
* Calls the server periodically to ensure that session doesn't
* time out
*/
function initSessionHeartBeat(){
// interval in seconds
var interval = 900;
if (oc_config.session_lifetime) {
interval = Math.floor(oc_config.session_lifetime / 2);
}
// minimum one minute
if (interval < 60) {
interval = 60;
}
OC.Router.registerLoadedCallback(function(){
var url = OC.Router.generate('heartbeat');
setInterval(function(){
$.post(url);
}, interval * 1000);
});
}
// session heartbeat (defaults to enabled)
if (typeof(oc_config.session_keepalive) === 'undefined' ||
!!oc_config.session_keepalive) {
initSessionHeartBeat();
}
if(!SVGSupport()){ //replace all svg images with png images for browser that dont support svg if(!SVGSupport()){ //replace all svg images with png images for browser that dont support svg
replaceSVG(); replaceSVG();
@ -856,7 +889,9 @@ $(document).ready(function(){
$('input[type=text]').focus(function(){ $('input[type=text]').focus(function(){
this.select(); this.select();
}); });
}); }
$(document).ready(initCore);
/** /**
* Filter Jquery selector by attribute value * Filter Jquery selector by attribute value
@ -986,15 +1021,3 @@ jQuery.fn.exists = function(){
return this.length > 0; return this.length > 0;
}; };
/**
* Calls the server periodically every 15 mins to ensure that session doesnt
* time out
*/
function sessionHeartBeat(){
OC.Router.registerLoadedCallback(function(){
var url = OC.Router.generate('heartbeat');
setInterval(function(){
$.post(url);
}, 900000);
});
}

View File

@ -19,6 +19,8 @@
* *
*/ */
/* global OC */
/** /**
* Simulate the variables that are normally set by PHP code * Simulate the variables that are normally set by PHP code
*/ */
@ -57,10 +59,15 @@ window.oc_webroot = location.href + '/';
window.oc_appswebroots = { window.oc_appswebroots = {
"files": window.oc_webroot + '/apps/files/' "files": window.oc_webroot + '/apps/files/'
}; };
window.oc_config = {
session_lifetime: 600 * 1000,
session_keepalive: false
};
// global setup for all tests // global setup for all tests
(function setupTests() { (function setupTests() {
var fakeServer = null; var fakeServer = null,
routesRequestStub;
beforeEach(function() { beforeEach(function() {
// enforce fake XHR, tests should not depend on the server and // enforce fake XHR, tests should not depend on the server and
@ -78,9 +85,18 @@ window.oc_appswebroots = {
// make it globally available, so that other tests can define // make it globally available, so that other tests can define
// custom responses // custom responses
window.fakeServer = fakeServer; window.fakeServer = fakeServer;
OC.Router.routes = [];
OC.Router.routes_request = {
state: sinon.stub().returns('resolved'),
done: sinon.stub()
};
}); });
afterEach(function() { afterEach(function() {
OC.Router.routes_request.state.reset();
OC.Router.routes_request.done.reset();
// uncomment this to log requests // uncomment this to log requests
// console.log(window.fakeServer.requests); // console.log(window.fakeServer.requests);
fakeServer.restore(); fakeServer.restore();

View File

@ -203,4 +203,78 @@ describe('Core base tests', function() {
})).toEqual('number=123'); })).toEqual('number=123');
}); });
}); });
describe('Session heartbeat', function() {
var clock,
oldConfig,
loadedStub,
routeStub,
counter;
beforeEach(function() {
clock = sinon.useFakeTimers();
oldConfig = window.oc_config;
loadedStub = sinon.stub(OC.Router, 'registerLoadedCallback');
routeStub = sinon.stub(OC.Router, 'generate').returns('/heartbeat');
counter = 0;
fakeServer.autoRespond = true;
fakeServer.autoRespondAfter = 0;
fakeServer.respondWith(/\/heartbeat/, function(xhr) {
counter++;
xhr.respond(200, {'Content-Type': 'application/json'}, '{}');
});
});
afterEach(function() {
clock.restore();
window.oc_config = oldConfig;
loadedStub.restore();
routeStub.restore();
});
it('sends heartbeat half the session lifetime when heartbeat enabled', function() {
window.oc_config = {
session_keepalive: true,
session_lifetime: 300
};
window.initCore();
expect(loadedStub.calledOnce).toEqual(true);
loadedStub.yield();
expect(routeStub.calledWith('heartbeat')).toEqual(true);
expect(counter).toEqual(0);
// less than half, still nothing
clock.tick(100 * 1000);
expect(counter).toEqual(0);
// reach past half (160), one call
clock.tick(55 * 1000);
expect(counter).toEqual(1);
// almost there to the next, still one
clock.tick(140 * 1000);
expect(counter).toEqual(1);
// past it, second call
clock.tick(20 * 1000);
expect(counter).toEqual(2);
});
it('does no send heartbeat when heartbeat disabled', function() {
window.oc_config = {
session_keepalive: false,
session_lifetime: 300
};
window.initCore();
expect(loadedStub.notCalled).toEqual(true);
expect(routeStub.notCalled).toEqual(true);
expect(counter).toEqual(0);
clock.tick(1000000);
// still nothing
expect(counter).toEqual(0);
});
});
}); });