Overview

Packages

  • None
  • Vilma

Classes

  • Vilma
  • Vilma_Api
  • Vilma_Driver
  • Vilma_Driver_Qmailldap
  • Vilma_Driver_Sql
  • Vilma_Form_DeleteDomain
  • Vilma_Form_EditAlias
  • Vilma_Form_EditDomain
  • Vilma_Form_EditForward
  • Vilma_Form_EditUser
  • Vilma_MailboxDriver
  • Vilma_MailboxDriver_Hooks
  • Vilma_MailboxDriver_Imap
  • Vilma_MailboxDriver_Maildrop
  • Vilma_MailboxDriver_Null
  • Vilma_Test
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Copyright 2003-2012 Horde LLC (http://www.horde.org/)
  4:  *
  5:  * See the enclosed file LICENSE for license information (BSD). If you did not
  6:  * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
  7:  *
  8:  * @author  Marko Djukic <marko@oblo.com>
  9:  * @author  Daniel Collins <horde_dev@argentproductions.com>
 10:  * @package Vilma
 11:  */
 12: abstract class Vilma_Driver
 13: {
 14:     /**
 15:      * A hash containing any parameters for the current driver.
 16:      *
 17:      * @var array
 18:      */
 19:     protected $_params = array();
 20: 
 21:     /**
 22:      * Constructor.
 23:      *
 24:      * @param array $params  Any parameters needed for this driver.
 25:      */
 26:     public function __construct(array $params)
 27:     {
 28:         $this->_params = $params;
 29:     }
 30: 
 31:     /**
 32:      * Returns the list of domains from the backend.
 33:      *
 34:      * @return array  All the domains and their data in an array.
 35:      */
 36:     abstract public function getDomains();
 37: 
 38:     /**
 39:      * Returns the specified domain information from the backend.
 40:      *
 41:      * @param integer $domain_id  The id of the domain to fetch.
 42:      *
 43:      * @return array  The domain's information in an array.
 44:      */
 45:     abstract public function getDomain($domain_id);
 46: 
 47:     /**
 48:      * Given a domain name returns the information from the backend.
 49:      *
 50:      * @param string $name  The name of the domain to fetch.
 51:      *
 52:      * @return array  The domain's information in an array.
 53:      */
 54:     abstract public function getDomainByName($domain_name);
 55: 
 56:     /**
 57:      * Saves a domain with the provided information.
 58:      *
 59:      * @param array $info  Array of details to save the domain.
 60:      *
 61:      * @throws Vilma_Exception
 62:      */
 63:     public function saveDomain($info)
 64:     {
 65:         $this->_saveDomain($info);
 66:         try {
 67:             Horde::callHook('saveDomain', array($info), 'vilma');
 68:         } catch (Horde_Exception_HookNotSet $e) {
 69:         }
 70:     }
 71: 
 72:     /**
 73:      * Saves a domain with the provided information.
 74:      *
 75:      * @param array $info  Array of details to save the domain.
 76:      */
 77:     abstract protected function _saveDomain($info);
 78: 
 79:     /**
 80:      * Deletes a domain and all the users and virtuals within it.
 81:      *
 82:      * @param integer $domain_id  The id of the domain to delete.
 83:      *
 84:      * @throws Vilma_Exception
 85:      */
 86:     public function deleteDomain($domain_id)
 87:     {
 88:         $domain_record = $this->getDomain($domain_id);
 89:         $users = $this->getUsers($domain_record['domain_name']);
 90:         foreach ($users as $user) {
 91:             $this->deleteUser($user['user_id']);
 92:         }
 93:         $this->_deleteDomain($domain_id);
 94:         try {
 95:             Horde::callHook('deleteDomain', array($domain_record['domain_name']), 'vilma');
 96:         } catch (Horde_Exception_HookNotSet $e) {
 97:         }
 98:     }
 99: 
100:     /**
101:      * Deletes a domain.
102:      *
103:      * @param integer $domain_id  The id of the domain to delete.
104:      *
105:      * @throws Vilma_Exception
106:      */
107:     abstract protected function _deleteDomain($domain_id);
108: 
109:     /**
110:      * Returns the user who is the domain administrator.
111:      *
112:      * @todo  This should be replaced by moving all permissions into Horde
113:      *        permissions.
114:      *
115:      * @param string $domain_name  The name of the domain for which to
116:      *                             return the administrator.
117:      *
118:      * @return string  The domain adminstrator.
119:      * @throws Vilma_Exception
120:      */
121:     public function getDomainAdmin($domain_name)
122:     {
123:         $domain = $this->getDomainByName($domain_name);
124:         return $domain['domain_admin'];
125:     }
126: 
127:     /**
128:      * Returns the configured quota for this domain.
129:      *
130:      * @param string $domain_name  The name of the domain for which to
131:      *                             return the quota.
132:      *
133:      * @return integer  The domain quota.
134:      * @throws Vilma_Exception
135:      */
136:     public function getDomainQuota($domain_name)
137:     {
138:         $domain = $this->getDomainByName($domain_name);
139:         return $domain['domain_quota'];
140:     }
141: 
142:     /**
143:      * Returns the maximum number of users allowed for a given domain.
144:      *
145:      * @param string $domain_name  The name of the domain for which to
146:      *                             return the maximum users.
147:      *
148:      * @return integer The maximum number of allowed users.
149:      * @throws Vilma_Exception
150:      */
151:     public function getDomainMaxUsers($domain_name)
152:     {
153:         $domain = $this->getDomainByName($domain_name);
154:         return $domain['max_users'];
155:     }
156: 
157:     /**
158:      * Returns the current number of users for a domain.
159:      *
160:      * @param string $domain_name  The name of the domain for which to
161:      *                             get the current number of users.
162:      *
163:      * @return integer  The current number of users.
164:      */
165:     abstract public function getDomainNumUsers($domain_name);
166: 
167:     /**
168:      * Checks if the given domain is below the maximum allowed users.
169:      *
170:      * @param string $domain  The domain name to check.
171:      *
172:      * @return boolean  True if the domain does not have a maximum limit (0) or
173:      *                  current number of users is below the maximum number
174:      *                  allowed.
175:      */
176:     public function isBelowMaxUsers($domain)
177:     {
178:         /* Get the maximum number of users for this domain. */
179:         $max_users = $this->getDomainMaxUsers($domain);
180:         if (!$max_users) {
181:             /* No maximum. */
182:             return true;
183:         }
184: 
185:         /* Get the current number of users. */
186:         return $this->getDomainNumUsers($domain) < $max_users;
187:     }
188: 
189:     /**
190:      * Returns all available users, if a domain name is passed then limit the
191:      * list of users only to those users.
192:      *
193:      * @param string $domain  The name of the domain for which to fetch the
194:      *                        users.
195:      *
196:      * @return array  The available users and their stored information.
197:      * @throws Vilma_Exception
198:      */
199:     abstract public function getUsers($domain = null);
200: 
201:     /**
202:      * Returns all the users sorted by domain and as arrays of each domain.
203:      *
204:      * @return array  An array of domains then users for each domain.
205:      */
206:     public function getAllUsers()
207:     {
208:         /* Determine the domain for each user and plug into array by domain. */
209:         $users = array();
210:         foreach ($this->getUsers() as $user) {
211:             $domain = Vilma::stripDomain($user['user_name']);
212:             $users[$domain][] = $user;
213:         }
214: 
215:         /* Sort by domain. */
216:         ksort($users);
217: 
218:         /* Sort each domain's users by user name. */
219:         foreach ($users as $key => $val) {
220:             Horde_Array::arraySort($users[$key], 'user_name');
221:         }
222: 
223:         return $users;
224:     }
225: 
226:     /**
227:      * Returns the user information for a given user id.
228:      *
229:      * @param integer $user_id  The id of the user for which to fetch
230:      *                          information.
231:      *
232:      * @return array  The user information.
233:      */
234:     abstract public function getUser($user_id);
235: 
236:     /**
237:      * Does a series of checks for a given user to determine the status.
238:      *
239:      * @param array $user  The user's details in an array as returned by the
240:      *                     getUser() function.
241:      *
242:      * @return array  Either an array of error messages found during the checks
243:      *                or an array with a single element stating that the user
244:      *                is ready.
245:      * @throws Vilma_Exception if an error occurs looking up the user status.
246:      */
247:     public function getUserStatus($user)
248:     {
249:         /* Some needed vars. */
250:         $error = false;
251:         $status = array();
252:         $domain_name = Vilma::stripDomain($user['user_name']);
253:         $user_name = Vilma::stripUser($user['user_name']);
254: 
255:         /* Check if user enabled. */
256:         if ($user['user_enabled'] !== 'active') {
257:             $error = true;
258:             $err_msg = _("User disabled.");
259:             $status[] = Horde::img('alerts/error.png', $err_msg) . '&nbsp;' . $err_msg;
260:         }
261: 
262:         /* Check if mailbox exists. */
263:         try {
264:             Vilma_MailboxDriver::factory()->checkMailbox($user_name, $domain_name);
265:         } catch (Exception $result) {
266:             $error = true;
267:             $err_msg = $result->getMessage();
268:             $status[] = Horde::img('alerts/warning.png', $err_msg) . '&nbsp;' . $err_msg;
269:         }
270: 
271:         /* TODO: Quota checking would be nice too. */
272: 
273:         /* If no errors have been found output a success message for this
274:          * user's status. */
275:         if (!$error) {
276:             $msg = _("User ready.");
277:             $status = array(Horde::img('alerts/success.png', $msg) . '&nbsp;' . $msg);
278:         }
279: 
280:         return $status;
281:     }
282: 
283:     /**
284:      * @throws Vilma_Exception
285:      */
286:     public function saveUser($info)
287:     {
288:         $create = empty($info['user_id']);
289:         $info['user_id'] = $this->_saveUser($info);
290: 
291:         if ($create) {
292:             try {
293:                 Vilma_MailboxDriver::factory()
294:                     ->createMailbox(Vilma::stripUser($info['user_name']),
295:                                     Vilma::stripDomain($info['user_name']));
296:             } catch (Exception $e) {
297:                 $this->_deleteUser($info['user_id']);
298:                 throw $e;
299:             }
300:         }
301: 
302:         if (isset($GLOBALS['conf']['mta']['auth_update_script']) &&
303:             !empty($info['password'])) {
304:             $cmd = sprintf('%s set %s %s 2>&1',
305:                            $GLOBALS['conf']['mta']['auth_update_script'],
306:                            escapeshellarg($info['user_name']),
307:                            escapeshellarg($info['password']));
308:             $msg = system($cmd, $ec);
309:             if ($msg === false) {
310:                 throw new Vilma_Exception(_("Error running authentication update script."));
311:             }
312:             if ($ec != 0) {
313:                 throw new Vilma_Exception(_("Unknown error running authentication update script."));
314:             }
315:         }
316:     }
317: 
318:     /**
319:      * Saves a user to the backend.
320:      *
321:      * @param array $info  The user information to save.
322:      *
323:      * @return string  The user ID.
324:      * @throws Vilma_Exception
325:      */
326:     abstract protected function _saveUser($info);
327: 
328:     /**
329:      * Deletes a user.
330:      *
331:      * @param integer $user_id  The id of the user to delete.
332:      *
333:      * @throws Vilma_Exception
334:      */
335:     abstract public function deleteUser($user_id);
336: 
337:     public function getUserFormAttributes()
338:     {
339:     }
340: 
341:     /**
342:      * Returns a list of all users, aliases, or groups and forwards for a
343:      * domain.
344:      *
345:      * @param string $domain      Domain on which to search.
346:      * @param string $type        Only return a specific type. One of 'all',
347:      *                            'user', 'alias', 'forward', or 'group'.
348:      * @param string $key         Sort list by this key.
349:      * @param integer $direction  Sort direction.
350:      *
351:      * @return array  Account information for this domain.
352:      */
353:     public function getAddresses($domain, $type = 'all', $key = 'user_name',
354:                                  $direction = 0)
355:     {
356:         $addresses = $this->_getAddresses($domain, $type);
357:         Horde_Array::arraySort($addresses, $key, $direction, true);
358:         return $addresses;
359:     }
360: 
361:     /**
362:      * Returns a list of all users, aliases, or groups and forwards for a
363:      * domain.
364:      *
365:      * @param string $domain      Domain on which to search.
366:      * @param string $type        Only return a specific type. One of 'all',
367:      *                            'user', 'alias','forward', or 'group'.
368:      * @param string $key         Sort list by this key.
369:      * @param integer $direction  Sort direction.
370:      *
371:      * @return array  Account information for this domain.
372:      */
373:     abstract protected function _getAddresses($domain, $type = 'all');
374: 
375:     /**
376:      * Returns an array of information related to the address passed in.
377:      *
378:      * This method may be overridden by the backend driver if there is a more
379:      * efficient way to do this than a linear array search.
380:      *
381:      * @param string $address  Address for which information will be pulled.
382:      * @param string $type     Address type to request.
383:      *                         One of 'all', 'user', 'alias', 'forward' or
384:      *                         'group'.
385:      *
386:      * @return array  Array of user information on success or empty array
387:      *                if the user does not exist.
388:      * @throws Vilma_Exception if address of that type doesn't exist.
389:      */
390:     public function getAddressInfo($address, $type = 'all')
391:     {
392:         $domain = Vilma::stripDomain($address);
393:         $addresses = $this->getAddresses($domain, $type);
394:         foreach ($addresses as $addrinfo) {
395:             if ($addrinfo['id'] == $address ||
396:                 $addrinfo['address'] == $address) {
397:                 return $addrinfo;
398:             }
399:         }
400:         throw new Vilma_Exception(sprintf(_("No such address %s of type %s found."), $address, $type));
401:     }
402: 
403:     /**
404:      * Returns available virtual emails.
405:      *
406:      * @param string $filter  If passed a domain then return all virtual emails
407:      *                        for the domain, otherwise if passed a user name
408:      *                        return all virtual emails for that user.
409:      *
410:      * @return array  The available virtual emails.
411:      */
412:     public function getVirtuals($filter)
413:     {
414:     }
415: 
416:     /**
417:      * Returns information for a virtual id.
418:      *
419:      * @param integer $virtual_id  The virtual id for which to return
420:      *                             information.
421:      *
422:      * @return array  The virtual email information.
423:      */
424:     public function getVirtual($virtual_id)
425:     {
426:     }
427: 
428:     /**
429:      * Saves virtual email address to the backend.
430:      *
431:      * @param array $info     The virtual email data.
432:      * @param string $domain  The name of the domain for this virtual email.
433:      *
434:      * @throws Vilma_Exception
435:      */
436:     public function saveVirtual($info, $domain)
437:     {
438:     }
439: 
440:     /**
441:      * Deletes a virtual email.
442:      *
443:      * @param integer $virtual_id  The id of the virtual email to delete.
444:      */
445:     public function deleteVirtual($virtual_id)
446:     {
447:     }
448: 
449:     /**
450:      * Saves or creates alias records for a user.
451:      *
452:      * @param array $info  The info used to store the information.
453:      *                     Required fields are:
454:      *                     - 'address': The destination address (used for LDAP
455:      *                       ID lookup).
456:      *                     - 'alias_address': The alias to create or the new
457:      *                       data for the modified entry.
458:      *                     - 'alias': The alias we are modifying, if we are
459:      *                       modifying an existing one.
460:      *
461:      * @throws Vilma_Exception
462:      */
463:     public function saveAlias($info)
464:     {
465:     }
466: 
467:     /**
468:      * Deletes alias records for a given user.
469:      *
470:      * @param array $info  The info used to store the information.
471:      *                     Required fields are:
472:      *                     - 'address': The destination address (used for LDAP
473:      *                       ID lookup).
474:      *                     - 'alias': The alias we are deleting.
475:      *
476:      * @throws Vilma_Exception
477:      */
478:     public function deleteAlias($info)
479:     {
480:     }
481: 
482:     /**
483:      * Saves or creates forward records for a given user.
484:      *
485:      * @param array $info  The info used to store the information.
486:      *                     Required fields are:
487:      *                     - 'address': The destination address (used for LDAP
488:      *                       ID lookup).
489:      *                     - 'forward_address': The forward to create or the
490:      *                       new data for the modified entry.
491:      *                     - 'forward': The forward we are modifying, if we are
492:      *                       modifying an existing one.
493:      *
494:      * @throws Vilma_Exception
495:      */
496:     public function saveForward($info)
497:     {
498:     }
499: 
500:     /**
501:      * Deletes forward records for a given user.
502:      *
503:      * @param array $info  The info used to store the information.
504:      *                     Required fields are:
505:      *                     - 'address': The destination address (used for LDAP
506:      *                       ID lookup).
507:      *                     - 'forward': The forward we are deleting.
508:      *
509:      * @throws Vilma_Exception
510:      */
511:     public function deleteForward($info)
512:     {
513:     }
514: 
515:     /**
516:      * Attempts to return a concrete Vilma_Driver instance based on $driver.
517:      *
518:      * @param string $driver  The type of concrete Vilma_Driver subclass to
519:      *                        return.
520:      * @param array $params   A hash containing any additional configuration or
521:      *                        connection parameters a subclass might need.
522:      *
523:      * @return Vilma_Driver  The newly created concrete Vilma_Driver instance.
524:      * @throws Vilma_Exception
525:      */
526:     static public function factory($driver = null, $params = null)
527:     {
528:         if (is_null($driver)) {
529:             $driver = $GLOBALS['conf']['storage']['driver'];
530:         }
531:         $driver = Horde_String::ucfirst(basename($driver));
532: 
533:         if (is_null($params)) {
534:             $params = Horde::getDriverConfig('storage', $driver);
535:         }
536: 
537:         $class = 'Vilma_Driver_' . $driver;
538:         if (class_exists($class)) {
539:             return new $class($params);
540:         }
541: 
542:         throw new Vilma_Exception(sprintf(_("No such backend \"%s\" found"), $driver));
543:     }
544: }
545: 
API documentation generated by ApiGen