export host selection per service, RT#17914
[freeside.git] / FS / FS / part_export / cyrus.pm
1 package FS::part_export::cyrus;
2
3 use vars qw(@ISA %info);
4 use Tie::IxHash;
5 use FS::part_export;
6
7 @ISA = qw(FS::part_export);
8
9 tie my %options, 'Tie::IxHash',
10   'server'   => { label=>'IMAP server' },
11   'username' => { label=>'Admin username' },
12   'password' => { label=>'Admin password' },
13 ;
14
15 %info = ( 
16   'svc'      => 'svc_acct',
17   'desc'     => 'Real-time export to Cyrus IMAP server',
18   'options'  => \%options,
19   'nodomain' => 'Y',
20   'no_machine' => 1, #de facto... but "server" option should move to it
21   'default_svc_class' => 'Email',
22   'notes'    => <<'END'
23 Integration with
24 <a href="http://asg.web.cmu.edu/cyrus/imapd/">Cyrus IMAP Server</a>.
25 Cyrus::IMAP::Admin should be installed locally and the connection to the
26 server secured.  <B>svc_acct.quota</B>, if available, is used to set the
27 Cyrus quota.
28 END
29 );
30
31 sub rebless { shift; }
32
33 sub _export_insert {
34   my($self, $svc_acct) = (shift, shift);
35   $self->cyrus_queue( $svc_acct->svcnum, 'insert',
36     $svc_acct->username, $svc_acct->quota );
37 }
38
39 sub _export_replace {
40   my( $self, $new, $old ) = (shift, shift, shift);
41   return "can't change username using Cyrus"
42     if $old->username ne $new->username;
43   return '';
44 #  #return '' unless $old->_password ne $new->_password;
45 #  $self->cyrus_queue( $new->svcnum,
46 #    'replace', $new->username, $new->_password );
47 }
48
49 sub _export_delete {
50   my( $self, $svc_acct ) = (shift, shift);
51   $self->cyrus_queue( $svc_acct->svcnum, 'delete',
52     $svc_acct->username );
53 }
54
55 #a good idea to queue anything that could fail or take any time
56 sub cyrus_queue {
57   my( $self, $svcnum, $method ) = (shift, shift, shift);
58   my $queue = new FS::queue {
59     'svcnum' => $svcnum,
60     'job'    => "FS::part_export::cyrus::cyrus_$method",
61   };
62   $queue->insert(
63     $self->option('server'),
64     $self->option('username'),
65     $self->option('password'),
66     @_
67   );
68 }
69
70 sub cyrus_insert { #subroutine, not method
71   my $client = cyrus_connect(shift, shift, shift);
72   my( $username, $quota ) = @_;
73   my $rc = $client->create("user.$username");
74   my $error = $client->error;
75   die "creating user.$username: $error" if $error;
76
77   $rc = $client->setacl("user.$username", $username => 'all' );
78   $error = $client->error;
79   die "setacl user.$username: $error" if $error;
80
81   if ( $quota ) {
82     $rc = $client->setquota("user.$username", 'STORAGE' => $quota );
83     $error = $client->error;
84     die "setquota user.$username: $error" if $error;
85   }
86
87 }
88
89 sub cyrus_delete { #subroutine, not method
90   my ( $server, $admin_username, $password_username, $username ) = @_;
91   my $client = cyrus_connect($server, $admin_username, $password_username);
92
93   my $rc = $client->setacl("user.$username", $admin_username => 'all' );
94   my $error = $client->error;
95   die $error if $error;
96
97   $rc = $client->delete("user.$username");
98   $error = $client->error;
99   die $error if $error;
100 }
101
102 sub cyrus_connect {
103
104   my( $server, $admin_username, $admin_password ) = @_;
105
106   eval "use Cyrus::IMAP::Admin;";
107
108   my $client = Cyrus::IMAP::Admin->new($server);
109   $client->authenticate(
110     -user      => $admin_username,
111     -mechanism => "login",       
112     -password  => $admin_password,
113   );
114   $client;
115
116 }
117
118 #sub cyrus_replace { #subroutine, not method
119 #}
120
121 1;
122