- move cyrus, shellcommands, CP exports exports to new-style
authorivan <ivan>
Sun, 14 Apr 2002 09:11:22 +0000 (09:11 +0000)
committerivan <ivan>
Sun, 14 Apr 2002 09:11:22 +0000 (09:11 +0000)
- skeleton files for vpopmail exports
- documentation updates
- add big schema diagram to docs

19 files changed:
FS/FS/Conf.pm
FS/FS/part_export.pm
FS/FS/part_export/cp.pm
FS/FS/part_export/cyrus.pm [new file with mode: 0644]
FS/FS/part_export/infostreet.pm
FS/FS/part_export/shellcommands.pm [new file with mode: 0644]
FS/FS/part_export/vpopmail.pm [new file with mode: 0644]
FS/FS/svc_acct.pm
FS/MANIFEST
FS/t/part_export-cp.t [new file with mode: 0644]
FS/t/part_export-cyrus.t [new file with mode: 0644]
FS/t/part_export-shellcommands.t [new file with mode: 0644]
FS/t/part_export-vpopmail.t [new file with mode: 0644]
eg/export_template.pm
httemplate/docs/billing.html
httemplate/docs/legacy.html
httemplate/docs/schema.dia [new file with mode: 0644]
httemplate/docs/schema.html
httemplate/docs/schema.png [new file with mode: 0644]

index b029132..d16dd94 100644 (file)
@@ -298,8 +298,8 @@ httemplate/docs/config.html
 
   {
     'key'         => 'cyrus',
-    'section'     => 'mail',
-    'description' => 'Integration with <a href="http://asg.web.cmu.edu/cyrus/imapd/">Cyrus IMAP Server</a>, three lines: IMAP server, admin username, and admin password.  Cyrus::IMAP::Admin should be installed locally and the connection to the server secured.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>cyrus</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to integrate with <a href="http://asg.web.cmu.edu/cyrus/imapd/">Cyrus IMAP Server</a>, three lines: IMAP server, admin username, and admin password.  Cyrus::IMAP::Admin should be installed locally and the connection to the server secured.',
     'type'        => 'textarea',
   },
 
@@ -604,29 +604,29 @@ httemplate/docs/config.html
 
   {
     'key'         => 'shellmachine',
-    'section'     => 'shell',
-    'description' => 'A single machine with user home directories mounted.  This enables home directory creation, renaming and archiving/deletion.  In conjunction with `qmailmachines\', it also enables `.qmail-extension\' file maintenance.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>cp</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to contain a single machine with user home directories mounted.  This enables home directory creation, renaming and archiving/deletion.  In conjunction with `qmailmachines\', it also enables `.qmail-extension\' file maintenance.',
     'type'        => 'text',
   },
 
   {
     'key'         => 'shellmachine-useradd',
-    'section'     => 'shell',
-    'description' => 'The command(s) to run on shellmachine when an account is created.  If the <b>shellmachine</b> option is set but this option is not, <code>useradd -d $dir -m -s $shell -u $uid $username</code> is the default.  If this option is set but empty, <code>cp -pr /etc/skel $dir; chown -R $uid.$gid $dir</code> is the default instead.  Otherwise the value is evaluated as a double-quoted perl string, with the following variables available: <code>$username</code>, <code>$uid</code>, <code>$gid</code>, <code>$dir</code>, and <code>$shell</code>.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>cp</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to contain command(s) to run on shellmachine when an account is created.  If the <b>shellmachine</b> option is set but this option is not, <code>useradd -d $dir -m -s $shell -u $uid $username</code> is the default.  If this option is set but empty, <code>cp -pr /etc/skel $dir; chown -R $uid.$gid $dir</code> is the default instead.  Otherwise the value is evaluated as a double-quoted perl string, with the following variables available: <code>$username</code>, <code>$uid</code>, <code>$gid</code>, <code>$dir</code>, and <code>$shell</code>.',
     'type'        => [qw( checkbox text )],
   },
 
   {
     'key'         => 'shellmachine-userdel',
-    'section'     => 'shell',
-    'description' => 'The command(s) to run on shellmachine when an account is deleted.  If the <b>shellmachine</b> option is set but this option is not, <code>userdel $username</code> is the default.  If this option is set but empty, <code>rm -rf $dir</code> is the default instead.  Otherwise the value is evaluated as a double-quoted perl string, with the following variables available: <code>$username</code> and <code>$dir</code>.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>cp</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to contain command(s) to run on shellmachine when an account is deleted.  If the <b>shellmachine</b> option is set but this option is not, <code>userdel $username</code> is the default.  If this option is set but empty, <code>rm -rf $dir</code> is the default instead.  Otherwise the value is evaluated as a double-quoted perl string, with the following variables available: <code>$username</code> and <code>$dir</code>.',
     'type'        => [qw( checkbox text )],
   },
 
   {
     'key'         => 'shellmachine-usermod',
-    'section'     => 'shell',
-    'description' => 'The command(s) to run on shellmachine when an account is modified.  If the <b>shellmachine</b> option is set but this option is empty, <code>[ -d $old_dir ] &amp;&amp; mv $old_dir $new_dir || ( chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; find . -depth -print | cpio -pdm $new_dir; chmod u-t $new_dir; chown -R $uid.$gid $new_dir; rm -rf $old_dir )</code> is the default.  Otherwise the contents of the file are treated as a double-quoted perl string, with the following variables available: <code>$old_dir</code>, <code>$new_dir</code>, <code>$uid</code> and <code>$gid</code>.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>cp</i> <a href="../browse/part_export.cgi">export</a> instead.  This option used to contain command(s) to run on shellmachine when an account is modified.  If the <b>shellmachine</b> option is set but this option is empty, <code>[ -d $old_dir ] &amp;&amp; mv $old_dir $new_dir || ( chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; find . -depth -print | cpio -pdm $new_dir; chmod u-t $new_dir; chown -R $uid.$gid $new_dir; rm -rf $old_dir )</code> is the default.  Otherwise the contents of the file are treated as a double-quoted perl string, with the following variables available: <code>$old_dir</code>, <code>$new_dir</code>, <code>$uid</code> and <code>$gid</code>.',
     #'type'        => [qw( checkbox text )],
     'type'        => 'text',
   },
