export host selection per service, RT#17914
[freeside.git] / FS / FS / part_export / broadband_sqlradius.pm
index dc117b0..b5d1a80 100644 (file)
@@ -1,7 +1,7 @@
 package FS::part_export::broadband_sqlradius;
 
 use strict;
-use vars qw($DEBUG @ISA %options %info $conf);
+use vars qw($DEBUG @ISA @pw_set %options %info $conf);
 use Tie::IxHash;
 use FS::Conf;
 use FS::Record qw( dbh str2time_sql ); #qsearch qsearchs );
@@ -13,6 +13,8 @@ FS::UID->install_callback(sub { $conf = new FS::Conf });
 
 $DEBUG = 0;
 
+@pw_set = ( 'a'..'z', 'A'..'Z', '0'..'9', '(', ')', '#', '.', ',' );
+
 tie %options, 'Tie::IxHash',
   'datasrc'  => { label=>'DBI data source ' },
   'username' => { label=>'Database username' },
@@ -26,6 +28,11 @@ tie %options, 'Tie::IxHash',
 #    type  => 'checkbox',
 #    label => 'Hide IP address on session reports',
 #  },
+  'mac_case' => {
+    label => 'Export MAC address as',
+    type  => 'select',
+    options => [ qw(uppercase lowercase) ],
+  },
   'mac_delimiter' => {
     label => 'Separate MAC address octets with',
     default => '-',
@@ -48,6 +55,7 @@ tie %options, 'Tie::IxHash',
   'svc'      => 'svc_broadband',
   'desc'     => 'Real-time export to SQL-backed RADIUS (such as FreeRadius) for broadband services',
   'options'  => \%options,
+  'no_machine' => 1,
   'nas'      => 'Y',
   'notes'    => <<END,
 Real-time export of <b>radcheck</b>, <b>radreply</b>, and <b>usergroup</b> 
@@ -73,8 +81,9 @@ sub rebless { shift; }
 
 sub export_username {
   my($self, $svc_broadband) = (shift, shift);
-  my $mac_addr = $svc_broadband->mac_addr;
-  join( ($self->option('mac_delimiter',1) || ''), $mac_addr =~ /../g );
+  $svc_broadband->mac_addr_formatted(
+    $self->option('mac_case'), $self->option('mac_delimiter')
+  );
 }
 
 sub radius_reply {
@@ -92,9 +101,7 @@ sub radius_check {
   my $password_attrib = $conf->config('radius-password') || 'Password';
   my %check;
   if ( $self->option('mac_as_password') ) {
-    my $mac_addr = $svc_broadband->mac_addr;
-    $check{$password_attrib} =
-      join( ($self->option('mac_delimiter',1) || ''), $mac_addr =~ /../g );
+    $check{$password_attrib} = $self->export_username($svc_broadband);
   }
   elsif ( length( $self->option('radius_password',1)) ) {
     $check{$password_attrib} = $self->option('radius_password');
@@ -102,8 +109,65 @@ sub radius_check {
   %check;
 }
 
-sub _export_suspend {}
-sub _export_unsuspend {}
+sub radius_check_suspended {
+  my($self, $svc_broadband) = (shift, shift);
+
+  return () unless $self->option('mac_as_password')
+                || length( $self->option('radius_password',1));
+
+  my $password_attrib = $conf->config('radius-password') || 'Password';
+  (
+    $password_attrib => join('',map($pw_set[ int(rand $#pw_set) ], (0..7) ) )
+  );
+}
+
+#false laziness w/sqlradius.pm
+sub _export_suspend {
+  my( $self, $svc_broadband ) = (shift, shift);
+
+  local $SIG{HUP} = 'IGNORE';
+  local $SIG{INT} = 'IGNORE';
+  local $SIG{QUIT} = 'IGNORE';
+  local $SIG{TERM} = 'IGNORE';
+  local $SIG{TSTP} = 'IGNORE';
+  local $SIG{PIPE} = 'IGNORE';
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  my @newgroups = $self->suspended_usergroups($svc_broadband);
+
+  unless (@newgroups) { #don't change password if assigning to a suspended group
+
+    my $err_or_queue = $self->sqlradius_queue(
+       $svc_broadband->svcnum, 'insert',
+      'check', $self->export_username($svc_broadband),
+      $self->radius_check_suspended($svc_broadband)
+    );
+    unless ( ref($err_or_queue) ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $err_or_queue;
+    }
+
+  }
+
+  my $error =
+    $self->sqlreplace_usergroups(
+      $svc_broadband->svcnum,
+      $self->export_username($svc_broadband),
+      '',
+      [ $svc_broadband->radius_groups('hashref') ],
+      \@newgroups,
+    );
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+  '';
+}
 
 sub update_svc {} #do nothing