diff --git a/portal.cfg b/portal.cfg index e88bb26..a51b34c 100644 --- a/portal.cfg +++ b/portal.cfg @@ -8,8 +8,9 @@ debug=True redis_host=127.0.0.1 redis_port=6379 -plugin_ttl=120 +plugin_timeout=180 +# Can specify an alternate webpage for the portal index_page=portalindex [logging] diff --git a/portal.py b/portal.py index 7d7764b..5735d19 100644 --- a/portal.py +++ b/portal.py @@ -1,7 +1,7 @@ # Captiveportal web application using Bottle.py import json -from pprint import pprint +from pprint import pprint as pp from uuid import UUID from importlib import import_module @@ -128,12 +128,17 @@ def dispatch_plugins(): )) continue + # Let plugin run for 30 more seconds than the defined plugin_timeout + # because that value is also used by the JS code to poll the job + # status so we don't want rq to kill the job before JS has timed out. + plugin_timeout = config.getint('portal', 'plugin_timeout')+30 + # Run plugin.run() try: plugin_job = Q.enqueue( plugin_module.run, arg, - ttl=config.getint('portal', 'plugin_ttl') + timeout=plugin_timeout ) except Exception as e: l.warn('{plugin}: {error}'.format( @@ -166,7 +171,7 @@ app.router.add_filter('uuid', uuid_filter) def portalindex(): return template( config.get('portal', 'index_page'), - plugin_ttl=config.get('portal', 'plugin_ttl') + plugin_timeout=config.getint('portal', 'plugin_timeout') ) @@ -203,6 +208,7 @@ def job_status(job_id): 'meta': job.meta } + return json.dumps(job_data) diff --git a/static/css/captiveportal.css b/static/css/captiveportal.css index 86bde0e..d0286cd 100644 --- a/static/css/captiveportal.css +++ b/static/css/captiveportal.css @@ -18,3 +18,7 @@ color: #D8000C; background-color: #FFBABA; } + +#error-box { + display:none; +} diff --git a/static/js/captiveportal.js b/static/js/captiveportal.js index d31b729..9e72f02 100644 --- a/static/js/captiveportal.js +++ b/static/js/captiveportal.js @@ -1,11 +1,10 @@ // Captive portal Javascript -// by Stefan Midjich -// +// by Stefan Midjich @ Cygate AB // var debug = true; -var getUrlParameter = function getUrlParameter(sParam) { +function getUrlParameter(sParam, default_value) { var sPageURL = decodeURIComponent(window.location.search.substring(1)), sURLVariables = sPageURL.split('&'), sParameterName, @@ -18,12 +17,15 @@ var getUrlParameter = function getUrlParameter(sParam) { return sParameterName[1] === undefined ? true : sParameterName[1]; } } -}; + + return default_value; +} + // This function ensures the user gets redirect to the correct destination once // all jobs have succeeded in the portal software. function do_success() { - var url = getUrlParameter('url'); + var url = getUrlParameter('url', 'www.google.com'); // If url does not start with http the window.location redirect // won't work. So prefix http to url. @@ -31,24 +33,30 @@ function do_success() { url = 'http://'+url; } console.log('success: '+url); + $('#error-box').html('

If you\'re not automatically redirected open your browser and try any website manually.

'); + $('#error-box').show(); + $('#statusDiv').html(''); + $('#approveButton').prop('disabled', false); - // Do something like refresh the window or go to another URL. + // Redirect user to the url paramter. window.location = url; } + // Show an error to the user function do_error(message) { - console.log('failure: '+message); $('#approveButton').prop('disabled', false); + $('#statusDiv').html(''); $('#error-box').show(); - $('#form-row').hide(); - $('#error-box').append('

Failed. Reload page and try again or contact support.

'); + $('#error-box').html('

Failed. Reload page and try again or contact support.

'); if (message) { + console.log('server: '+message); $('#error-box').append('

System response: '+message+'

'); } } + // Poll the returned jobs and ensure they all succeed function poll_jobs(data) { var promises = []; @@ -67,7 +75,7 @@ function poll_jobs(data) { } promises.push(new Promise(function(resolve, reject) { - var maxRun = plugin_ttl/2; + var maxRun = plugin_timeout/2; var timesRun = 0; // Timer function that polls the API for job results @@ -83,14 +91,14 @@ function poll_jobs(data) { console.log(job_result); if(job_result.is_finished) { - console.log('Resolving job: ', job_result.id); + console.log('Resolving job: ', job_result); resolve(job_result); clearTimeout(timer); return(true); } if(job_result.is_failed) { - console.log('Job failed: ', job_result.id); + console.log('Job failed: ', job_result); reject(job_result); clearTimeout(timer); return(false); @@ -117,48 +125,46 @@ function poll_jobs(data) { } // Run .all() on promises array until all promises resolve + // This is resolve() above. Promise.all(promises).then(function(result) { var success = true; for(var i=0;i'); - // Had some issues trying to set a background image on the button, so I'm - // just replacing it. if ($('#approveCheckbox').is(':checked')) { - $('#approveButton').prop('disabled', true); - //$('#approveButton').val(''); - $('#approveButton').addClass('button-loading'); - - //$('#approveButtonDiv').replaceWith('Loading, please wait...'); var ajaxReq = $.post(api_url); ajaxReq.done(poll_jobs); diff --git a/views/portalindex.tpl b/views/portalindex.tpl index 01e0de7..db23bd5 100644 --- a/views/portalindex.tpl +++ b/views/portalindex.tpl @@ -54,6 +54,8 @@
+
+
@@ -64,7 +66,8 @@
@@ -73,7 +76,7 @@