Code

Updated Mail Account ACLs
[gosa.git] / gosa-plugins / mail / personal / mail / class_mail-methods.inc
1 <?php
4 class mailMethod{
6   /* Allow modification of account_ids for existing mail accounts */
7   protected $modifyableMail = TRUE;
9   /* Enforces same value for 'mail' as used for 'cn' */
10   protected $mailEqualsCN   = FALSE; 
12   /* the attribute used to create accounts */ 
13   protected $uattrib        = "mail";  // Naming attribute for accounts, e.g. imap.
15   /* The account prefixes, keep the '.' here! See FAQ cyrusUseSlashes */
16   protected $user_prefix    = "user.";  
17   protected $share_prefix   = "share.";
19   /* Create accounts in cyrus style with '/' instead of '.' */
20   protected $cyrusUseSlashes= FALSE;
22   /* The atribute mapping for this class  Source --> Destination */
23   protected $attributes     = array();
24   protected $userObjectClasses = array();
25   protected $shareObjectClasses = array();
27   /* Enabled mail domain selection. If enabled getMailDomains must the domain parts */ 
28   protected $enableDomainSelection= FALSE;
29   protected $enableQuota          = TRUE;
30   protected $enableSieveManager   = FALSE;
31   protected $enableVacationRange  = TRUE;
32   protected $enableFolderTypes    = FALSE;
34   /* Default values */
35   protected $quotaValue   = 0;  
36   protected $quotaUsage   = 0;  
38   /* Method internal */
39   protected $type               = "user"; 
40   protected $account_id         = "";
41   protected $initial_account_id = "";
42   protected $connected          = FALSE;
43   protected $error              = "";
44   protected $parent             = NULL;   
45   protected $MailServer         = "";
48   protected $acl_map = array(
49       "lrsw"     => "read",
50       "lrswp"    => "post",
51       "p"        => "external post",
52       "lrswip"   => "append",
53       "lrswipcd" => "write",
54       "lrswipcda"=> "admin",
55       " "         => "none");
57   protected $acl_mapping = array();
58  
60   /*! \brief  Constructs the mail class 
61       @param  Object  Config  The GOsa configuration object
62       @param  Object  Plugin  The initator
63       @param  String          Open "user" or "group" account.
64    */
65   function __construct(&$config, &$parent, $type = "user")
66   {
67     $this->parent = $parent;
68     $this->config = $config;
70     /* Create a refernce to the mail selected server 
71      */
72     if(isset($this->parent->gosaMailServer)){
73       $this->MailServer = &$this->parent->gosaMailServer;
74     }else{
75       trigger_error("mailMethod with invalid parent object initialized.");
76     }
78     if(!in_array($this->type,array("user","group"))){
79       trigger_error("Unknown mail class type used '".$type."'.");
80     }else{
81       $this->type = $type;
82     }
83   }
85   
86   /*! \brief  Intialize attributes and config settings.
87    */
88   protected function init()
89   {
90     /* Get config value for cyrusUseSlashes
91      */
92     if ($this->config->get_cfg_value("cyrusUseSlashes") == "true"){
93       $this->cyrusUseSlashes = TRUE;
94       @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "cyrusUseSlashes: <b>Enabled</b>","");
95     }else{
96       @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "cyrusUseSlashes: <b>Disabled</b>","");
97     }
99     /* Check if the mail account identification attribute
100        is overridden in the configuration file
101      */
102     if($this->config->get_cfg_value("mailAttribute","mail") != ""){
103       $new_uattrib= strtolower($this->config->get_cfg_value("mailAttribute"));
104       if(in_array($new_uattrib,array("mail","uid"))){
105         $this->uattrib = $new_uattrib;
106       }else{
107         @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$new_uattrib."</b>",
108             "Unsupported 'mailAttribute' in gosa configuration specified");
109         msg_dialog::display(_("Configuration error"), 
110             sprintf(_("The configured mail attribute '%s' is unsupported!"), $new_uattrib), ERROR_DIALOG);
111       }
112     }
114     /* Create ACL map */
115     foreach($this->acl_map as $acl => $name){
116       $this->acl_mapping[$acl] = _($name);
117     }
119     $this->build_account_id();
120     $this->initial_account_id = $this->account_id;
121   }
123   
124   public function fixAttributesOnLoad()
125   {
126     foreach($this->attributes as $source => $dest){
127       if(isset($this->parent->attrs[$source])){
128         $this->parent->attrs[$dest] = $this->parent->attrs[$source];
129       }
130       if(isset($this->parent->$source)){
131         $this->parent->$dest = $this->parent->$source;
132       }
133       if(isset($this->parent->attrs[$source][0])){
134         $this->parent->saved_attributes[$source] = $this->parent->attrs[$source][0];
135       }
136     }
137   }
140   public function mailEqualsCN()
141   {
142     return($this->mailEqualsCN);
143   }
144   
146   public function fixAttributesOnRemove()
147   {
148     /* Remove objectClasses  
149      */ 
150     if($this->type == "user"){
151       $this->parent->attrs['objectClass'] = 
152         array_remove_entries_ics($this->userObjectClasses, $this->parent->attrs['objectClass']);
153     }else{
154       $this->parent->attrs['objectClass'] = 
155         array_remove_entries_ics($this->shareObjectClasses, $this->parent->attrs['objectClass']);
156     }
157     foreach($this->attributes as $source => $dest){
158       $this->attrs[$dest]   = array();
159       $this->attrs[$source] = array();
160     }
161   }
163   public function fixAttributesOnStore()
164   {
165     foreach($this->attributes as $source => $dest){
166       if(isset($this->parent->attrs[$dest])){
167         $this->parent->attrs[$source] = $this->parent->attrs[$dest ];
168       }
169       if(isset($this->parent->$dest)){
170         $this->parent->$source = $this->parent->$dest;
171       }
172     }
174     if($this->type == "user"){
175       $ocs = $this->userObjectClasses;
176     }else{
177       $ocs = $this->shareObjectClasses;
178     }
179     foreach($ocs as $oc){
180       if(!in_array($oc, $this->parent->attrs['objectClass'])){
181         $this->parent->attrs['objectClass'][] = $oc;
182       }
183     }
184   }
187   /*! \brief  Connect services like imap.
188               Not necessary for the base class.
189       @return Boolean True if this method is connected else false.
190    */
191   public function connect()
192   {
193     $this->reset_error();
194     @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Connect method</b>: ".get_class($this),"");
195     @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Current server</b>: ".$this->MailServer,"");
196  
197     $this->connected = TRUE;
198     return(TRUE);
199   }
202   /*! \brief  Returns the connection status of this method.
203       @return Boolean True if this method is connected else false.
204    */
205   public function is_connected()
206   {
207     return($this->connected);
208   }
211   /*! \brief  Disconnect this method. Close services like imap connection.
212               Not necessary for the base class.
213    */
214   public function disconnect()
215   {
216     $this->reset_error();
217     if($this->is_connected()){
218       @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Disconnect method</b>: ".get_class($this),"");
219       $this->connected =FALSE; 
220     }
221   }
223   
224   /*! \brief  Returns true the current object represents a valid account
225               (Some methods may check imap accounts here.)
226       @return Boolean TRUE if this is a valid account else FALSE
227   */
228   public function account_exists()
229   {
230     $this->reset_error();
231     return(TRUE);
232   }
233   
235   /*! \brief  Returns the last error occurred 
236       @return String  The last error message.
237    */
238   public function get_error(){
239     return($this->error);
240   }
243   public function isModifyableMail()
244   {
245     return($this->modifyableMail);
246   }
249   /*! \brief  Returns TRUE if the action caused an error.
250       @return Boolean TRUE on error else FALSE
251    */
252   public function is_error(){
253     return($this->error != "");
254   }
257   /*! \brief  Resets the error message.
258    */
259   public function reset_error(){
260     $this->error = "";
261   }
264   public function get_account_id()
265   {
266     $this->build_account_id();
267     return($this->account_id);
268   }
270   /*! \brief  Create a new account id, like 'user/name@domain.com'.
271    */
272   protected function build_account_id()
273   {
274     /* Build account identicator */
275     if($this->type == "user"){
276       $str = $this->user_prefix;
277     }else{
278       $str = $this->share_prefix;
279     }
281     /* Create account prefix and respect "cyrusUseSlashes" 
282        Do not replace escaped dots for cyrusUseSlashes.
283      */
284     $uattrib = $this->uattrib;
285     if($this->cyrusUseSlashes){
286       $str = preg_replace('/([^\\\\])\./',"\\1/",$str);
287     }
288     $str = preg_replace("/\\\\([\.\/])/","\\1",$str);
289     $str = trim(strtolower($str . $this->parent->$uattrib));
291     if($this->account_id != $str){
292       $this->account_id = $str;
293       @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "accountID generated: <b>".$str."</b>","");
294     }
295   }
298   /*! \brief  Creates a valid folder id for a given folder name.
299                e.g. $folder_id = "INBOX/test"  &&  $this->account_id = "share/mailbox@domain.de"
300                will result in "share/mailbox/test@domain.de"
301               This function is mainly used to read and write folder permissions.
302       @return String A valid folder id
303    */
304   public function create_folder_id($folder, $type = "")
305   {
307     if(!empty($folder)){
308       $folder = trim(preg_replace("/^INBOX[\.\/]*/i","",$folder));
309     }
310     if(!empty($folder)){
311       $folder = "/".$folder;
312     }
314     /* Build account identicator */
315     if($type == ""){
316       $type = $this->type;
317     }
318     if($type == "user"){
319       $str = $this->user_prefix;
320     }else{
321       $str = $this->share_prefix;
322     } 
324     /* Create account prefix and respect "cyrusUseSlashes"
325        Do not replace escaped dots for cyrusUseSlashes.
326      */
327     $uattrib = $this->uattrib;
328     if($this->cyrusUseSlashes){
329       $str = preg_replace('/([^\\\\])\./',"\\1/",$str);
330     }
331     $str = preg_replace("/\\\\([\.\/])/","\\1",$str);
332     $str = trim(strtolower($str . $this->parent->$uattrib));
334     if(preg_match("/\@/",$this->parent->$uattrib)){
335       list($mail,$domain) = split("\@",$this->parent->$uattrib);
336       $str = trim(strtolower($str . $mail . $folder . "@" . $domain));
337     }else{
338       $str = trim(strtolower($str . $this->parent->$uattrib));
339     }
340     return($str) ;
341   }
344   /*! \brief  Returns the configured mail method for the given parent object, 
345                 initialized and read for use.
346       @return mailMethod  The configured mailMethod.
347    */
348   public function get_method()
349   {
350     $methods = mailMethod::get_methods();
351     if ($this->config->get_cfg_value("mailmethod") != ""){
352       $method= $this->config->get_cfg_value("mailmethod");
353       $cls = get_correct_class_name("mailMethod$method");
354       if(isset($methods[$cls])){
355         @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "Selected mailMethod: <b>".$cls."</b>","");
356         $tmp = new $cls($this->config,$this->parent,$this->type);
357         $tmp->init();
358         return($tmp);
359       }else{
360         @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "Invalid mailMethod defined <b>".$cls.
361             "</b> falling back to <b>".get_class($this)."</b>","");
363         /* Print out configuration errors directly, we can't catch them everywhere. 
364          */
365         msg_dialog::display(_("Configuration error"), 
366             sprintf(_("Mail method '%s' is unknown!"), $method), ERROR_DIALOG);
367       }
368     }
370     /* If no valued mailMethod could be detected, return the base class.
371      */
372     $this->init();
373     return($this);
374   }
377   /*! \brief Saves sieve settings 
378    */
379   public function saveSieveSettings()
380   {
381     $this->reset_error();
382     return(TRUE);
383   }
385   
386   /*! \brief  Creates or Updates the mailAccount represented by this class. 
387    */
388   public function updateMailbox()
389   {
390     $this->reset_error();
391     return(TRUE);
392   }
395   /*! \brief  Update shared folder dependencies 
396    */
397   public function updateSharedFolder()
398   {
399     $this->reset_error();
400     return(TRUE);
401   }
404   /*! \brief  Removes the mailbox represented by this class,
405                and update shared folder ACLs .
406    */
407   public function deleteMailbox()
408   {
409     $this->reset_error();
411     @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id."</b>" ,
412         "<b>Remove account</b> from server :".$this->MailServer);
414     return(TRUE);
416     /* No imap actions here, just updated shared folder membership 
417      */
418     $ldap = $this->config->get_ldap_link();
419     $ldap->cd($this->config->current['BASE']);
420     $ldap->search("(&(objectClass=posixGroup)(objectClass=gosaMailAccount)(memberUid=".$account."))",array('dn','cn'));
421     if(class_exists("grouptabs")){
422       while($attrs = $ldap->fetch()){
423         $tmp = new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $attrs['dn']);
424         if(isset($tmp->by_object['mailgroup'])){
425           $tmp->by_object['mailgroup']->members= $tmp->by_object['group']->memberUid;
426           if(!$this->is_account){
427             $tmp->by_object['mailgroup']->removeUserAcl($account);
428             $tmp->by_object['mailgroup']->removeUserAcl($this->mail);
429           }
430           $tmp->by_object['mailgroup']->save();
431         }
432       }
433     }
434     return(TRUE);
435   }
437   
438   /*! \brief  Returns the used mail attribute (mail,uid)
439       @param  String  One out of 'mail','uid'
440    */
441   public function getUAttrib()
442   {
443     return($this->uattrib);
444   }
447   /*! \brief  Returns the used mail attribute (mail,uid)
448       @param  String  One out of 'mail','uid'
449    */
450   public function getUAttribValue()
451   {
452     $uattrib = $this->getUAttrib();
453     return($this->parent->$uattrib);
454   }
456   
457   /*! \brief  Returns whether the quota settings are enabled or not 
458       @return Boolean TRUE if enabled else FALSE
459    */
460   public function quotaEnabled()
461   {
462     return($this->enableQuota);
463   }
465   
466   /*! \brief  Returns the used quota 
467       @return Integer Quota used.
468    */
469   public function getQuotaUsage()
470   {
471     return(-1);
472   }
475   /*! \brief  Returns the quota restrictions.
476       @return Integer Quota restrictions.
477    */
478   public function getQuota($quotaValue)
479   {
480     return($quotaValue);
481   }
483   
484   /*! \brief  Sets the mail quota
485    */
486   public function setQuota($number)
487   {
488     if(!is_numeric($number)){
489       $number = (int) $number;
490       if(!$number){
491         $number = 0;
492       }
493     }
494     $this->quotaValue = $number; 
495     return(TRUE);
496   }
499   /*! \brief  Returns true whether the domain is selectable or not 
500    */
501   public function domainSelectionEnabled()
502   {
503     return($this->enableDomainSelection);
504   } 
507   /*! \brief Returns a list of configured mail domains 
508       @return Array A list of mail domains
509    */
510   public function getMailDomains()
511   {
512     return(array("Unconfigured"));
513   } 
515   
516   /*! \brief  Returns the used Spamlevels for this mailmethod 
517    */
518   public function getSpamLevels()
519   {
520     $spamlevel= array();
521     for ($i= 0; $i<21; $i++){
522       $spamlevel[]= $i;
523     }
524     return($spamlevel);
525   }
527   
528   /*! \brief  Returns the list of configured mailbox folders
529       @return Array The mailbox folders.
530    */
531   public function getMailboxList()
532   {
533     return(array("INBOX"));
534   }
537   /*! \brief  Returns whether the vacation range is selectable or not
538       @return Boolean TRUE, FALSE
539    */
540   public function vacationRangeEnabled()
541   {
542     return($this->enableVacationRange);
543   }
545   
546   /*! \brief  Returns true if the sieveManagement is allowed
547       @return Boolean TRUE, FALSE
548    */
549   public function allowSieveManagement()
550   {
551     return($this->enableSieveManager);
552   } 
555   /*! \brief  Checks dependencies to other GOsa plugins.
556    */
557   public function accountCreateable(&$reason = ""){
558     return(TRUE);
559   }
562   /*! \brief  Checks whether this account is removeable or not.
563               There may be some dependencies left, eg. kolab.
564    */
565   public function accountRemoveable(&$reason = ""){
566     return(TRUE);
567   }
569   
570   /*! \brief  Returns all mail servers configured in GOsa 
571                that are useable with this mailMethod.
572       @return Array  All useable mail servers.
573   */
574   public function getMailServers()
575   {
576     $mailserver = array();
577     $ui = get_userinfo();
578     foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){
579       if( $this->MailServer == $key ||
580           preg_match("/r/",$ui->get_permissions($val['server_dn'],"server/goImapServer",""))){
581         $mailserver[]= $key;
582       }
583     }
584     return($mailserver);
585   }
587   
588   /*! \brief  Returns the available mailMethods
589       @return Array   A list of all avaialable mailMethods_
590    */ 
591   static protected function get_methods()
592   {
593     global $class_mapping;
594     $available = array();
595     foreach($class_mapping as $class => $path){
596       if($class == "mailMethod") continue;
597       if(preg_match("/^mailMethod/",$class)){
598         $available[$class] = $class;
599       }
600     }
601     return($available);
602   }
604   
605   /* \brief   Some method require special folder types, "kolab" for example.
606       !! Those values are dummy values, the base class doesn't use folder types;
607      @return  Array Return folder types.
608    */
609   public function getAvailableFolderTypes()
610   {
611     $ret = array();
612     $ret['CAT'][''] = _("None"); 
613     $ret['SUB_CAT'][''][''] = _("None");
614     return($ret);
615   }
618   /* \brief  Returns the selected folder type. 
619       !! Those values are dummy values, the base class doesn't use folder types;
620      @return  Array  The folde type.
621    */
622   public function getFolderType($default)
623   {
624     return($default);
625   }
627  
628   /* \brief  Returns the selected folder type. 
629       !! Those values are dummy values, the base class doesn't use folder types;
630      @return  Array  The folde type.
631    */
632   public function setFolderType($type)
633   {
634     return(TRUE) ;   
635   }
638   /*! \brief  Returns configured acls 
639    */
640   public function  getFolderACLs($folder_acls)
641   {
642     /* Merge given ACL with acl mapping 
643        This ensures that no ACL will accidentally overwritten by gosa.
644      */
645     foreach($folder_acls as $user => $acl){
646       if(!isset($this->acl_mapping[$acl])){
647         $this->acl_mapping[$acl] = $acl;
648       }
649     }
651     return($folder_acls);
652   }
655   /*! \brief  Write ACLs back to imap or what ever 
656    */
657   public function  setFolderACLs($array)
658   {
659     return(TRUE);
660   }
663   /*! \brief  Returns a list of all possible acls.
664       @return Array   ACLs.
665   */
666   public function getAclTypes()
667   {
668     return( $this->acl_mapping);
669   }
671   public function folderTypesEnabled()
672   {
673     return($this->enableFolderTypes);
674   }
676   public function allow_remove(&$reason)
677   {
678     return(TRUE);
679   }
683 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
684 ?>