diff --git a/src/opnsense/mvc/app/controllers/OPNsense/CaptivePortal/Api/VoucherController.php b/src/opnsense/mvc/app/controllers/OPNsense/CaptivePortal/Api/VoucherController.php index de88c9707..a1557cad4 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/CaptivePortal/Api/VoucherController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/CaptivePortal/Api/VoucherController.php @@ -138,13 +138,14 @@ class VoucherController extends ApiControllerBase if ($auth != null && method_exists($auth, 'generateVouchers')) { $count = $this->request->getPost('count', 'int', 0); $validity = $this->request->getPost('validity', 'int', 0); + $expirytime = $this->request->getPost('expirytime', 'int', 0); $vouchergroup = $this->request->getPost('vouchergroup', 'striptags', '---'); // remove characters which are known to provide issues when using in the url foreach (array("&", "#") as $skip_chars) { $vouchergroup = str_replace($skip_chars, "", $vouchergroup); } if ($count > 0 && $count <= 10000 && $validity > 0) { - return $auth->generateVouchers($vouchergroup, $count, $validity); + return $auth->generateVouchers($vouchergroup, $count, $validity, $expirytime); } } } diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php b/src/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php index d59b4b0e6..f2b71d59f 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/Voucher.php @@ -105,6 +105,8 @@ class Voucher extends Base implements IAuthConnector , vouchergroup varchar2 -- group of vouchers , validity integer -- voucher credits , starttime integer -- voucher start at + , expirytime integer -- voucher valid until - '0' = disabled + , vouchertype varchar2 -- (not implemented) voucher type , primary key (username) ); @@ -177,9 +179,10 @@ class Voucher extends Base implements IAuthConnector * @param int $count number of vouchers to generate * @param int $validity time (in seconds) * @param int $starttime valid from + * @param int $expirytime valid until ('0' means no expiry time) * @return array list of generated vouchers */ - public function generateVouchers($vouchergroup, $count, $validity, $starttime = null) + public function generateVouchers($vouchergroup, $count, $validity, $expirytime, $starttime = null) { $response = array(); if ($this->dbHandle != null) { @@ -220,6 +223,7 @@ class Voucher extends Base implements IAuthConnector // generate new vouchers $vouchersGenerated = 0; + $expirytime = $expirytime == 0 ? 0 : $expirytime + time(); while ($vouchersGenerated < $count) { $generatedUsername = ''; $random_bytes = openssl_random_pseudo_bytes($this->usernameLength); @@ -237,13 +241,14 @@ class Voucher extends Base implements IAuthConnector // save user, hash password first $generatedPasswordHash = crypt($generatedPassword, '$6$'); $stmt = $this->dbHandle->prepare(' - insert into vouchers(username, password, vouchergroup, validity, starttime) - values (:username, :password, :vouchergroup, :validity, :starttime) + insert into vouchers(username, password, vouchergroup, validity, expirytime, starttime) + values (:username, :password, :vouchergroup, :validity, :expirytime, :starttime) '); $stmt->bindParam(':username', $generatedUsername); $stmt->bindParam(':password', $generatedPasswordHash); $stmt->bindParam(':vouchergroup', $vouchergroup); $stmt->bindParam(':validity', $validity); + $stmt->bindParam(':expirytime', $expirytime); $stmt->bindParam(':starttime', $starttime); $stmt->execute(); @@ -251,6 +256,7 @@ class Voucher extends Base implements IAuthConnector 'password' => $generatedPassword, 'vouchergroup' => $vouchergroup, 'validity' => $validity, + 'expirytime' => $expirytime, 'starttime' => $starttime ); $response[] = $row; @@ -299,7 +305,7 @@ class Voucher extends Base implements IAuthConnector { $response = array(); $stmt = $this->dbHandle->prepare(' - select username, validity, starttime, vouchergroup + select username, validity, expirytime, starttime, vouchergroup from vouchers where vouchergroup = :vouchergroup'); $stmt->bindParam(':vouchergroup', $vouchergroup); @@ -308,13 +314,14 @@ class Voucher extends Base implements IAuthConnector $record = array(); $record['username'] = $row['username']; $record['validity'] = $row['validity']; + $record['expirytime'] = $row['expirytime']; # always calculate a starttime, if not registered yet, use now. $record['starttime'] = empty($row['starttime']) ? time() : $row['starttime']; $record['endtime'] = $record['starttime'] + $row['validity']; - if (empty($row['starttime'])) { + if (empty($row['starttime']) && ($record['expirytime'] == 0|| ($record['expirytime'] > 0 && time() < $record['expirytime']))) { $record['state'] = 'unused'; - } elseif (time() < $record['endtime']) { + } elseif (time() < $record['endtime'] && ($record['expirytime'] == 0 || ($record['expirytime'] > 0 && time() < $record['expirytime']))) { $record['state'] = 'valid'; } else { $record['state'] = 'expired'; @@ -356,8 +363,8 @@ class Voucher extends Base implements IAuthConnector delete from vouchers where vouchergroup = :vouchergroup - and starttime is not null - and starttime + validity < :endtime + and ((starttime is not null) or (expirytime > 0)) + and (starttime + validity < :endtime or (expirytime > 0 and expirytime < :endtime)) '); $stmt->bindParam(':vouchergroup', $vouchergroup); $endtime = time(); @@ -385,7 +392,7 @@ class Voucher extends Base implements IAuthConnector public function authenticate($username, $password) { $stmt = $this->dbHandle->prepare(' - select username, password,validity, starttime + select username, password,validity, expirytime, starttime from vouchers where username = :username '); @@ -402,8 +409,10 @@ class Voucher extends Base implements IAuthConnector $this->setStartTime($username, $row['starttime']); } if (time() - $row['starttime'] < $row['validity']) { - $this->lastAuthProperties['session_timeout'] = $row['validity'] - (time() - $row['starttime']); - return true; + if($row['expirytime'] == 0 || ($row['expirytime'] > 0 && $row['expirytime'] > time())) { + $this->lastAuthProperties['session_timeout'] = $row['validity'] - (time() - $row['starttime']); + return true; + } } } } diff --git a/src/opnsense/mvc/app/views/OPNsense/CaptivePortal/vouchers.volt b/src/opnsense/mvc/app/views/OPNsense/CaptivePortal/vouchers.volt index 9a765c8b3..07dc4252c 100644 --- a/src/opnsense/mvc/app/views/OPNsense/CaptivePortal/vouchers.volt +++ b/src/opnsense/mvc/app/views/OPNsense/CaptivePortal/vouchers.volt @@ -110,7 +110,7 @@ POSSIBILITY OF SUCH DAMAGE. if (status == "success") { $("#grid-vouchers > tbody").html(''); $.each(data, function (key, value) { - var fields = ["username", "starttime", "endtime", "state"]; + var fields = ["username", "starttime", "endtime", "expirytime", "state"]; tr_str = ''; for (var i = 0; i < fields.length; i++) { if (value[fields[i]] != null) { @@ -178,12 +178,13 @@ POSSIBILITY OF SUCH DAMAGE. $('#generatevouchererror').hide(); var voucher_provider = $('#voucher-providers').find("option:selected").val(); var voucher_validity = $("#voucher-validity").val(); + var voucher_expirytime = $("#voucher-expiry").val(); var voucher_quantity = $("#voucher-quantity").val(); var voucher_groupname = $("#voucher-groupname").val(); - if (!$.isNumeric(voucher_validity) || !$.isNumeric(voucher_quantity)) { - // don't try to generate vouchers then validity or quantity are invalid + if (!$.isNumeric(voucher_validity) || !$.isNumeric(voucher_quantity) || !$.isNumeric(voucher_expirytime)) { + // don't try to generate vouchers when validity, expirytime or quantity are invalid var error = $('

'); - error.text("{{ lang._('The validity and the quantity of vouchers must be integers.') }}"); + error.text("{{ lang._('The validity, expiry time and the quantity of vouchers must be integers.') }}"); $('#generatevouchererror').append(error); $('#generatevouchererror').show(); return; @@ -192,14 +193,16 @@ POSSIBILITY OF SUCH DAMAGE. sendData={ 'count':voucher_quantity, 'validity':voucher_validity, - 'vouchergroup': voucher_groupname + 'expirytime':voucher_expirytime, + 'vouchergroup':voucher_groupname }, callback=function(data,status){ // convert json to csv data - var output_data = 'username,password,vouchergroup,validity\n'; + var output_data = 'username,password,vouchergroup,expirytime,validity\n'; $.each(data, function( key, value ) { output_data = output_data.concat('"', value['username'], '",'); output_data = output_data.concat('"', value['password'], '",'); output_data = output_data.concat('"', value['vouchergroup'], '",'); + output_data = output_data.concat('"', value['expirytime'], '",'); output_data = output_data.concat('"', value['validity'], '"\n'); }); @@ -216,7 +219,13 @@ POSSIBILITY OF SUCH DAMAGE. .appendTo('body'); $('#downloadFile').ready(function() { - $('#downloadFile').get(0).click(); + if ( window.navigator.msSaveOrOpenBlob && window.Blob ) { + var blob = new Blob( [ output_data ], { type: "text/csv" } ); + navigator.msSaveOrOpenBlob( blob, voucher_groupname.toLowerCase() + '.csv' ); + } + else { + $('#downloadFile').get(0).click(); + } }); $("#generateVouchers").modal('hide'); @@ -304,6 +313,16 @@ POSSIBILITY OF SUCH DAMAGE. $("#voucher-validity-custom-data").keyup(function(){ $("#voucher-validity-custom").val($(this).val()*60); }); + $("#voucher-expiry").change(function(){ + if ($(this).children(":selected").attr("id") == 'voucher-expiry-custom') { + $("#voucher-expiry-custom-data").show(); + } else { + $("#voucher-expiry-custom-data").hide(); + } + }); + $("#voucher-expiry-custom-data").keyup(function(){ + $("#voucher-expiry-custom").val($(this).val()*3600); + }); $("#voucher-quantity").change(function(){ if ($(this).children(":selected").attr("id") == 'voucher-quantity-custom') { @@ -343,6 +362,7 @@ POSSIBILITY OF SUCH DAMAGE. {{ lang._('Voucher') }} {{ lang._('Valid from') }} {{ lang._('Valid to') }} + {{ lang._('Expires at') }} {{ lang._('State') }} @@ -392,15 +412,9 @@ POSSIBILITY OF SUCH DAMAGE.