1 <?php
2 class kolabAccount extends plugin
3 {
4 /* Definitions */
5 var $plHeadline = "Kolab";
6 var $plDescription = "Manage Kolab user settings";
8 /* Kolab attributes */
9 var $kolabInvitationPolicy = array();
10 var $kolabFreeBusyFuture = 60;
11 var $unrestrictedMailSize = 0;
12 var $calFBURL = "";
13 var $kolabDelegate = array();
15 /* attribute list for save action */
16 var $attributes = array("kolabFreeBusyFuture", "unrestrictedMailSize", "calFBURL","kolabDelegate","kolabInvitationPolicy");
17 var $objectclasses = array("kolabInetOrgPerson");
19 /* Helper */
20 var $imapping = array();
21 var $mail_Account = false;
22 var $ReadOnly = false;
23 var $view_logged = FALSE;
24 var $uid = "";
26 var $multiple_support = TRUE;
29 /*! \brief Initialize Plugin
30 @param $config GOsa configuration object
31 @param $dn DN of the currently edited object
32 @param $parent The parent object, used to fetch Attributes.
33 */
34 function kolabAccount (&$config, $dn= NULL,$parent = NULL)
35 {
36 plugin::plugin ($config, $dn, $parent);
38 /* Setting uid to default */
39 if(isset($this->attrs['uid'][0])){
40 $this->uid = $this->attrs['uid'][0];
41 }
43 /* Pull arrays */
44 foreach(array("kolabDelegate", "kolabInvitationPolicy") as $attr){
45 if (isset($this->attrs["$attr"]["count"])){
46 $tmp = array();
47 for ($i= 0; $i<$this->attrs["$attr"]["count"]; $i++){
48 $tmp[]=$this->attrs["$attr"][$i];
49 }
50 $this->$attr = $tmp;
51 }
52 }
54 /* Get Boolean value */
55 $this->unrestrictedMailSize = FALSE;
56 if(isset($this->attrs['unrestrictedMailSize'][0]) && preg_match("/true/i",$this->attrs['unrestrictedMailSize'][0])){
57 $this->unrestrictedMailSize = TRUE;
58 }
60 /* If this one is empty, preset with ACT_MANUAL for anonymous users */
61 if (count ($this->kolabInvitationPolicy) == 0){
62 $this->kolabInvitationPolicy= array("ACT_MANUAL");
63 }
65 /* Check is account state */
66 $this->is_account = false;
67 if(count($this->kolabDelegate)){
68 $this->is_account = true;
69 }
71 /* Propose FreeBusy URL if empty */
72 if(!empty($this->calFBURL)){
73 $this->is_account = true;
74 }
76 /* Transfer account states for this union */
77 if (isset($this->parent->by_object['mailAccount']) && $this->parent->by_object['mailAccount']->is_account){
78 $this->mail_Account = true;
79 }elseif( isset($this->attrs) && isset($this->attrs['kolabHomeServer'])){
80 $this->mail_Account= true;
81 }else{
82 $this->is_account = false;
83 $this->mail_Account = false;
84 }
86 }
89 /*! \brief Create thml output
90 */
91 function execute()
92 {
93 /* Call parent execute */
94 plugin::execute();
96 /* Fill proposed FB URL if empty */
97 if (empty($this->calFBURL)) {
98 $this->calFBURL= "https://".$this->parent->by_object['mailAccount']->gosaMailServer.
99 "/freebusy/".$this->parent->by_object['mailAccount']->mail.".ifb";
100 }
102 /* Log view */
103 if($this->is_account && !$this->view_logged){
104 $this->view_logged = TRUE;
105 new log("view","users/".get_class($this),$this->dn);
106 }
108 /* Show tab dialog headers */
109 $display= "";
111 /* Show main page */
112 $smarty= get_smarty();
114 /* Load attributes */
115 foreach($this->attributes as $val){
116 $smarty->assign("$val", set_post($this->$val));
117 }
119 $tmp = $this->plInfo();
120 foreach($tmp['plProvidedAcls'] as $acl => $description){
121 $smarty->assign($acl."ACL",$this->getacl($acl,$this->ReadOnly));
122 $smarty->assign($acl."_W", $this->acl_is_writeable($acl,$this->ReadOnly));
123 }
124 $smarty->assign("is_account" , $this->is_account);
126 if($this->ReadOnly){
127 $smarty->assign("is_removeable",false);
128 $smarty->assign("is_createable",false);
129 }else{
130 $smarty->assign("is_removeable",$this->acl_is_removeable());
131 $smarty->assign("is_createable",$this->acl_is_createable());
132 }
134 /* Check for invitation action */
135 $nr= 0;
137 foreach($_POST as $name => $value){
138 if(preg_match("/add_inv_/",$name)){
139 $this->kolabInvitationPolicy[]= ": ACT_MANUAL";
140 }
141 }
142 foreach($_POST as $name => $value){
143 if(preg_match("/del_inv_/",$name)){
145 $id = preg_replace("/del_inv_/","",$name);
146 $id = preg_replace("/_(x|y)$/","",$id);
148 $new= array();
149 foreach ($this->kolabInvitationPolicy as $entry){
150 if (!preg_match("/^".$this->imapping[$id].":/", $entry)){
151 $new[]= $entry;
152 }
153 }
154 $this->kolabInvitationPolicy= $new;
155 }
156 }
158 /* Unify addresses */
159 $new= array();
160 foreach($this->kolabInvitationPolicy as $value){
161 $address= preg_replace('/^([^:]+:).*$/', '\1', $value);
162 $new[$address]= $value;
163 }
164 $this->kolabInvitationPolicy= array();
165 foreach($new as $value){
166 $this->kolabInvitationPolicy[]= $value;
167 }
169 /* Add delegation */
170 if (isset($_POST['add_delegation'])){
171 if ($_POST['delegate_address'] != ""){
173 /* Valid email address specified? */
174 $address= get_post('delegate_address');
175 $valid= FALSE;
176 if (!tests::is_email($address)){
177 if (!tests::is_email($address, TRUE)){
178 msg_dialog::display(_("Error"), msgPool::invalid(_("Mail address"), "","", "your-domain@your-domain.com"));
179 }
180 } else {
182 # $ldap= $this->config->get_ldap_link();
183 # $ldap->cd ($this->config->current['BASE']);
184 # $ldap->search('(mail='.$address.')',array("mail"));
185 # if ($ldap->count() == 0){
186 # msg_dialog::display(_("Error"), msgPool::duplicated(_("Primary mail address")));
187 # } else {
188 $valid= TRUE;
189 # }
190 }
192 if ($valid){
193 /* Add it */
194 if ($this->acl_is_writeable("kolabDelegate")){
195 $this->addDelegate ($address);
196 $this->is_modified= TRUE;
197 }
199 }
200 }
201 }
203 /* Delete forward email addresses */
204 if ((isset($_POST['delete_delegation'])) && (isset($_POST['delegate_list']))){
205 if (count($_POST['delegate_list']) && $this->acl_is_writeable("kolabDelegate")){
206 $this->delDelegate (get_post('delegate_list'));
207 }
208 }
210 /* Assemble policies */
211 $policies= array( 'ACT_ALWAYS_ACCEPT' => _("Always accept"),
212 'ACT_ALWAYS_REJECT' => _("Always reject"),
213 'ACT_REJECT_IF_CONFLICTS' => _("Reject if conflicts"),
214 'ACT_MANUAL_IF_CONFLICTS' => _("Manual if conflicts"),
215 'ACT_MANUAL' => _("Manual"));
216 $smarty->assign('policies', set_post($policies));
218 /* Adjust checkbox */
219 if ($this->unrestrictedMailSize){
220 $smarty->assign('unrestrictedMailSizeState', "checked");
221 } else {
222 $smarty->assign('unrestrictedMailSizeState', "");
223 }
225 /* Transfer delegation list */
226 if (!count($this->kolabDelegate)){
227 /* Smarty will produce <option value=""></option> and tidy don't like that, so tell smarty to create no option (array();)*/
228 $smarty->assign("kolabDelegate", array());
229 } else {
230 $smarty->assign("kolabDelegate", set_post($this->kolabDelegate));
231 }
233 $smarty->assign("mail_account",$this->mail_Account);
235 /* Create InvitationPolicy table */
236 $invitation= "";
237 $this->imapping= array();
238 $nr= 0;
239 $changeState = "";
240 foreach ($this->kolabInvitationPolicy as $entry){
242 if($this->acl_is_writeable("kolabInvitationPolicy")){
243 $changeState .= "changeState('address".$nr."'); \n changeState('policy".$nr."'); \n
244 changeState('add".$nr."'); \n changeState('remove".$nr."'); \n";
245 }
247 if(!$this->acl_is_writeable("kolabInvitationPolicy") && !$this->multiple_support_active){
248 $dis = " disabled ";
249 }else{
250 if($this->is_account || $this->multiple_support_active){
251 $dis = " ";
252 }else{
253 $dis = " disabled ";
254 }
255 }
256 $invitation.= "<tr><td>";
258 if(!$this->acl_is_readable("kolabInvitationPolicy")) {
259 }
261 /* The default entry does not have colons... */
262 if (!preg_match('/:/', $entry)){
263 $invitation.= _("Anonymous");
264 $name= "";
265 $mode= $entry;
266 } else {
267 $name= preg_replace('/:.*$/', '', $entry);
268 $mode= preg_replace('/^[^:]*: */', '', $entry);
270 if(!$this->acl_is_readable("kolabInvitationPolicy")){
271 $name='';
272 }
273 $invitation.= "<input type='text'name=\"address$nr\" size=16 maxlength=60 value=\"".set_post($name)."\" id='address".$nr."' ".$dis.">";
274 }
275 $invitation.= "</td>";
277 /* Add mode switch */
278 $invitation.= "<td><select size=\"1\" name=\"policy$nr\" id='policy".$nr."' ".$dis.">";
279 foreach($policies as $key => $value){
280 if ($key == $mode){
281 $invitation.= "<option value=\"$key\" selected>$value</option>";
282 } else {
283 $invitation.= "<option value=\"$key\">$value</option>";
284 }
285 }
287 /* Assign buttons */
288 $button= "";
289 if ($nr == count($this->kolabInvitationPolicy)-1){
290 $button= "<button type='submit' name=\"add_inv_".$nr."\" id='add".$nr."' ".$dis.">".msgPool::addButton()."</button>";
291 }
292 if ($nr != 0) {
293 $button.= "<button type='submit' name=\"del_inv_".$nr."\" id='remove".$nr."' ".$dis.">".msgPool::delButton()."</button>";
294 }
296 $invitation.= "</select> </td>
297 <td>$button</td>
298 </tr>\n";
299 $this->imapping[$nr]= $name;
300 $nr++;
301 }
302 $smarty->assign("invitation", $invitation);
303 $smarty->assign("changeState", $changeState);
304 $smarty->assign("kolabState",$this->is_account);
306 $smarty->assign("multiple_support",$this->multiple_support_active);
307 foreach($this->attributes as $attr){
308 $smarty->assign("use_".$attr,in_array_strict($attr,$this->multi_boxes));
309 }
310 foreach(array("kolabState") as $attr){
311 $smarty->assign("use_".$attr,in_array_strict($attr,$this->multi_boxes));
312 }
314 if($this->multiple_support_active){
315 }
318 $display.= $smarty->fetch (get_template_path('kolab.tpl', TRUE, dirname(__FILE__)));
319 return ($display);
320 }
322 function remove_from_parent()
323 {
324 if(!$this->initially_was_account){
325 return;
326 }
328 /* Optionally execute a command after we're done */
329 plugin::remove_from_parent();
331 if(!in_array_strict("kolabInetOrgPerson",$this->attrs['objectClass'])){
332 $this->attrs['objectClass'][] = "kolabInetOrgPerson";
333 }
335 $ldap = $this->config->get_ldap_linK();
336 $ldap->cd($this->config->current['BASE']);
337 $ldap->cd ($this->dn);
338 $ldap->modify($this->attrs);
340 /* Log last action */
341 new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
343 $this->handle_post_events('remove',array("uid" => $this->uid));
344 if (!$ldap->success()){
345 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
346 }
347 }
350 function check()
351 {
352 /* Call common method to give check the hook */
353 $message= plugin::check();
355 /* FBFuture is in days... */
356 if ($this->kolabFreeBusyFuture == ""){
357 $message[]= msgPool::required(_("Free Busy future"));
358 }
359 if(!preg_match('/^[0-9]+$/', $this->kolabFreeBusyFuture)){
360 $message[]= msgPool::invalid(_("Free Busy future"), $this->kolabFreeBusyFuture, "/^[0-9]+$/");
361 }
363 /* Check for URL scheme... */
364 if(empty($this->calFBURL)){
365 $message[]= msgPool::required(_("Free Busy URL"));
366 }
367 if(!preg_match("/^http+(s)*:\/\//",$this->calFBURL)){
368 $message[]= msgPool::invalid(_("Free Busy URL"), $this->calFBURL, "/^http+(s)*:\/\//");
369 }
371 /* Check invitation policy for existing mail addresses */
372 foreach($this->kolabInvitationPolicy as $policy){
374 /* Ignore anonymous string */
375 if (!preg_match('/:/', $policy)){
376 continue;
377 }
379 $address= preg_replace('/^([^:]+).*$/', '\1', $policy);
380 if (!tests::is_email($address)){
381 if (!tests::is_email($address, TRUE)){
382 $message[]= sprintf(_("The invitation policy entry for address '%s' is not valid."), $address);
383 }
384 } else {
386 $ldap= $this->config->get_ldap_link();
387 $ldap->cd ($this->config->current['BASE']);
388 $ldap->search('(mail='.$address.')',array("mail"));
389 if ($ldap->count() == 0){
390 $message[]= sprintf(_("There's no mail user with address '%s' for your invitation policy!"), $address);
391 } else {
392 $valid= TRUE;
393 }
394 }
395 }
397 return ($message);
398 }
400 /* Save data to object */
401 function save_object()
402 {
403 /* Do we need to flip is_account state? */
404 if (isset($_POST['connectivityTab'])){
406 if(isset($_POST["kolabState"])){
407 if($this->acl_is_createable()){
408 $this->is_account = true;
409 }
410 }else{
411 if($this->acl_is_removeable()){
412 $this->is_account = false;
413 }
414 }
415 if ($this->acl_is_writeable("unrestrictedMailSize")){
416 if (isset($_POST['unrestrictedMailSize']) && $_POST['unrestrictedMailSize'] == 1){
417 $this->unrestrictedMailSize= 1;
418 } else {
419 $this->unrestrictedMailSize= 0;
420 }
421 }
422 }
424 plugin::save_object();
426 /* Save changes done in invitation policies */
427 if($this->acl_is_writeable("kolabInvitationPolicy")){
429 $nr= 0;
430 $this->kolabInvitationPolicy= array();
431 while (isset($_POST["policy$nr"])){
433 /* Anonymous? */
434 if (!isset($_POST["address$nr"])){
435 $this->kolabInvitationPolicy[]= get_post("policy$nr");
436 } else {
437 $this->kolabInvitationPolicy[]= get_post("address$nr").": ".get_post("policy$nr");
438 }
440 $nr++;
441 }
443 /* If this one is empty, preset with ACT_MANUAL for anonymous users */
444 if (count ($this->kolabInvitationPolicy) == 0){
445 $this->kolabInvitationPolicy= array("ACT_MANUAL");
446 }
447 }
448 }
451 /* Save to LDAP */
452 function save()
453 {
454 /* Check mailmethod before doing something useful */
455 plugin::save();
457 /* Transfer arrays */
458 $this->attrs['kolabDelegate']= $this->kolabDelegate;
459 $this->attrs['kolabInvitationPolicy']= $this->kolabInvitationPolicy;
461 /* unrestrictedMailSize is boolean */
462 if($this->attrs['unrestrictedMailSize']){
463 $this->attrs['unrestrictedMailSize'] = "TRUE";
464 }else{
465 $this->attrs['unrestrictedMailSize'] = "FALSE";
466 }
468 /* Write back to ldap */
469 $ldap= $this->config->get_ldap_link();
470 $ldap->cd($this->dn);
471 $this->cleanup();
472 $ldap->modify ($this->attrs);
474 /* Log last action */
475 if($this->initially_was_account){
476 new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
477 }else{
478 new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
479 }
481 if (!$ldap->success()){
482 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
483 }
485 /* Optionally execute a command after we're done */
486 if ($this->initially_was_account == $this->is_account){
487 if ($this->is_modified){
488 $this->handle_post_events("modify",array("uid" => $this->uid));
489 }
490 } else {
491 $this->handle_post_events("add",array("uid" => $this->uid));
492 }
493 }
496 /* Add entry to delegation list */
497 function addDelegate($address)
498 {
499 $this->kolabDelegate[]= $address;
500 $this->kolabDelegate= array_unique ($this->kolabDelegate);
502 sort ($this->kolabDelegate);
503 reset ($this->kolabDelegate);
504 $this->is_modified= TRUE;
505 }
507 function delDelegate($addresses)
508 {
509 $this->kolabDelegate= array_remove_entries ($addresses, $this->kolabDelegate);
510 $this->is_modified= TRUE;
511 }
514 /* Return plugin informations for acl handling */
515 static function plInfo()
516 {
517 return (array(
518 "plShortName" => _("Kolab"),
519 "plDescription" => _("Kolab account settings")." ("._("Connectivity add-on").")",
520 "plSelfModify" => TRUE,
521 "plDepends" => array("user"),
522 "plPriority" => 20, // Position in tabs
523 "plSection" => array("personal" => _("My account")),
524 "plCategory" => array("users"),
525 "plOptions" => array(),
526 "plRequirements"=> array(
527 'ldapSchema' => array('kolabInetOrgPerson' => ''),
528 'onFailureDisablePlugin' => array(get_class())
529 ),
531 "plProvidedAcls" => array(
532 "kolabFreeBusyFuture" => _("Free busy future"),
533 "unrestrictedMailSize" => _("Mail size restriction"),
534 "calFBURL" => _("Free busy information"),
535 "kolabDelegate" => _("Delegations"),
536 "kolabInvitationPolicy" => _("Invitation policy"))
537 ));
538 }
541 /*! \brief Enable multiple edit support. \
542 Also sets $this->mail_account to TRUE, which simulates \
543 a valid mail extension.
544 */
545 public function enable_multiple_support()
546 {
547 plugin::enable_multiple_support();
548 $this->mail_Account = TRUE;
549 }
552 /*! \brief Save html POSTs in multiple edit.
553 */
554 public function multiple_save_object()
555 {
556 if (isset($_POST['connectivityTab'])){
557 plugin::multiple_save_object();
558 if(isset($_POST['use_kolabState'])){
559 $this->multi_boxes[] = "kolabState";
560 }
561 $this->save_object();
562 }
563 }
566 /*! \brief Returns all modified values. \
567 All selected an modified values will be returned \
568 in an array.
569 @return array Returns an array containing all attribute modifications
570 */
571 public function get_multi_edit_values()
572 {
573 $ret = plugin::get_multi_edit_values();
574 if(in_array_strict("kolabState",$this->multi_boxes)){
575 $ret['is_account'] = $this->is_account;
576 }
577 return($ret);
578 }
580 /*! \brief Sets modified attributes in mutliple edit. \
581 All collected values from "get_multi_edit_values()" \
582 will be applied to this plugin.
583 @param array An array containing modified attributes returned by get_multi_edit_values();
584 */
585 public function set_multi_edit_values($values)
586 {
587 plugin::set_multi_edit_values($values);
588 if(isset($values['is_account'])){
589 $this->is_account = $values['is_account'];
590 }
591 }
594 /*! \brief Initialize multiple edit ui for this plugin. \
595 This function sets plugin defaults in multiple edit.
596 @param array Attributes used in all object
597 @param array All used attributes.
598 */
599 public function init_multiple_support($attrs,$all)
600 {
601 plugin::init_multiple_support($attrs,$all);
602 if(isset($attrs['objectClass']) && in_array_strict("kolabInetOrgPerson",$attrs['objectClass'])){
603 $this->is_account = TRUE;
604 }
606 /* Pull arrays */
607 foreach(array("kolabDelegate", "kolabInvitationPolicy") as $attr){
608 if (isset($this->multi_attrs["$attr"]["count"])){
609 $tmp = array();
610 for ($i= 0; $i<$this->multi_attrs["$attr"]["count"]; $i++){
611 $tmp[]=$this->multi_attrs["$attr"][$i];
612 }
613 $this->$attr = $tmp;
614 }
615 }
617 /* If this one is empty, preset with ACT_MANUAL for anonymous users */
618 if (count ($this->kolabInvitationPolicy) == 0){
619 $this->kolabInvitationPolicy= array("ACT_MANUAL");
620 }
621 }
623 /* Adapt from template, using 'dn' */
624 function adapt_from_template($dn, $skip= array())
625 {
626 plugin::adapt_from_template($dn, $skip);
628 /* Setting uid to default */
629 if(isset($this->attrs['uid'][0]) && !in_array_strict("uid", $skip)){
630 $this->uid = $this->attrs['uid'][0];
631 }
633 /* Pull arrays */
634 foreach(array("kolabDelegate", "kolabInvitationPolicy") as $attr){
636 if (in_array_strict($attr, $skip)){
637 continue;
638 }
640 if (isset($this->attrs["$attr"]["count"])){
641 $tmp = array();
642 for ($i= 0; $i<$this->attrs["$attr"]["count"]; $i++){
643 $tmp[]=$this->attrs["$attr"][$i];
644 }
645 $this->$attr = $tmp;
646 }
647 }
649 /* If this one is empty, preset with ACT_MANUAL for anonymous users */
650 if (count ($this->kolabInvitationPolicy) == 0){
651 $this->kolabInvitationPolicy= array("ACT_MANUAL");
652 }
654 /* Get Boolean value */
655 $this->unrestrictedMailSize = FALSE;
656 if(isset($this->attrs['unrestrictedMailSize'][0]) && preg_match("/true/i",$this->attrs['unrestrictedMailSize'][0])){
657 $this->unrestrictedMailSize = TRUE;
658 }
660 /* Check is account state */
661 $this->is_account = false;
662 if(count($this->kolabDelegate)){
663 $this->is_account = true;
664 }
665 foreach(array("calFBURL") as $attr){
666 if(!empty($this->$attr)){
667 $this->is_account = true;
668 }
669 }
670 }
672 function PrepareForCopyPaste($source)
673 {
674 plugin::PrepareForCopyPaste($source);
676 $this->is_account = FALSE;
678 if(isset($source['kolabDelegate']) || isset($source['calFBURL'])){
679 $this->is_account = TRUE;
680 }
681 }
682 }
684 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
685 ?>