index 7ae00f0..82503c4 100644 (file)
@@ -489,14 +489,37 @@ sub exporttype2svcdb {
 #        'Batch export of /etc/global/passwd and /etc/global/shadow for NIS ',
 #      'options' => {},
 #    },
-    'bsdshell' => {
-      'desc' =>
-        'Batch export of /etc/passwd and /etc/master.passwd files (BSD)',
-      'options' => {},
-    },
     'textradius' => {
       'desc' => 'Batch export of a text /etc/raddb/users file (Livingston, Cistron)',
     },
+
+    'shellcommands' => {
+      'desc' => 'Real-time export via arbitrary commands on a remote machine (i.e. useradd, userdel, etc.)',
+      'options' => {
+        'machine' => { label=>'Remote machine' },
+        'user' => { label=>'Remote username', default=>'root' },
+        'useradd' => { label=>'Insert command',
+                       default=>'useradd -d $dir -m -s $shell -u $uid $username'
+                      #default=>'cp -pr /etc/skel $dir; chown -R $uid.$gid $dir'
+                     },
+        'userdel' => { label=>'Delete command',
+                       default=>'userdel $username',
+                       #default=>'rm -rf $dir',
+                     },
+        'usermod' => { label=>'Modify command',
+                       default=>'usermod -d $new_dir -l $new_username -s $new_shell -u $new_uid $old_username',
+                      #default=>'[ -d $old_dir ] && mv $old_dir $new_dir || ( '.
+                       #  'chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; '.
+                       #  'find . -depth -print | cpio -pdm $new_dir; '.
+                       #  'chmod u-t $new_dir; chown -R $uid.$gid $new_dir; '.
+                       #  'rm -rf $old_dir'.
+                       #')'
+                     },
+      },
+      'nodomain' => 'Y',
+      'notes' => 'shellcommandsnotes... (this one is the nodomain one)',
+    },
+
     'sqlradius' => {
       'desc' => 'Real-time export to SQL-backed RADIUS (ICRADIUS, FreeRADIUS)',
       'options' => {
@@ -507,9 +530,18 @@ sub exporttype2svcdb {
       'nodomain' => 'Y',
       'notes' => 'Real-time export of radcheck, radreply and usergroup tables to any SQL database for <a href="http://www.freeradius.org/">FreeRADIUS</a> or <a href="http://radius.innercite.com/">ICRADIUS</a>.  Use <a href="../docs/man/bin/freeside-sqlradius-reset">freeside-sqlradius-reset</a> to delete and repopulate the tables from the Freeside database.',
     },
+
     'cyrus' => {
       'desc' => 'Real-time export to Cyrus IMAP server',
+      'options' => {
+        'server' => { label=>'IMAP server' },
+        'username' => { label=>'Admin username' },
+        'password' => { label=>'Admin password' },
+      },
+      'nodomain' => 'Y',
+      'notes' => 'Integration with <a href="http://asg.web.cmu.edu/cyrus/imapd/">Cyrus IMAP Server</a>.  Cyrus::IMAP::Admin should be installed locally and the connection to the server secured.  <B>svc_acct.quota</B> is used to set the Cyrus quota if available. '
     },
+
     'cp' => {
       'desc' => 'Real-time export to Critical Path Account Provisioning Protocol',
       'options' => {
@@ -522,6 +554,7 @@ sub exporttype2svcdb {
       },
       'notes' => 'Real-time export to <a href="http://www.cp.net/">Critial Path Account Provisioning Protocol</a>.  Requires installation of <a href="http://search.cpan.org/search?dist=Net-APP">Net::APP</a> from CPAN.',
     },
+    
     'infostreet' => {
       'desc' => 'Real-time export to InfoStreet streetSmartAPI',
       'options' => {
@@ -532,7 +565,8 @@ sub exporttype2svcdb {
       },
       'nodomain' => 'Y',
       'notes' => 'Real-time export to <a href="http://www.infostreet.com/">InfoStreet</a> streetSmartAPI.  Requires installation of <a href="http://search.cpan.org/search?dist=Frontier-Client">Frontier::Client</a> from CPAN.',
-    }
+    },
+
   },
 
   'svc_domain' => {},
index 58ac85e..d998c1d 100644 (file)
@@ -69,22 +69,17 @@ sub cp_command { #subroutine, not method
       );
     }
 
+    my $other = 'F';
     if ( $new_password =~ /^\*SUSPENDED\* (.*)$/ ) {
       $new_password = $1;
-      cp_command($host, $port, $username, $password, 'set_mailbox_status',
-        Domain       => $domain,
-        Mailbox      => $new_username,
-        Other        => 'T',
-        Other_Bounce => 'T',
-      );
-    } else {
-      cp_command($host, $port, $username, $password, 'set_mailbox_status',
-        Domain       => $domain,
-        Mailbox      => $new_username,
-        Other        => 'F',
-        Other_Bounce => 'F',
-      );
+      $other = 'T';
     }
+    cp_command($host, $port, $username, $password, 'set_mailbox_status',
+      Domain       => $domain,
+      Mailbox      => $new_username,
+      Other        => $other,
+      Other_Bounce => $other,
+    );
 
     if ( $old_password ne $new_password ) {
       cp_command($host, $port, $username, $password, 'change_mailbox',
diff --git a/FS/FS/part_export/cyrus.pm b/FS/FS/part_export/cyrus.pm
new file mode 100644 (file)
index 0000000..110ff19
--- /dev/null
@@ -0,0 +1,98 @@
+package FS::part_export::cyrus;
+
+use vars qw(@ISA);
+use FS::part_export;
+
+@ISA = qw(FS::part_export);
+
+sub rebless { shift; }
+
+sub _export_insert {
+  my($self, $svc_acct) = (shift, shift);
+  $self->cyrus_queue( $svc_acct->svcnum, 'insert',
+    $svc_acct->username, $svc_acct->quota );
+}
+
+sub _export_replace {
+  my( $self, $new, $old ) = (shift, shift, shift);
+  return "can't change username using Cyrus"
+    if $old->username ne $new->username;
+  return '';
+#  #return '' unless $old->_password ne $new->_password;
+#  $self->cyrus_queue( $new->svcnum,
+#    'replace', $new->username, $new->_password );
+}
+
+sub _export_delete {
+  my( $self, $svc_acct ) = (shift, shift);
+  $self->cyrus_queue( $svc_acct->svcnum, 'delete',
+    $svc_acct->username );
+}
+
+#a good idea to queue anything that could fail or take any time
+sub cyrus_queue {
+  my( $self, $svcnum, $method ) = (shift, shift, shift);
+  my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+    'job'    => "FS::part_export::cyrus::cyrus_$method",
+  };
+  $queue->insert(
+    $self->option('server'),
+    $self->option('username'),
+    $self->option('password'),
+    @_
+  );
+}
+
+sub cyrus_insert { #subroutine, not method
+  my $client = cyrus_connect(shift, shift, shift);
+  my( $username, $quota ) = @_;
+  my $rc = $client->create("user.$username");
+  my $error = $client->error;
+  die "creating user.$username: $error" if $error;
+
+  $rc = $client->setacl("user.$username", $username => 'all' );
+  $error = $client->error;
+  die "setacl user.$username: $error" if $error;
+
+  if ( $quota ) {
+    $rc = $client->setquota("user.$username", 'STORAGE' => $quota );
+    $error = $client->error;
+    die "setquota user.$username: $error" if $error;
+  }
+
+}
+
+sub cyrus_delete { #subroutine, not method
+  my ( $server, $admin_username, $password_username, $username ) = @_;
+  my $client = cyrus_connect($server, $admin_username, $password_username);
+
+  my $rc = $client->setacl("user.$username", $admin_username => 'all' );
+  my $error = $client->error;
+  die $error if $error;
+
+  $rc = $client->delete("user.$username");
+  $error = $client->error;
+  die $error if $error;
+}
+
+sub cyrus_connect {
+
+  my( $server, $admin_username, $admin_password ) = @_;
+
+  eval "use Cyrus::IMAP::Admin;";
+
+  my $client = Cyrus::IMAP::Admin->new($server);
+  $client->authenticate(
+    -user      => $admin_username,
+    -mechanism => "login",       
+    -password  => $admin_password,
+  );
+  $client;
+
+}
+
+#sub cyrus_replace { #subroutine, not method
+#}
+
+
index c2386ad..e86e82a 100644 (file)
@@ -10,7 +10,7 @@ sub rebless { shift; }
 sub _export_insert {
   my( $self, $svc_acct ) = (shift, shift);
   $self->infostreet_queue( $svc_acct->svcnum,
-    'createUser', $svc_acct->username, $svc_acct->password );
+    'createUser', $svc_acct->username, $svc_acct->_password );
 }
 
 sub _export_replace {
@@ -19,7 +19,7 @@ sub _export_replace {
     if $old->username ne $new->username;
   return '' unless $old->_password ne $new->_password;
   $self->infostreet_queue( $new->svcnum,
-    'passwd', $new->username, $new->password );
+    'passwd', $new->username, $new->_password );
 }
 
 sub _export_delete {
diff --git a/FS/FS/part_export/shellcommands.pm b/FS/FS/part_export/shellcommands.pm
new file mode 100644 (file)
index 0000000..e99c382
--- /dev/null
@@ -0,0 +1,59 @@
+package FS::part_export::shellcommands;
+
+use vars qw(@ISA);
+use FS::part_export;
+
+@ISA = qw(FS::part_export);
+
+sub rebless { shift; }
+
+sub _export_insert {
+  my($self) = shift;
+  $self->_export_command($self, 'useradd', @_);
+}
+
+sub _export_delete {
+  my($self) = shift;
+  $self->_export_command($self, 'userdel', @_);
+}
+
+sub _export_command {
+  my ( $self, $action, $svc_acct) = (shift, shift, shift);
+  my $command = $self->option($action);
+  no strict 'refs';
+  ${$_} = $svc_acct->getfield($_) foreach $svc_acct->fields;
+  $self->shellcommands_queue(
+    $self->options('user')||'root'. "\@". $self->options('machine'),
+    eval(qq("$command"))
+  );
+}
+
+sub _export_replace {
+  my($self, $new, $old ) = (shift, shift, shift);
+  my $command = $self->option('usermod');
+  no strict 'refs';
+  ${"old_$_"} = $old->getfield($_) foreach $old->fields;
+  ${"new_$_"} = $new->getfield($_) foreach $new->fields;
+  $self->shellcommands_queue(
+    $self->options('user')||'root'. "\@". $self->options('machine'),
+    eval(qq("$command"))
+  );
+}
+
+#a good idea to queue anything that could fail or take any time
+sub shellcommands_queue {
+  my( $self, $svcnum ) = (shift, shift);
+  my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+    'job'    => "Net::SSH::ssh_cmd", #freeside-queued pre-uses...
+  };
+  $queue->insert( @_ );
+}
+
+#sub shellcommands_insert { #subroutine, not method
+#}
+#sub shellcommands_replace { #subroutine, not method
+#}
+#sub shellcommands_delete { #subroutine, not method
+#}
+
diff --git a/FS/FS/part_export/vpopmail.pm b/FS/FS/part_export/vpopmail.pm
new file mode 100644 (file)
index 0000000..7a59f32
--- /dev/null
@@ -0,0 +1,47 @@
+package FS::part_export::myexport;
+
+use vars qw(@ISA);
+use FS::part_export;
+
+@ISA = qw(FS::part_export);
+
+sub rebless { shift; }
+
+sub _export_insert {
+  my($self, $svc_acct) = (shift, shift);
+  $self->myexport_queue( $svc_acct->svcnum, 'insert',
+    $svc_acct->username, $svc_acct->_password );
+}
+
+sub _export_replace {
+  my( $self, $new, $old ) = (shift, shift, shift);
+  #return "can't change username with myexport"
+  #  if $old->username ne $new->username;
+  #return '' unless $old->_password ne $new->_password;
+  $self->myexport_queue( $new->svcnum,
+    'replace', $new->username, $new->_password );
+}
+
+sub _export_delete {
+  my( $self, $svc_acct ) = (shift, shift);
+  $self->myexport_queue( $svc_acct->svcnum,
+    'delete', $svc_acct->username );
+}
+
+#a good idea to queue anything that could fail or take any time
+sub myexport_queue {
+  my( $self, $svcnum, $method ) = (shift, shift, shift);
+  my $queue = new FS::queue {
+    'svcnum' => $svcnum,
+    'job'    => "FS::part_export::myexport::myexport_$method",
+  };
+  $queue->insert( @_ );
+}
+
+sub myexport_insert { #subroutine, not method
+}
+sub myexport_replace { #subroutine, not method
+}
+sub myexport_delete { #subroutine, not method
+}
+
index 1e1cbb0..ea11078 100644 (file)
@@ -6,8 +6,7 @@ use vars qw( @ISA $nossh_hack $noexport_hack $conf
              $usernamemax $passwordmin $passwordmax
              $username_ampersand $username_letter $username_letterfirst
              $username_noperiod $username_uppercase
-             $shellmachine $useradd $usermod $userdel $mydomain
-             $cyrus_server $cyrus_admin_user $cyrus_admin_pass
+             $mydomain
              $dirhash
              @saltset @pw_set
              $rsync $ssh $exportdir $vpopdir);
@@ -38,47 +37,16 @@ $FS::UID::callback{'FS::svc_acct'} = sub {
   $conf = new FS::Conf;
   $dir_prefix = $conf->config('home');
   @shells = $conf->config('shells');
-  $shellmachine = $conf->config('shellmachine');
   $usernamemin = $conf->config('usernamemin') || 2;
   $usernamemax = $conf->config('usernamemax');
   $passwordmin = $conf->config('passwordmin') || 6;
   $passwordmax = $conf->config('passwordmax') || 8;
-  if ( $shellmachine ) {
-    if ( $conf->exists('shellmachine-useradd') ) {
-      $useradd = join("\n", $conf->config('shellmachine-useradd') )
-                 || 'cp -pr /etc/skel $dir; chown -R $uid.$gid $dir';
-    } else {
-      $useradd = 'useradd -d $dir -m -s $shell -u $uid $username';
-    }
-    if ( $conf->exists('shellmachine-userdel') ) {
-      $userdel = join("\n", $conf->config('shellmachine-userdel') )
-                 || 'rm -rf $dir';
-    } else {
-      $userdel = 'userdel $username';
-    }
-    $usermod = join("\n", $conf->config('shellmachine-usermod') )
-               || '[ -d $old_dir ] && mv $old_dir $new_dir || ( '.
-                    'chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; '.
-                    'find . -depth -print | cpio -pdm $new_dir; '.
-                    'chmod u-t $new_dir; chown -R $uid.$gid $new_dir; '.
-                    'rm -rf $old_dir'.
-                  ')';
-  }
   $username_letter = $conf->exists('username-letter');
   $username_letterfirst = $conf->exists('username-letterfirst');
   $username_noperiod = $conf->exists('username-noperiod');
   $username_uppercase = $conf->exists('username-uppercase');
   $username_ampersand = $conf->exists('username-ampersand');
   $mydomain = $conf->config('domain');
-  if ( $conf->exists('cyrus') ) {
-    ($cyrus_server, $cyrus_admin_user, $cyrus_admin_pass) =
-      $conf->config('cyrus');
-    eval "use Cyrus::IMAP::Admin;"
-  } else {
-    $cyrus_server = '';
-    $cyrus_admin_user = '';
-    $cyrus_admin_pass = '';
-  }
 
   $dirhash = $conf->config('dirhash') || 0;
   $exportdir = "/usr/local/etc/freeside/export." . datasrc;
@@ -94,8 +62,6 @@ $FS::UID::callback{'FS::svc_acct'} = sub {
 @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
 @pw_set = ( 'a'..'z', 'A'..'Z', '0'..'9', '(', ')', '#', '!', '.', ',' );
 
-#not needed in 5.004 #srand($$|time);
-
 sub _cache {
   my $self = shift;
   my ( $hashref, $cache ) = @_;
@@ -228,7 +194,7 @@ is the default instead.  Otherwise the contents of the file are treated as
 a double-quoted perl string, with the following variables available:
 $username, $uid, $gid, $dir, and $shell.
 
-(TODOC: cyrus config file, L<FS::queue> and L<freeside-queued>)
+(TODOC: L<FS::queue> and L<freeside-queued>)
 
 (TODOC: new exports! $noexport_hack)
 
@@ -309,37 +275,6 @@ sub insert {
 
   #old-style exports
 
-  my( $username, $uid, $gid, $dir, $shell ) = (
-    $self->username,
-    $self->uid,
-    $self->gid,
-    $self->dir,
-    $self->shell,
-  );
-  if ( $username && $uid && $dir && $shellmachine && ! $nossh_hack ) {
-    my $queue = new FS::queue {
-      'svcnum' => $self->svcnum,
-      'job' => 'Net::SSH::ssh_cmd',
-    };
-    $error = $queue->insert("root\@$shellmachine", eval qq("$useradd") );
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
-    }
-  }
-
-  if ( $cyrus_server ) {
-    my $queue = new FS::queue {
-      'svcnum' => $self->svcnum,
-      'job'    => 'FS::svc_acct::cyrus_insert',
-    };
-    $error = $queue->insert($self->username, $self->quota);
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
-    }
-  }
-
   if ( $vpopdir ) {
 
     my $vpopmail_queue =
@@ -365,41 +300,6 @@ sub insert {
   ''; #no error
 }
 
-sub cyrus_insert {
-  my( $username, $quota ) = @_;
-
-  warn "cyrus_insert: starting for user $username, quota $quota\n";
-
-  warn "cyrus_insert: connecting to $cyrus_server\n";
-  my $client = Cyrus::IMAP::Admin->new($cyrus_server);
-
-  warn "cyrus_insert: authentication as $cyrus_admin_user\n";
-  $client->authenticate(
-    -user      => $cyrus_admin_user,
-    -mechanism => "login",       
-    -password  => $cyrus_admin_pass
-  );
-
-  warn "cyrus_insert: creating user.$username\n";
-  my $rc = $client->create("user.$username");
-  my $error = $client->error;
-  die "cyrus_insert: error creating user.$username: $error" if $error;
-
-  warn "cyrus_insert: setacl user.$username, $username => all\n";
-  $rc = $client->setacl("user.$username", $username => 'all' );
-  $error = $client->error;
-  die "cyrus_insert: error setacl user.$username: $error" if $error;
-
-  if ( $quota ) {
-    warn "cyrus_insert: setquota user.$username, STORAGE => $quota\n";
-    $rc = $client->setquota("user.$username", 'STORAGE' => $quota );
-    $error = $client->error;
-    die "cyrus_insert: error setquota user.$username: $error" if $error;
-  }
-
-  1;
-}
-
 sub vpopmail_insert {
   my( $username, $password, $domain, $vpopdir ) = @_;
   
@@ -468,8 +368,6 @@ is the default instead.  Otherwise the contents of the file are treated as a
 double-quoted perl string, with the following variables available:
 $username and $dir.
 
-(TODOC: cyrus config file)
-
 (TODOC: new exports! $noexport_hack)
 
 =cut
@@ -566,29 +464,6 @@ sub delete {
 
   #old-style exports
 
-  my( $username, $dir ) = (
-    $self->username,
-    $self->dir,
-  );
-  if ( $username && $shellmachine && ! $nossh_hack ) {
-    my $queue = new FS::queue { 'job' => 'Net::SSH::ssh_cmd' };
-    $error = $queue->insert("root\@$shellmachine", eval qq("$userdel") );
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
-    }
-
-  }
-
-  if ( $cyrus_server ) {
-    my $queue = new FS::queue { 'job' => 'FS::svc_acct::cyrus_delete' };
-    $error = $queue->insert($self->username);
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
-    }
-  }
-  
   if ( $vpopdir ) {
     my $queue = new FS::queue { 'job' => 'FS::svc_acct::vpopmail_delete' };
     $error = $queue->insert( $self->username, $self->domain );
@@ -605,27 +480,6 @@ sub delete {
   '';
 }
 
-sub cyrus_delete {
-  my $username = shift; 
-
-  my $client = Cyrus::IMAP::Admin->new($cyrus_server);
-  $client->authenticate(
-    -user      => $cyrus_admin_user,
-    -mechanism => "login",       
-    -password  => $cyrus_admin_pass
-  );
-
-  my $rc = $client->setacl("user.$username", $cyrus_admin_user => 'all' );
-  my $error = $client->error;
-  die $error if $error;
-
-  $rc = $client->delete("user.$username");
-  $error = $client->error;
-  die $error if $error;
-
-  1;
-}
-
 sub vpopmail_delete {
   my( $username, $domain ) = @_;
   
@@ -649,7 +503,7 @@ sub vpopmail_delete {
   flock(VPASSWD,LOCK_UN);
   close(VPASSWD);
 
-  rmtree "$exportdir/domains/$domain/$username" or die "can't destroy Maildir";+ 
+  rmtree "$exportdir/domains/$domain/$username" or die "can't destroy Maildir"; 
   1;
 }
 
@@ -699,9 +553,6 @@ sub replace {
     return "Can't change uid!" if $old->uid != $new->uid;
   }
 
-  return "can't change username using Cyrus"
-    if $cyrus_server && $old->username ne $new->username;
-
   #change homdir when we change username
   $new->setfield('dir', '') if $old->username ne $new->username;
 
@@ -770,36 +621,6 @@ sub replace {
 
   #old-style exports
 
-  my ( $old_dir, $new_dir, $uid, $gid ) = (
-    $old->getfield('dir'),
-    $new->getfield('dir'),
-    $new->getfield('uid'),
-    $new->getfield('gid'),
-  );
-  if ( $old_dir && $new_dir && $old_dir ne $new_dir && ! $nossh_hack ) {
-    my $queue = new FS::queue { 
-      'svcnum' => $new->svcnum,
-      'job' => 'Net::SSH::ssh_cmd'
-    };
-    $error = $queue->insert("root\@$shellmachine", eval qq("$usermod") );
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
-    }
-  }
-
-  if ( $cp_server && $old->username ne $new->username ) {
-    my $queue = new FS::queue { 
-      'svcnum' => $new->svcnum,
-      'job' => 'FS::svc_acct::cp_rename'
-    };
-    $error = $queue->insert( $old->username, $new->username );
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "queueing job (transaction rolled back): $error";
-    }
-  }
-
   if ( $vpopdir ) {
     my $cpassword = crypt(
       $new->_password,$saltset[int(rand(64))].$saltset[int(rand(64))]
index 1c90dfc..86516e3 100644 (file)
@@ -51,6 +51,10 @@ FS/part_export.pm
 FS/part_export_option.pm
 FS/part_export/infostreet.pm
 FS/part_export/sqlradius.pm
+FS/part_export/cyrus.pm
+FS/part_export/cp.pm
+FS/part_export/shellcommands.pm
+FS/part_export/vpopmail.pm
 FS/part_pkg.pm
 FS/part_pop_local.pm
 FS/part_referral.pm
@@ -106,6 +110,10 @@ t/part_export.t
 t/part_export_option.t
 t/part_export-infostreet.t
 t/part_export-sqlradius.t
+t/part_export-cyrus.t
+t/part_export-cp.t
+t/part_export-shellcommands.t
+t/part_export-vpopmail.t
 t/part_pkg.t
 t/part_pop_local.t
 t/part_referral.t
diff --git a/FS/t/part_export-cp.t b/FS/t/part_export-cp.t
new file mode 100644 (file)
index 0000000..bbefa6c
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::cp;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/part_export-cyrus.t b/FS/t/part_export-cyrus.t
new file mode 100644 (file)
index 0000000..e0b3f35
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::cyrus;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/part_export-shellcommands.t b/FS/t/part_export-shellcommands.t
new file mode 100644 (file)
index 0000000..7bb47d3
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::shellcommands;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/part_export-vpopmail.t b/FS/t/part_export-vpopmail.t
new file mode 100644 (file)
index 0000000..2e37114
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::vpopmail;
+$loaded=1;
+print "ok 1\n";
index 11e1c3b..f2a5a19 100644 (file)
@@ -10,7 +10,7 @@ sub rebless { shift; }
 sub _export_insert {
   my($self, $svc_something) = (shift, shift);
   $self->myexport_queue( $svc_acct->svcnum, 'insert',
-    $svc_something->username, $svc_something->password );
+    $svc_something->username, $svc_something->_password );
 }
 
 sub _export_replace {
@@ -19,7 +19,7 @@ sub _export_replace {
   #  if $old->username ne $new->username;
   #return '' unless $old->_password ne $new->_password;
   $self->myexport_queue( $new->svcnum,
-    'replace', $new->username, $new->password );
+    'replace', $new->username, $new->_password );
 }
 
 sub _export_delete {
index 4a5642a..c6ef7a8 100644 (file)
@@ -18,7 +18,7 @@
             <li>$page - current page
             <li>$total_pages - total pages
             <li>@address - A six-element array containing the customer name, company, and address.
-            <li>$overdue - true if this invoice is overdue
+<!--            <li>$overdue - true if this invoice is overdue -->
           </ul>
       </ul>
     <li>Batch credit card processing
@@ -47,6 +47,6 @@ if ( $error ) {
 </pre>
 All fields except paybatch are contained in the cust_pay_batch table.  You can use paybatch field to track particular batches and/or particular transactions within a batch.
     </ul>
-      <li>The <a href="man/bin/freeside-print-batch.html"><b>freeside-print-batch</b></a> script can print or email pending credit card batches for manual entry.
+<!--      <li>The <a href="man/bin/freeside-print-batch.html"><b>freeside-print-batch</b></a> script can print or email pending credit card batches for manual entry. -->
   </ul>
 </body>
index 3ab21da..5f59bb8 100755 (executable)
@@ -3,6 +3,7 @@
 </head>
 <body>
   <h1>Importing legacy data</h1>
+<font size="+2">NOTE: This file is OUT OF DATE with the landing of the new export code.  Importing your legacy data will most probably involve some hacking on the example scripts noted below.  Contributions to the import process are welcome.</font>
 <ul>
   <li><a name="svc_acct">bin/svc_acct.import</a> - Import `passwd', ( `shadow' or `master.passwd' ) and RADIUS `users'.  Before running bin/svc_acct.import, you need <a href="../browse/part_svc.cgi">services</a> (with table svc_acct) as follows:
     <ul>
diff --git a/httemplate/docs/schema.dia b/httemplate/docs/schema.dia
new file mode 100644 (file)
index 0000000..4a54652
Binary files /dev/null and b/httemplate/docs/schema.dia differ
index 6ed96d2..07fcb90 100644 (file)
@@ -3,6 +3,7 @@
 </head>
 <body>
   <h1>Schema reference</h1>
+  Schema diagram: <a href="schema.png">as a giant .png</a> or <a href="schema.dia">dia source</a> (<a href="http://www.lysator.liu.se/~alla/dia/">dia homepage</a>).
   <ul>
     <li><a name="agent" href="man/FS/agent.html">agent</a> - Agents are resellers of your service.  Agents may be limited to a subset of your full offerings (via their agent type).
       <ul>
diff --git a/httemplate/docs/schema.png b/httemplate/docs/schema.png
new file mode 100644 (file)
index 0000000..b3f0037
Binary files /dev/null and b/httemplate/docs/schema.png differ