jenkins-bot has submitted this change and it was merged.

Change subject: Ping server to keep the session alive
......................................................................


Ping server to keep the session alive

Ping the server every 5 minutes to refresh the server side session and
the local CSRF token. Pings are only made if there has been activity in
the window (typing or mouse movement) since the last ping.

Bug: T63269
Co-Authored-By: Bryan Davis <bd...@wikimedia.org>
Change-Id: I6babb68ddb77296afbd67947dbc7f79e611df882
---
M data/templates/apply.html
A data/templates/apply.js
A data/templates/csrf.json
M src/Wikimania/Scholarship/App.php
A src/Wikimania/Scholarship/Controllers/RevalidateCsrf.php
5 files changed, 119 insertions(+), 2 deletions(-)

Approvals:
  BryanDavis: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/data/templates/apply.html b/data/templates/apply.html
index 90a411d..e7419d4 100644
--- a/data/templates/apply.html
+++ b/data/templates/apply.html
@@ -17,6 +17,12 @@
 
 {% block nav_li_apply %}class="active"{% endblock %}
 
+{% block javascript %}
+<script type="text/javascript">
+{% include 'apply.js' %}
+</script>
+{% endblock javascript %}
+
 {% block content %}
 {% spaceless %}
 
@@ -71,8 +77,8 @@
 
 <div class="row">
   <div class="col-md-8 col-md-offset-2">
-<form action="{{ urlFor( 'apply_post' ) }}" method="post" role="form">
-  <input type="hidden" name="{{ csrf_param }}" value="{{ csrf_token }}" />
+<form id="appform" action="{{ urlFor( 'apply_post' ) }}" method="post" 
role="form">
+  <input id="token" type="hidden" name="{{ csrf_param }}" value="{{ csrf_token 
}}" />
   <input type="hidden" name="lang" id="lang" value="{{ lang }}" />
   <div class="form-group">
     <label class="required">{{ wgLang.message( 'required-field' ) }}</label>
diff --git a/data/templates/apply.js b/data/templates/apply.js
new file mode 100644
index 0000000..14070c0
--- /dev/null
+++ b/data/templates/apply.js
@@ -0,0 +1,48 @@
+(function( $, document ) {
+    var timeout = 5 * 60 * 1000,
+        lastActive = 0,
+        refreshCsrf = function() {
+            return $.getJSON(
+                '{{ urlFor( "revalidatecsrf") }}',
+                function( data ) {
+                    var $token = $( '#token' );
+                    $token.val( data[ "{{ csrf_param }}" ] );
+                    console.log( 'csrf token: ' + $token.val() );
+                }
+            );
+        },
+        ping = setInterval(function() {
+            if ( new Date().getTime() - lastActive > timeout ) {
+                console.log( 'Killing keep-alive job due to inactivity' );
+                clearInterval( ping );
+            } else {
+                console.log( 'Refreshing csrf token' );
+                refreshCsrf();
+            }
+        }, timeout ),
+        debounce = function( func, wait ) {
+            // Adapted from http://davidwalsh.name/javascript-debounce-function
+            var timeout;
+            return function() {
+                var that = this,
+                    args = arguments,
+                    later = function() {
+                        timeout = null;
+                        func.apply( that, args );
+                    };
+                clearTimeout( timeout );
+                timeout = setTimeout( later, wait );
+            };
+        },
+        $document = $( document );
+
+    $document.keydown( debounce(
+        function() { lastActive = new Date().getTime(); },
+        1000
+    ) );
+    $document.mousemove( debounce(
+        function() { lastActive = new Date().getTime(); },
+        1000
+    ) );
+    // TODO: refresh token on form submit?
+})( jQuery, document );
diff --git a/data/templates/csrf.json b/data/templates/csrf.json
new file mode 100644
index 0000000..188c5ee
--- /dev/null
+++ b/data/templates/csrf.json
@@ -0,0 +1 @@
+{"{{  csrf_param|escape('js') }}": "{{ csrf_token|escape('js') }}"}
diff --git a/src/Wikimania/Scholarship/App.php 
b/src/Wikimania/Scholarship/App.php
index a8f2611..4db0517 100644
--- a/src/Wikimania/Scholarship/App.php
+++ b/src/Wikimania/Scholarship/App.php
@@ -323,6 +323,11 @@
                                $page();
                        })->name( 'apply_post' );
 
+                       $slim->get( 'apply/revalidatecsrf', function () use ( 
$slim ) {
+                               $page = new Controllers\RevalidateCsrf( $slim );
+                               $page();
+                       })->name( 'revalidatecsrf' );
+
                        App::template( $slim, 'contact' );
                        App::template( $slim, 'credits' );
                        App::template( $slim, 'privacy' );
diff --git a/src/Wikimania/Scholarship/Controllers/RevalidateCsrf.php 
b/src/Wikimania/Scholarship/Controllers/RevalidateCsrf.php
new file mode 100644
index 0000000..47f576f
--- /dev/null
+++ b/src/Wikimania/Scholarship/Controllers/RevalidateCsrf.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @section LICENSE
+ * This file is part of Wikimania Scholarship Application.
+ *
+ * Wikimania Scholarship Application is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Wikimania Scholarship Application is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Wikimania Scholarship Application.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * @file
+ */
+
+namespace Wikimania\Scholarship\Controllers;
+
+use Wikimania\Scholarship\Controller;
+use Wikimania\Scholarship\CsrfMiddleware;
+
+/**
+ * Routes related to authentication.
+ *
+ * @author Niharika Kohli <niharikakohl...@gmail.com>
+ * @copyright © 2013 Niharika Kohli and Wikimedia Foundation.
+ */
+class RevalidateCsrf extends Controller {
+
+       public function __construct( \Slim\Slim $slim = null ) {
+               parent::__construct( $slim );
+       }
+
+       protected function handleGet() {
+               // Touch the key in the session to make sure it is kept alive
+               $token = $_SESSION[CsrfMiddleware::PARAM];
+               $_SESSION[CsrfMiddleware::PARAM] = $token;
+               $this->response()->header(
+                       'Content-Type',
+                       'application/json;charset=utf-8'
+               );
+               $this->response()->header(
+                       'Cache-Control',
+                       'no-cache, no-store, must-revalidate'
+               );
+               $this->response()->header( 'Pragma', 'no-cache' );
+               $this->response()->header( 'Expires', '0' );
+               $this->render( 'csrf.json' );
+       }
+
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/179471
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I6babb68ddb77296afbd67947dbc7f79e611df882
Gerrit-PatchSet: 11
Gerrit-Project: wikimedia/wikimania-scholarships
Gerrit-Branch: master
Gerrit-Owner: Niharika29 <niharikakohl...@gmail.com>
Gerrit-Reviewer: Aude <aude.w...@gmail.com>
Gerrit-Reviewer: BryanDavis <bda...@wikimedia.org>
Gerrit-Reviewer: Chad <ch...@wikimedia.org>
Gerrit-Reviewer: Niharika29 <niharikakohl...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to