session monitor
authorivan <ivan>
Tue, 7 Nov 2000 15:00:37 +0000 (15:00 +0000)
committerivan <ivan>
Tue, 7 Nov 2000 15:00:37 +0000 (15:00 +0000)
13 files changed:
FS/FS/Record.pm
FS/FS/nas.pm
FS/FS/session.pm
FS/MANIFEST
bin/fs-setup
fs_sesmon/FS-SessionClient/MANIFEST
fs_sesmon/FS-SessionClient/Makefile.PL
fs_sesmon/FS-SessionClient/SessionClient.pm
fs_sesmon/FS-SessionClient/bin/freeside-login [new file with mode: 0644]
fs_sesmon/FS-SessionClient/bin/freeside-logoff [new file with mode: 0644]
fs_sesmon/fs_session_server
htdocs/docs/index.html
htdocs/docs/schema.html

index b0bfb0b..59472c8 100644 (file)
@@ -731,10 +731,10 @@ Check/untaint ip addresses.  IPv4 only for now.
 
 sub ut_ip {
   my( $self, $field ) = @_;
-  $self->getfield($field) =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
+  $self->getfield($field) =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
     or return "Illegal (IP address) $field: ". $self->getfield($field);
-  for ( $1 $2 $3 $4 ) { return "Illegal (IP address) $field" if $_ > 255; };
-  $self->$setfield($field, "$1.$2.$3.$3");
+  for ( $1, $2, $3, $4 ) { return "Illegal (IP address) $field" if $_ > 255; }
+  $self->setfield($field, "$1.$2.$3.$3");
   '';
 }
 
