sudo cpanm Number::Bytes::Human;
sudo cpanm CGI::Session;
sudo cpanm TryCatch;
-sudo cpanm Number/Bytes/Human.pm
-sudo cpanm Regexp::Common
-
+sudo cpanm Number/Bytes/Human.pm;
+sudo cpanm Regexp::Common;
+sudo cpanm Crypt::CBC;
#Upgrade Instructions
#!/usr/bin/perl
-
+#
+# Programed in vim by: Will Budic
+# Open Source License -> https://choosealicense.com/licenses/isc/
+#
use strict;
use warnings;
use Try::Tiny;
use Switch;
use CGI;
+use CGI::Session '-ip_match';
use DBI;
use DateTime;
use DateTime::Duration;
use Text::CSV;
-my $driver = "SQLite";
-my $database = "../../dbLifeLog/data_log.db";
-my $dsn = "DBI:$driver:dbname=$database";
-my $userid = $ENV{'DB_USER'};
-my $password = $ENV{'DB_PASS'};
+#DEFAULT SETTINGS HERE!
+our $REC_LIMIT = 25;
+our $TIME_ZONE = 'Australia/Sydney';
+our $PRC_WIDTH = '60';
+#END OF DEFAULT SETTINGS
+
-my $db = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
- or die "<p>Error->"& $DBI::errstri &"</p>";
+my $q = CGI->new;
+my $session = new CGI::Session(undef, $q);
+my $dbname=$session->param('database');
+my $userid=$session->param('alias');
+my $password=$session->param('passw');
+
+### Authenticate session to alias password
+#
+if(!$userid || !$dbname){
+ print $q->redirect('login_ctr.cgi');
+ exit;
+}
+
+my $database = '../../dbLifeLog/'.$dbname;
+my $dsn= "DBI:SQLite:dbname=$database";
+my $db = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die "<p>Error->"& $DBI::errstri &"</p>";
-#DEFAULT SETTINGS HERE!
-my $REC_LIMIT = 25;
-my $TIME_ZONE = 'Australia/Sydney';
-#END OF
my $rv;
my $dbs;
my $today = DateTime->now;
$today->set_time_zone( $TIME_ZONE );
#####################
- &checkCreateTablesAndSettings;
+ &getConfiguration;
#####################
-my $q = CGI->new;
print $q->header(-expires=>"+6os", -charset=>"UTF-8");
}
-sub checkCreateTablesAndSettings{
-
-
-$dbs = $db->prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='LOG';");
- $dbs->execute();
-try{
- if(!$dbs->fetchrow_array()) {
- my $stmt = qq(
- CREATE TABLE LOG (
- ID_CAT TINY NOT NULL,
- DATE DATETIME NOT NULL,
- LOG VCHAR(128) NOT NULL,
- AMMOUNT integer
- );
- );
-
- $rv = $db->do($stmt);
-
- if($rv < 0) {
- print "<p>Error->"& $DBI::errstri &"</p>";
- }
+sub getConfiguration{
+ try{
+ $dbs = $db->prepare("SELECT * FROM CONFIG;");
+ $dbs->execute();
- $dbs = $db->prepare('INSERT INTO LOG VALUES (?,?,?,?)');
+ while (my @r=$dbs->fetchrow_array()){
+
+ switch ($r[1]) {
- $dbs->execute( 3, $today, "DB Created!",0);
+ case "REC_LIMIT" {$REC_LIMIT=$r[2]}
+ case "TIME_ZONE" {$TIME_ZONE=$r[2]}
+ case "PRC_WIDTH" {$PRC_WIDTH=$r[2]}
+ else {print "Unknow variable setting: ".$r[1]. " == ". $r[2]}
-
- }
-
- $dbs = $db->prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='CAT';");
- $dbs->execute();
- if(!$dbs->fetchrow_array()) {
- my $stmt = qq(
- CREATE TABLE CAT(
- ID TINY PRIMARY KEY NOT NULL,
- NAME VCHAR(16),
- DESCRIPTION VCHAR(64)
- );
- );
-
- $rv = $db->do($stmt);
-
- if($rv < 0) {
- print "<p>Error->"& $DBI::errstri &"</p>";
- }
-
- $dbs = $db->prepare('INSERT INTO CAT VALUES (?,?,?)');
-
- $dbs->execute(1,"Unspecified", "For quick uncategoriesed entries.");
- $dbs->execute(3,"File System", "Operating file system short log.");
- $dbs->execute(6,"System Log", "Operating system important log.");
- $dbs->execute(9,"Event", "Event that occured, meeting, historical important.");
- $dbs->execute(28,"Personal", "Personal log of historical importants, diary type.");
- $dbs->execute(32, "Expense", "Significant yearly expense.");
- $dbs->execute(35, "Income", "Significant yearly income.");
- $dbs->execute(40, "Work", "Work related entry, worth monitoring.");
- $dbs->execute(45, "Food", "Quick reference to recepies, observations.");
- }
-
- $dbs = $db->prepare("SELECT name FROM sqlite_master
- WHERE type='table' AND name='CONFIG';");
- $dbs->execute();
-
- if(!$dbs->fetchrow_array()) {
-
- my $stmt = qq(
-
- CREATE TABLE CONFIG(
- ID INT PRIMARY KEY NOT NULL,
- NAME VCHAR(16),
- VALUE VCHAR(64)
- );
-
- );
-
- $rv = $db->do($stmt);
-
- if($rv < 0) {
- print "<p>Error->"& $DBI::errstri &"</p>";
- }
-
- $dbs = $db->prepare('INSERT INTO CONFIG VALUES (?,?)');
- $dbs->execute("REC_LIMIT", "25");
- $dbs->execute("TIME_ZONE", "Australia/Sydney");
-
- }
-
- $dbs = $db->prepare("SELECT * FROM CONFIG;");
- $dbs->execute();
-
- while (my @r=$dbs->fetchrow_array()){
-
- switch ($r[1]) {
-
- case "REC_LIMIT" {$REC_LIMIT=$r[2]}
- case "TIME_ZONE" {$TIME_ZONE=$r[2]}
- else {print "Unknow variable setting: ".$r[1]. " == ". $r[2]}
+ }
}
-
}
-
-}
-catch{
- print "<font color=red><b>SERVER ERROR</b></font>:".$_;
-}
-
+ catch{
+ print "<font color=red><b>SERVER ERROR</b></font>:".$_;
+ }
}
#!/usr/bin/perl
-
+#
+# Programed in vim by: Will Budic
+# Open Source License -> https://choosealicense.com/licenses/isc/
+#
use strict;
use warnings;
-use Try::Tiny;
-use Switch;
-
+use Try::Tiny;
use CGI;
-use CGI::Session;
+use CGI::Session '-ip_match';
use DBI;
use DateTime;
use DateTime::Format::SQLite;
use DateTime::Duration;
use Text::CSV;
+use Crypt::CBC;
+use Crypt::IDEA;
-my $driver = "SQLite";
-my $database = "../../dbLifeLog/data_config_test_log.db";
-my $dsn = "DBI:$driver:dbname=$database";
-my $userid = $ENV{'DB_USER'};
-my $password = $ENV{'DB_PASS'};
+#DEFAULT SETTINGS HERE!
+our $REC_LIMIT = 25;
+our $TIME_ZONE = 'Australia/Sydney';
+our $PRC_WIDTH = '60';
+#END OF DEFAULT SETTINGS
+my $cgi = CGI->new;
+my $session = new CGI::Session(undef,$cgi);
+#dev session setting change to +1h, hard coded for now. - WB
+$session->expire('+2m');
+my $sid=$session->id();
+my $cookie = $cgi->cookie(CGISESSID => $sid);
-my $rv;
-my $dbs;
+my $alias = $cgi->param('alias');
+my $passw = $cgi->param('passw');
+if(!$alias){$alias=""};
+if(!$passw){$passw=""}
+#This is the OS developer release key and cipher, replace on istallation. As it is not secure.
+my $cipher_key = '95d7a85ba891da896d0d87aca6d742d5';
+my $cipher = new Crypt::CBC({key => $cipher_key, cipher => 'IDEA'});
-my $q = CGI->new;
-
-print $q->header(-expires=>"+6os", -charset=>"UTF-8");
-print $q->start_html(-title => "Personal Log",
- -script=>{-type => 'text/javascript', -src => 'wsrc/main.js'},
- -style =>{-type => 'text/css', -src => 'wsrc/main.css'},
- );
+
+if(&processSubmit){
+
+}else{
+
+print $cgi->header(-expires=>"+6os", -charset=>"UTF-8", -cookie=>$cookie);
+print $cgi->start_html(-title => "Personal Log Login",
+ -script=>{-type => 'text/javascript', -src => 'wsrc/main.js'},
+ -style =>{-type => 'text/css', -src => 'wsrc/main.css'},
+ );
my $frm = qq(
- <form id="frm_login" action="login_ctr.cgi"><table>
+ <form id="frm_login" action="login_ctr.cgi"><table border="0" width="$PRC_WIDTH%">
<tr class="r0">
<td colspan="3"><center>LOGIN</center></td>
</tr>
- <tr class="r1">
- <td>Alias:</td><td><input type="text" name="alias"/></td><td></td>
+ <tr class="r1" style="border-left:1px solid black; border-right:1px solid black;">
+ <td align="right">Alias:</td><td><input type="text" name="alias" value="$alias"/></td><td></td>
</tr>
- <tr class="r1">
- <td>Password:</td><td><input type="text" name="password"/></td><td></td>
+ <tr class="r1" style="border-left:1px solid black; border-right:1px solid black;">
+ <td align="right">Password:</td><td><input type="text" name="passw" value="$passw"/></td><td></td>
</tr>
<tr class="r1">
- <td colspan="3"><font color="red">NOTICE!</font> If here the first time? Write down your alias and password, before proceeding. So you can comeback in the future to continue. Only you can know it.
-<input type="hidden" name="login" value="1"/></td></tr></table></form>);
+ <td colspan="3" style="border-left:1px solid black; border-right:1px solid black;"><font color="red">NOTICE!</font> If here the first time? Write down your alias and password, before proceeding. So you can comeback in the future to continue. Only you can know it.
+ <input type="hidden" name="CGISESSID" value="$sid"/>
+ <input type="hidden" name="login" value="1"/></td></tr>
+ <tr class="r0"><td colspan="2"></td><td><input type="submit" value="Login"/></td></tr>
+</table></form>);
print "<center>";
print "\n<div>\n" . $frm ."\n</div>\n<br/>";
print "</center>";
+}
-print $q->end_html;
+print $cgi->end_html;
exit;
+sub processSubmit{
+ if($alias&&$passw){
+ $passw = $cipher->encrypt_hex($passw);
+ &checkCreateTables;
+ $session = CGI::Session->load();
+ $session->param('alias', $alias);
+ $session->param('passw', $passw);
+ $session->param('database', 'data_'.$alias.'_log.db');
+ $session->param('cipher', $cipher_key);
+ $session->save_param($cgi);
+ print $cgi->redirect('main.cgi');
+
+ return 1;
+ }
+return 0;
+}
+
+sub checkCreateTables{
+try{
+ my $today = DateTime->now;
+ $today->set_time_zone( $TIME_ZONE );
+ my $database = '../../dbLifeLog/'.'data_'.$alias.'_log.db';
+ my $dsn= "DBI:SQLite:dbname=$database";
+ my $db = DBI->connect($dsn, $alias, $passw, { RaiseError => 1 })
+ or die "<p>Error->"& $DBI::errstri &"</p>";
+ my $rv;
+ my $st = $db->prepare(selSQLTbl('LOG'));
+ $st->execute();
+
+ if(!$st->fetchrow_array()) {
+ my $stmt = qq(
+ CREATE TABLE LOG (
+ ID_CAT TINY NOT NULL,
+ DATE DATETIME NOT NULL,
+ LOG VCHAR(128) NOT NULL,
+ AMMOUNT integer
+ );
+ );
+ $rv = $db->do($stmt);
+ if($rv < 0){print "<p>Error->"& $DBI::errstri &"</p>";}
+
+ $st = $db->prepare('INSERT INTO LOG VALUES (?,?,?,?)');
+ $st->execute( 3, $today, "DB Created!",0);
+ }
+ $st = $db->prepare(selSQLTbl('CAT'));
+ $st->execute();
+ if(!$st->fetchrow_array()) {
+ my $stmt = qq(
+ CREATE TABLE CAT(
+ ID TINY PRIMARY KEY NOT NULL,
+ NAME VCHAR(16),
+ DESCRIPTION VCHAR(64)
+ );
+ );
+ $rv = $db->do($stmt);
+
+ $st = $db->prepare('INSERT INTO CAT VALUES (?,?,?)');
+ $st->execute(1,"Unspecified", "For quick uncategories entries.");
+ $st->execute(3,"File System", "Operating file system short log.");
+ $st->execute(6,"System Log", "Operating system inportant log.");
+ $st->execute(9,"Event", "Event that occured, meeting, historical important.");
+ $st->execute(28,"Personal", "Personal log of historical importants, diary type.");
+ $st->execute(32, "Expense", "Significant yearly expense.");
+ $st->execute(35, "Income", "Significant yearly income.");
+ $st->execute(40, "Work", "Work related entry, worth monitoring.");
+ $st->execute(45, "Food", "Quick reference to recepies, observations.");
+ }
+ $st = $db->prepare(selSQLTbl('AUTH'));
+ $st->execute();
+ if(!$st->fetchrow_array()) {
+ my $stmt = qq(
+ CREATE TABLE AUTH(
+ alias TEXT PRIMARY KEY,
+ passw TEXT
+ ) WITHOUT ROWID;
+ );
+ $rv = $db->do($stmt);
+ if($rv < 0){print "<p>Error->"& $DBI::errstri &"</p>"};
+
+ }
+
+ $st = $db->prepare("SELECT * FROM AUTH WHERE alias='$alias' AND passw='$passw';");
+ $st->execute();
+ if(!$st->fetchrow_array()) {
+ $st = $db->prepare('INSERT INTO AUTH VALUES (?,?)');
+ $st->execute($alias, $passw);
+ }
+
+ $st = $db->prepare(selSQLTbl('CONFIG'));
+ $st->execute();
+ if(!$st->fetchrow_array()) {
+ my $stmt = qq(
+ CREATE TABLE CONFIG(
+ ID INT PRIMARY KEY NOT NULL,
+ NAME VCHAR(16),
+ VALUE VCHAR(64)
+ );
+ );
+ $rv = $db->do($stmt);
+
+ $st = $db->prepare('INSERT INTO CONFIG VALUES (?,?)');
+ $st->execute("REC_LIMIT", $REC_LIMIT);
+ $st->execute("TIME_ZONE", $TIME_ZONE);
+ $st->execute("PRC_WIDTH", $PRC_WIDTH);
+ }
+}
+ catch{
+ print "<font color=red><b>SERVER ERROR</b></font>:".$_;
+ }
+}
+
+sub selSQLTbl{
+ my $name = @_;
+return "SELECT name FROM sqlite_master WHERE type='table' AND name='$name';"
+}
+
### CGI END
use strict;
use warnings;
use Try::Tiny;
+use Switch;
use CGI;
+use CGI::Session '-ip_match';
use DBI;
use DateTime;
use DateTime::Format::SQLite;
use DateTime::Duration;
use Regexp::Common qw /URI/;
+use Crypt::CBC;
+use Crypt::IDEA;
-my $driver = "SQLite";
-my $database = "../../dbLifeLog/data_log.db";
-my $dsn = "DBI:$driver:dbname=$database";
-my $userid = $ENV{'DB_USER'};
-my $password = $ENV{'DB_PASS'};
-my $db = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
- or die "<p>Error->"& $DBI::errstri &"</p>";
+my $q = CGI->new;
+my $session = new CGI::Session(undef, $q);
+my $sid=$session->id();
+my $dbname=$session->param('database');
+my $userid=$session->param('alias');
+my $password=$session->param('passw');
+my $cphr=$session->param('cipher');
+
+
+### Authenticate session to alias password
+#
+if(!$userid || !$dbname){
+ print $q->redirect('login_ctr.cgi');
+ exit;
+}
+# "../../dbLifeLog/data_log.db";
+#my $database = "/home/will/dev/LifeLog/dbLifeLog/data_log.db";
+my $cipher = new Crypt::CBC({key => $cphr, cipher => 'IDEA'});
+my $database = '../../dbLifeLog/'.$dbname;
+my $dsn= "DBI:SQLite:dbname=$database";
+my $db = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die "<p>Error->"& $DBI::errstri &"</p>";
our $TIME_ZONE = 'Australia/Sydney';
our $PRC_WIDTH = '60';
#END OF SETTINGS
+&getConfiguration($db);
-my $q = CGI->new;
my $tbl_rc = 0;
my $tbl_rc_prev = 0;
my $tbl_cur_id;
my $toggle =""; if($rs_keys||$rs_cat_idx||$stmD){$toggle=1;};
-print $q->header(-expires=>"+6os", -charset=>"UTF-8");
-
+print $q->header(-expires=>"+6os", -charset=>"UTF-8");
print $q->start_html(-title => "Personal Log",
- -script=>{-type => 'text/javascript',-src => 'wsrc/main.js'},
- -style =>{-type => 'text/css', -src => 'wsrc/main.css'},
- -onload => "loadedBody('".$toggle."');"
+ -script=>{-type => 'text/javascript',-src => 'wsrc/main.js'},
+ -style =>{-type => 'text/css', -src => 'wsrc/main.css'},
+ -onload => "loadedBody('".$toggle."');"
);
+#print $q->div("session->".$session->header());
+#print $q->div("user:".$userid." passw:".$password);
my $rv;
my $st;
my $today = DateTime->now;
$today->set_time_zone( $TIME_ZONE );
-#####################
- &checkCreateTables;
-#####################
my $stmtCat = "SELECT * FROM CAT;";
-my $stmt = "SELECT rowid, ID_CAT, DATE, LOG, AMMOUNT FROM LOG ORDER BY DATE DESC, rowid DESC;";
+my $stmt = "SELECT rowid, ID_CAT, DATE, LOG, AMMOUNT FROM LOG ORDER BY rowid DESC, DATE DESC;";
$st = $db->prepare( $stmtCat );
<td><input type="submit" value="Search"/></form></td></tr>
</table>';
- my $frm = qq(<a name="top"></a>
+ my $frm = qq(<a name="top"></a>
<form id="frm_entry" action="main.cgi" onSubmit="return formValidation();">
<table class="tbl" border="0" width="$PRC_WIDTH%">
<tr class="r0"><td colspan="3"><b>* LOG ENTRY FORM *</b></td></tr>
</tr>
<tr><td>Log:</td>
<td id="al"><textarea id="el" name="log" rows="2" cols="60"></textarea></td>
- <td>Category: ).$cats.qq(</td></tr>
+ <td>Category: $cats</td></tr>
<tr><td><a href="#bottom">↡</a> Ammount:</td>
<td id="al">
<input id="am" name="am" type="number" step="any">
<input type="hidden" name="submit_is_view" id="submit_is_view" value="0"/>
<input type="hidden" name="rs_all" value="0"/>
<input type="hidden" name="rs_cur" value="0"/>
- <input type="hidden" name="rs_prev" value=").$tbl_rc_prev.q("/> </form>
+ <input type="hidden" name="rs_prev" value="$tbl_rc_prev"/>
+ <input type="hidden" name="CGISESSID" value="$sid"/>
+ </form>
);
);
$cats =~ s/selected//g;
-$srh .= '<tr><td align="right"><b>View by Category:</b></td><td>'.$cats.'</td><td></td>
+$srh .= qq(<tr><td align="right"><b>View by Category:</b></td><td>.$cats.</td><td></td>
<td colspan="1" align="left">
<button id="btn_cat" onclick="viewByCategory(this);" style="float:left">View</button>
<input id="idx_cat" name="category" type="hidden" value="0"></td></tr>
</tr>
<tr><td align="right"><b>Keywords:</b></td>
<td colspan="2" align="left">
- <input id="rs_keys" name="keywords" type="text" size="60" value="'.$rs_keys.'"/></td>
- <td align="left"><input type="submit" value="Search" align="left"></td></tr>';
+ <input id="rs_keys" name="keywords" type="text" size="60" value="$rs_keys"/></td>
+ <td align="left"><input type="submit" value="Search" align="left"></td></tr>);
if($rs_keys || $rs_cat_idx || $stmD){
$srh .= '<tr><td align="left" colspan="3">
print $q->end_html;
$st->finish;
$db->disconnect();
+$session->flush();
exit;
### CGI END
$tfId = 1;
}
- $tbl .= '<tr class="r'.$tfId.'"><td></td>';
+ $tbl .= qq!<tr class="r$tfId"><td></td>!;
if($rs_prev && $rs_prev>0 && $tbl_start>0){
- $tbl = $tbl . '<td><input type="hidden" value="'.$rs_prev.'"/>
- <input type="button" onclick="submitPrev('.$rs_prev.');return false;"
- value="‹‹– Previous"/></td>';
+ $tbl = $tbl . qq!<td><input type="hidden" value="$rs_prev"/>
+ <input type="button" onclick="submitPrev($rs_prev);return false;"
+ value="‹‹– Previous"/></td>!;
}
else{
- $tbl = $tbl .'<td><i>Top</i></td>';
+ $tbl .= '<td><i>Top</i></td>';
}
- $tbl = $tbl .'<td colspan="1"><input type="button" onclick="viewAll();return false;"
- value="View All"/></td>';
+ $tbl .= '<td colspan="1"><input type="button" onclick="viewAll();return false;" value="View All"/></td>';
if($is_end_of_rs == 1){
$tbl = $tbl .'<td><i>End</i></td>';
}
else{
- $tbl = $tbl . '<td><input type="button" onclick="submitNext('.$tbl_cur_id.');return false;"
- value="Next –››"/></td>';
+ $tbl .= qq!<td><input type="button" onclick="submitNext($tbl_cur_id);return false;"
+ value="Next –››"/></td>!;
}
$tbl = $tbl .'<td colspan="2"></td></tr>';
}
-sub checkCreateTables(){
-
- $st = $db->prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='LOG';");
- $st->execute();
-
- if(!$st->fetchrow_array()) {
- my $stmt = qq(
-
- CREATE TABLE LOG (
- ID_CAT TINY NOT NULL,
- DATE DATETIME NOT NULL,
- LOG VCHAR(128) NOT NULL,
- AMMOUNT integer
- );
-
- );
+sub getConfiguration{
+ my $st = $_[0]->prepare("SELECT * FROM CONFIG;");
+ $st->execute();
+ while (my @r=$st->fetchrow_array()){
+
+ switch ($r[1]) {
- $rv = $db->do($stmt);
+ case "REC_LIMIT" {$REC_LIMIT=$r[2]}
+ case "TIME_ZONE" {$TIME_ZONE=$r[2]}
+ case "PRC_WIDTH" {$PRC_WIDTH=$r[2]}
+ else {print "Unknow variable setting: ".$r[1]. " == ". $r[2]}
- if($rv < 0) {
- print "<p>Error->"& $DBI::errstri &"</p>";
- }
-
- $st = $db->prepare('INSERT INTO LOG VALUES (?,?,?,?)');
-
- $st->execute( 3, $today, "DB Created!",0);
-
-
- }
-
- $st = $db->prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='CAT';");
- $st->execute();
- if(!$st->fetchrow_array()) {
- my $stmt = qq(
-
- CREATE TABLE CAT(
- ID INT PRIMARY KEY NOT NULL,
- NAME VCHAR(16),
- DESCRIPTION VCHAR(64)
- );
-
- );
-
- $rv = $db->do($stmt);
-
- if($rv < 0) {
- print "<p>Error->"& $DBI::errstri &"</p>";
- }
-
- $st = $db->prepare('INSERT INTO CAT VALUES (?,?,?)');
-
- $st->execute(1,"Unspecified", "For quick uncategories entries.");
- $st->execute(3,"File System", "Operating file system short log.");
- $st->execute(6,"System Log", "Operating system inportant log.");
- $st->execute(9,"Event", "Event that occured, meeting, historical important.");
- $st->execute(28,"Personal", "Personal log of historical importants, diary type.");
- $st->execute(32, "Expense", "Significant yearly expense.");
- $st->execute(35, "Income", "Significant yearly income.");
- $st->execute(40, "Work", "Work related entry, worth monitoring.");
- $st->execute(45, "Food", "Quick reference to recepies, observations.");
- }
+ }
+ }
}
+
+sub authenticate{
+ return 0;
+}
\ No newline at end of file