@@ -895,7 +895,7 @@ sub hfields {
 
 =head1 VERSION
 
-$Id: Record.pm,v 1.8 2000-10-27 20:15:50 ivan Exp $
+$Id: Record.pm,v 1.9 2000-11-07 15:00:37 ivan Exp $
 
 =head1 BUGS
 
index 5ed95f9..873c9bc 100644 (file)
@@ -117,11 +117,21 @@ sub check {
     || $self->ut_numbern('last');
 }
 
+=sub heartbeat TIMESTAMP
+
+Updates the timestamp for this nas
+
+=cut
+
+sub heartbeat {
+  warn "warning: heartbeat unimplemented!"
+}
+
 =back
 
 =head1 VERSION
 
-$Id: nas.pm,v 1.1 2000-10-27 20:18:32 ivan Exp $
+$Id: nas.pm,v 1.2 2000-11-07 15:00:37 ivan Exp $
 
 =head1 BUGS
 
index 0d766bd..b85a582 100644 (file)
@@ -4,6 +4,8 @@ use strict;
 use vars qw( @ISA );
 use FS::Record qw( qsearchs );
 use FS::svc_acct;
+use FS::port;
+use FS::nas;
 
 @ISA = qw(FS::Record);
 
@@ -31,6 +33,8 @@ FS::session - Object methods for session records
 
   $error = $record->check;
 
+  $error = $record->nas_heartbeat($timestamp);
+
 =head1 DESCRIPTION
 
 An FS::session object represents an user login session.  FS::session inherits
@@ -57,7 +61,7 @@ from FS::Record.  The following fields are currently supported:
 
 =item new HASHREF
 
-Creates a new example.  To add the example to the database, see L<"insert">.
+Creates a new session.  To add the session to the database, see L<"insert">.
 
 Note that this stores the hash reference, not a distinct copy of the hash it
 points to.  You can ask the object for a copy with the I<hash> method.
@@ -95,6 +99,8 @@ sub insert {
   $error = $self->SUPER::insert;
   return $error if $error;
 
+  $self->nas_heartbeat($self->getfield('login'));
+
   #session-starting callback!
 
   '';
@@ -136,6 +142,8 @@ sub replace {
   $error = $self->SUPER::replace;
   return $error if $error;
 
+  $self->nas_heartbeat($self->getfield('logout'));
+
   #session-ending callback!
 
   '';
@@ -143,7 +151,7 @@ sub replace {
 
 =item check
 
-Checks all fields to make sure this is a valid example.  If there is
+Checks all fields to make sure this is a valid session.  If there is
 an error, returns the error, otherwise returns false.  Called by the insert
 and replace methods.
 
@@ -167,11 +175,24 @@ sub check {
   '';
 }
 
+=item nas_heartbeat
+
+Heartbeats the nas associated with this session (see L<FS::nas>).
+
+=cut
+
+sub nas_heartbeat {
+  my $self = shift;
+  my $port = qsearchs('port',{'portnum'=>$self->portnum});
+  my $nas = qsearchs('nas',{'nasnum'=>$port->nasnum});
+  $nas->heartbeat(shift);
+}
+
 =back
 
 =head1 VERSION
 
-$Id: session.pm,v 1.1 2000-10-27 20:18:32 ivan Exp $
+$Id: session.pm,v 1.2 2000-11-07 15:00:37 ivan Exp $
 
 =head1 BUGS
 
index e0b5b51..91d2e2f 100644 (file)
@@ -40,12 +40,16 @@ FS/svc_acct_pop.pm
 FS/svc_acct_sm.pm
 FS/svc_domain.pm
 FS/type_pkgs.pm
+FS/nas.pm
+FS/port.pm
+FS/session.pm
 MANIFEST
 MANIFEST.SKIP
 Makefile.PL
 test.pl
 README
 bin/freeside-bill
+bin/freeside-print-batch
 FS/domain_record.pm
 FS/prepay_credit.pm
 FS/svc_www.pm
index b0f4761..602dc72 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -Tw
 #
-# $Id: fs-setup,v 1.28 2000-10-30 10:47:26 ivan Exp $
+# $Id: fs-setup,v 1.29 2000-11-07 15:00:37 ivan Exp $
 #
 # ivan@sisd.com 97-nov-8,9
 #
 # fix radius attributes ivan@sisd.com 98-sep-27
 #
 # $Log: fs-setup,v $
-# Revision 1.28  2000-10-30 10:47:26  ivan
+# Revision 1.29  2000-11-07 15:00:37  ivan
+# session monitor
+#
+# Revision 1.28  2000/10/30 10:47:26  ivan
 # nas.last can't be defined NULL if indexed
 #
 # Revision 1.26  2000/07/06 08:57:27  ivan
@@ -751,9 +754,7 @@ sub tables_hash_hack {
         'nas',      'varchar', '',    $char_d,
         'nasip',    'varchar', '',    15,
         'nasfqdn',  'varchar', '',    $char_d,
-#        'last',     'timestamp', '', '',
-#change to above when move to DBIx::DBSchema!!!
-        'last',     'datetime', '', '',
+        'last',     @date_type,
       ],
       'primary_key' => 'nasnum',
       'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
@@ -765,11 +766,8 @@ sub tables_hash_hack {
         'sessionnum', 'int',       '',   '',
         'portnum',    'int',       '',   '',
         'svcnum',     'int',       '',   '',
-#        'login',      'timestamp', '',   '',
-#        'logout',     'timestamp', '',   '',
-#change to above when move to DBIx::DBSchema!!!
-        'login',      'datetime',  '',   '',
-        'logout',     'datetime',  NULL, '',
+        'login',      @date_type,
+        'logout',     @date_type,
       ],
       'primary_key' => 'sessionnum',
       'unique'      => [],
index 3ced1df..6da7b22 100644 (file)
@@ -7,3 +7,5 @@ test.pl
 fs_sessiond
 cgi/logon.cgi
 cgi/logoff.cgi
+bin/freeside-login
+bin/freeside-logoff
index 8dff176..1f59847 100644 (file)
@@ -4,7 +4,7 @@ use ExtUtils::MakeMaker;
 WriteMakefile(
     'NAME'          => 'FS::SessionClient',
     'VERSION_FROM'  => 'SessionClient.pm', # finds $VERSION
-    'EXE_FILES'     => [ 'fs_sessiond' ],
+    'EXE_FILES'     => [ qw(fs_sessiond freeside-login freeside-logoff) ],
     'INSTALLSCRIPT' => '/usr/local/sbin',
     'PERM_RWX'      => '750',
 );
index fd50e89..97332cb 100644 (file)
@@ -1,7 +1,7 @@
 package FS::SessionClient;
 
 use strict;
-use vars qw($VERSION @ISA @EXPORT_OK $fs_sessiond_socket);
+use vars qw($AUTOLOAD $VERSION @ISA @EXPORT_OK $fs_sessiond_socket);
 use Exporter;
 use Socket;
 use FileHandle;
@@ -10,7 +10,7 @@ use IO::Handle;
 $VERSION = '0.01';
 
 @ISA = qw( Exporter );
-@EXPORT_OK = qw( login logoff );
+@EXPORT_OK = qw( login logoff portnum );
 
 $fs_sessiond_socket = "/usr/local/freeside/fs_sessiond_socket";
 
@@ -104,7 +104,7 @@ sub AUTOLOAD {
 
 =head1 VERSION
 
-$Id: SessionClient.pm,v 1.1 2000-10-27 20:15:50 ivan Exp $
+$Id: SessionClient.pm,v 1.2 2000-11-07 15:00:37 ivan Exp $
 
 =head1 BUGS
 
diff --git a/fs_sesmon/FS-SessionClient/bin/freeside-login b/fs_sesmon/FS-SessionClient/bin/freeside-login
new file mode 100644 (file)
index 0000000..6ca4455
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -Tw
+
+#false-laziness hack w freeside-logoff
+
+use strict;
+use FS::SessionClient qw( login portnum );
+
+my $username = shift;
+
+my $portnum;
+if ( scalar(@ARGV) == 1 ) {
+  my $arg = shift;
+  if ( $arg =~ /^(\d+)$/ ) {
+    $portnum = $1;
+  } elsif ( $arg =~ /^([\d\.]+)$/ ) {
+    $portnum = portnum( { 'ip' => $1 } ) or die "unknown ip!"
+  } else {
+    &usage;
+  }
+} elsif ( scalar(@ARGV) == 2 ) {
+  $portnum = portnum( { 'nasnum' => shift, 'nasport' => shift } )
+    or die "unknown nasnum/nasport";
+} else {
+  &usage;
+}
+
+my $error = login ( {
+  'username' => $username,
+  'portnum'  => $portnum,
+} );
+
+warn $error if $error;
+
+sub usage {
+  die "Usage:\n\n  freeside-login username ( portnum | ip | nasnum nasport )";
+}
diff --git a/fs_sesmon/FS-SessionClient/bin/freeside-logoff b/fs_sesmon/FS-SessionClient/bin/freeside-logoff
new file mode 100644 (file)
index 0000000..f7b876b
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/perl -Tw
+
+#false-laziness hack w freeside-login
+
+use strict;
+use FS::SessionClient qw( logoff portnum );
+
+my $username = shift;
+
+my $portnum;
+if ( scalar(@ARGV) == 1 ) {
+  my $arg = shift;
+  if ( $arg =~ /^(\d+)$/ ) {
+    $portnum = $1;
+  } elsif ( $arg =~ /^([\d\.]+)$/ ) {
+    $portnum = portnum( { 'ip' => $1 } ) or die "unknown ip!"
+  } else {
+    &usage;
+  }
+} elsif ( scalar(@ARGV) == 2 ) {
+  $portnum = portnum( { 'nasnum' => shift, 'nasport' => shift } )
+    or die "unknown nasnum/nasport";
+} else {
+  &usage;
+}
+
+my $error = login ( {
+  'username' => $username,
+  'portnum'  => $portnum,
+} );
+
+warn $error if $error;
+
+sub usage {
+  die "Usage:\n\n  freeside-logoff username ( portnum | ip | nasnum nasport )";
+}
+
index be0a017..46e53d1 100644 (file)
@@ -12,6 +12,8 @@ use FS::Record qw( qsearch qsearchs );
 #use FS::cust_main_county;
 #use FS::cust_main;
 use FS::session;
+use FS::port;
+use FS::svc_acct;
 
 #require "configfile";
 $Debug = 1;
@@ -42,12 +44,70 @@ while (1) {
     }
 
     if ( $command eq 'login' ) {
-
+      $error = &login(\%hash);
+      print $writer "$error\n";
     } elsif ( $command eq 'logoff' ) {
-
+      $error = &logoff(\%hash);
+      print $writer "$error\n";
     } elsif ( $command eq 'portnum' ) {
-
+      if ( exists $hash{'ip'} ) {
+        $hash{'ip'} =~ /^([\d\.]+)$/ or $1='nomatch';
+        $port = qsearchs('port', { 'ip' => $1 } );
+      } else {
+        $hash{'nasnum'} =~ /^(\d+)$/ and my $nasnum = $1;
+        $hash{'nasport'} =~ /^(\d+)$/ and my $nasport = $1;
+        $port = qsearchs('port', { 'nasnum'=>$nasnum, 'nasport'=>$nasport } );
+      }
+      print $writer ( $port ? $port->portnum : '' ), "\n";
     } else {
       warn "$me WARNING: unrecognized command";
     }
+  }
+  #won't ever reach without code above to throw out of loop, but...
+  close $writer;
+  close $reader;
+  warn "connection to $machine lost!\n"
+  sleep 5;
+  warn "reconnecting...\n";
+}
+
+sub login {
+  my $href = shift;
+  $href->{'username'} =~ /^([a-z0-9_\-\.]+)$/ or return "Illegal username";
+  my $username = $1;
+  $svc_acct = qsearchs('svc_acct', { 'username' => $username } )
+    or return "Unknown user";
+  return "Incorrect password"
+    if defined($href->{'password'})
+       && $href->{'password'} ne $svc_acct->_password;
+  my $session = new FS::session {
+    'portnum' => $href->{'portnum'},
+    'svcnum'  => $svc_acct->svcnum,
+    'login'   => $href->{'login'},
+  };
+  $session->insert;
+}
+
+sub logout {
+  my $href = shift;
+  $href->{'username'} =~ /^([a-z0-9_\-\.]+)$/ or return "Illegal username";
+  my $username = $1;
+  $svc_acct = qsearchs('svc_acct', { 'username' => $username } )
+    or return "Unknown user";
+  return "Incorrect password"
+    if defined($href->{'password'})
+       && $href->{'password'} ne $svc_acct->_password;
+  my $session = qsearchs FS::session {
+    'portnum' => $href->{'portnum'},
+    'svcnum'  => $svc_acct->svcnum,
+    'logoff'  => '',
+  };
+  return "No currently open sessios found for that user/port!" unless $session;
+  my $nsession = new FS::session ( { $old->hash } );
+  $nsession->replace($session);
+}
+
+sub usage {
+  die "Usage:\n\n  fs_session_server user machine\n";
+}
 
index f4155c1..f5c43d0 100644 (file)
@@ -20,6 +20,7 @@
   <li><a href="export.html">File exporting and remote setup</a>
   <li><a href="passwd.html">fs_passwd</a>
   <li><a href="signup.html">Signup server</a>
+  <li><a href="session.html">Session monitor</a>
   <li><a href="billing.html">Billing</a>
   <li><a href="trouble.html">Troubleshooting</a>
   <li><a href="schema.html">Schema reference</a>
index 1ab0e7f..474a350 100644 (file)
         <li>pkgnum - <a href="#cust_pkg">package</a>
         <li>svcpart - <a href="#part_svc">Service definition</a>
       </ul>
+    <li><a name="nas">nas</a> - Network Access Server (terminal server)
+      <ul>
+        <li>nasnum - primary key
+        <li>nas - NAS name
+        <li>nasip - NAS ip address
+        <li>nasfqdn - NAS fully-qualified domain name
+        <li>last - timestamp indicating the last instant the NAS was in a known state (used by the session monitoring).
+      </ul>
     <li><a name="part_pkg">part_pkg</a> - Package definitions
       <ul>
         <li>pkgpart - primary key
         <li>svcpart - <a href="#part_svc">Service definition</a>
         <li>quantity - quantity of this service that this package includes
       </ul>
+    <li><a name="port">port</a> - individual port on a <a href="#nas">nas</a>
+      <ul>
+        <li>portnum - primary key
+        <li>ip - IP address of this port
+        <li>nasport - port number on the NAS
+        <li>nasnum - <a href="#nas">NAS</a>
+      </ul>
     <li><a name="prepay_credit">prepay_credit</a>
       <ul>
         <li>prepaynum - primary key
         <li>identifier - text or numeric string used to receive this credit
         <li>amount - amount of credit
       </ul>
+    <li><a name="session">session</a>
+      <ul>
+        <li>sessionnum - primary key
+        <li>portnum - <a href="#port">Port</a>
+        <li>svcnum - <a href="#svc_acct">Account</a>
+        <li>login - timestamp indicating the beginning of this user session.
+        <li>logout - timestamp indicating the end of this user session.  May be null, which indicates a currently open session.
+      </ul>
+
     <li><a name="svc_acct">svc_acct</a> - Accounts
       <ul>
         <li>svcnum - <a href="#cust_svc">primary key</a>