From 9f108dd1a969473375341d92a7b1252fa2cedc9a Mon Sep 17 00:00:00 2001 From: mszulecki Date: Thu, 14 Jun 2007 17:09:01 +0000 Subject: Initial import. git-svn-id: http://svn.sukimashita.com/repos/mailadmin/trunk@2 4281df72-ff29-0410-8fee-2d9ac0c5f5a7 --- apps/admin/config/app.yml | 50 +++ apps/admin/config/cache.yml | 4 + apps/admin/config/config.php | 8 + apps/admin/config/factories.yml | 35 ++ apps/admin/config/filters.yml | 10 + apps/admin/config/i18n.yml | 7 + apps/admin/config/logging.yml | 22 + apps/admin/config/routing.yml | 23 + apps/admin/config/security.yml | 3 + apps/admin/config/settings.yml | 117 +++++ apps/admin/config/view.yml | 15 + apps/admin/lib/imap/FakeIMAPClient.php | 9 + apps/admin/lib/imap/IMAPClient.php | 498 +++++++++++++++++++++ apps/admin/lib/imap/IMAPManager.php | 48 ++ apps/admin/lib/imap/IMAPServerInformation.php | 63 +++ apps/admin/lib/myChangeNicknameValidator.php | 43 ++ apps/admin/lib/myDenyStringValidator.php | 38 ++ apps/admin/lib/myLoginValidator.php | 45 ++ apps/admin/lib/myUser.class.php | 83 ++++ .../modules/address/actions/actions.class.php | 165 +++++++ apps/admin/modules/address/config/generator.yml | 48 ++ apps/admin/modules/address/templates/_alias.php | 9 + .../modules/address/templates/_destination.php | 23 + .../admin/modules/address/templates/_domain_id.php | 1 + .../admin/modules/address/templates/_localpart.php | 1 + .../modules/address/templates/_mailbox_id.php | 1 + apps/admin/modules/address/validate/create.yml | 10 + apps/admin/modules/address/validate/edit.yml | 10 + .../modules/content/actions/actions.class.php | 18 + .../admin/modules/domain/actions/actions.class.php | 47 ++ apps/admin/modules/domain/config/generator.yml | 53 +++ apps/admin/modules/domain/config/security.yml | 11 + .../domain/templates/_default_mailbox_quota.php | 1 + .../modules/domain/templates/_edit_header.php | 13 + .../domain/templates/_max_mailbox_count.php | 1 + apps/admin/modules/domain/templates/_quota.php | 1 + apps/admin/modules/domain/validate/create.yml | 46 ++ apps/admin/modules/domain/validate/edit.yml | 46 ++ apps/admin/modules/log/actions/actions.class.php | 46 ++ apps/admin/modules/log/config/generator.yml | 30 ++ apps/admin/modules/log/config/security.yml | 2 + apps/admin/modules/log/templates/_priority.php | 1 + apps/admin/modules/log/templates/_user_id.php | 1 + apps/admin/modules/log/templates/clearSuccess.php | 12 + .../modules/mailbox/actions/actions.class.php | 56 +++ apps/admin/modules/mailbox/config/generator.yml | 56 +++ .../admin/modules/mailbox/templates/_domain_id.php | 1 + .../modules/mailbox/templates/_last_login.php | 1 + .../mailbox/templates/_max_address_count.php | 1 + .../admin/modules/mailbox/templates/_max_quota.php | 1 + .../modules/mailbox/templates/_new_password.php | 1 + apps/admin/modules/mailbox/templates/_password.php | 1 + apps/admin/modules/mailbox/validate/create.yml | 50 +++ apps/admin/modules/mailbox/validate/edit.yml | 48 ++ .../admin/modules/server/actions/actions.class.php | 29 ++ .../admin/modules/server/templates/imapSuccess.php | 57 +++ apps/admin/modules/user/actions/actions.class.php | 115 +++++ apps/admin/modules/user/config/generator.yml | 55 +++ apps/admin/modules/user/config/security.yml | 13 + .../modules/user/templates/_domain_permissions.php | 27 ++ apps/admin/modules/user/templates/_last_login.php | 1 + apps/admin/modules/user/templates/_password.php | 3 + apps/admin/modules/user/templates/_password1.php | 3 + apps/admin/modules/user/templates/_password2.php | 3 + apps/admin/modules/user/templates/_role_id.php | 1 + apps/admin/modules/user/templates/loginSuccess.php | 12 + .../modules/user/templates/settingsSuccess.php | 22 + apps/admin/modules/user/validate/create.yml | 37 ++ apps/admin/modules/user/validate/edit.yml | 40 ++ apps/admin/modules/user/validate/login.yml | 24 + apps/admin/modules/user/validate/settings.yml | 43 ++ apps/admin/templates/_branding.php | 4 + apps/admin/templates/_navigation.php | 53 +++ apps/admin/templates/_notes.php | 9 + apps/admin/templates/layout.php | 35 ++ 75 files changed, 2520 insertions(+) create mode 100644 apps/admin/config/app.yml create mode 100644 apps/admin/config/cache.yml create mode 100644 apps/admin/config/config.php create mode 100644 apps/admin/config/factories.yml create mode 100644 apps/admin/config/filters.yml create mode 100644 apps/admin/config/i18n.yml create mode 100644 apps/admin/config/logging.yml create mode 100644 apps/admin/config/routing.yml create mode 100644 apps/admin/config/security.yml create mode 100644 apps/admin/config/settings.yml create mode 100644 apps/admin/config/view.yml create mode 100644 apps/admin/lib/imap/FakeIMAPClient.php create mode 100644 apps/admin/lib/imap/IMAPClient.php create mode 100644 apps/admin/lib/imap/IMAPManager.php create mode 100644 apps/admin/lib/imap/IMAPServerInformation.php create mode 100644 apps/admin/lib/myChangeNicknameValidator.php create mode 100644 apps/admin/lib/myDenyStringValidator.php create mode 100644 apps/admin/lib/myLoginValidator.php create mode 100644 apps/admin/lib/myUser.class.php create mode 100644 apps/admin/modules/address/actions/actions.class.php create mode 100644 apps/admin/modules/address/config/generator.yml create mode 100644 apps/admin/modules/address/templates/_alias.php create mode 100644 apps/admin/modules/address/templates/_destination.php create mode 100644 apps/admin/modules/address/templates/_domain_id.php create mode 100644 apps/admin/modules/address/templates/_localpart.php create mode 100644 apps/admin/modules/address/templates/_mailbox_id.php create mode 100644 apps/admin/modules/address/validate/create.yml create mode 100644 apps/admin/modules/address/validate/edit.yml create mode 100644 apps/admin/modules/content/actions/actions.class.php create mode 100644 apps/admin/modules/domain/actions/actions.class.php create mode 100644 apps/admin/modules/domain/config/generator.yml create mode 100644 apps/admin/modules/domain/config/security.yml create mode 100644 apps/admin/modules/domain/templates/_default_mailbox_quota.php create mode 100644 apps/admin/modules/domain/templates/_edit_header.php create mode 100644 apps/admin/modules/domain/templates/_max_mailbox_count.php create mode 100644 apps/admin/modules/domain/templates/_quota.php create mode 100644 apps/admin/modules/domain/validate/create.yml create mode 100644 apps/admin/modules/domain/validate/edit.yml create mode 100644 apps/admin/modules/log/actions/actions.class.php create mode 100644 apps/admin/modules/log/config/generator.yml create mode 100644 apps/admin/modules/log/config/security.yml create mode 100644 apps/admin/modules/log/templates/_priority.php create mode 100644 apps/admin/modules/log/templates/_user_id.php create mode 100644 apps/admin/modules/log/templates/clearSuccess.php create mode 100644 apps/admin/modules/mailbox/actions/actions.class.php create mode 100644 apps/admin/modules/mailbox/config/generator.yml create mode 100644 apps/admin/modules/mailbox/templates/_domain_id.php create mode 100644 apps/admin/modules/mailbox/templates/_last_login.php create mode 100644 apps/admin/modules/mailbox/templates/_max_address_count.php create mode 100644 apps/admin/modules/mailbox/templates/_max_quota.php create mode 100644 apps/admin/modules/mailbox/templates/_new_password.php create mode 100644 apps/admin/modules/mailbox/templates/_password.php create mode 100644 apps/admin/modules/mailbox/validate/create.yml create mode 100644 apps/admin/modules/mailbox/validate/edit.yml create mode 100644 apps/admin/modules/server/actions/actions.class.php create mode 100644 apps/admin/modules/server/templates/imapSuccess.php create mode 100644 apps/admin/modules/user/actions/actions.class.php create mode 100644 apps/admin/modules/user/config/generator.yml create mode 100644 apps/admin/modules/user/config/security.yml create mode 100644 apps/admin/modules/user/templates/_domain_permissions.php create mode 100644 apps/admin/modules/user/templates/_last_login.php create mode 100644 apps/admin/modules/user/templates/_password.php create mode 100644 apps/admin/modules/user/templates/_password1.php create mode 100644 apps/admin/modules/user/templates/_password2.php create mode 100644 apps/admin/modules/user/templates/_role_id.php create mode 100644 apps/admin/modules/user/templates/loginSuccess.php create mode 100644 apps/admin/modules/user/templates/settingsSuccess.php create mode 100644 apps/admin/modules/user/validate/create.yml create mode 100644 apps/admin/modules/user/validate/edit.yml create mode 100644 apps/admin/modules/user/validate/login.yml create mode 100644 apps/admin/modules/user/validate/settings.yml create mode 100644 apps/admin/templates/_branding.php create mode 100644 apps/admin/templates/_navigation.php create mode 100644 apps/admin/templates/_notes.php create mode 100644 apps/admin/templates/layout.php (limited to 'apps/admin') diff --git a/apps/admin/config/app.yml b/apps/admin/config/app.yml new file mode 100644 index 0000000..1380235 --- /dev/null +++ b/apps/admin/config/app.yml @@ -0,0 +1,50 @@ +# default values +prod: + server: + default: + imap: + # Client Backend to use for IMAP server communication + # FakeIMAPClient: Returns pseudo data for testing purposes + # IMAPClient: Operates on a standards compliant IMAP server + client: IMAPClient + host: localhost + port: 143 + admin: cyrus + pass: secret + +all: + info: + version: 1.0.0 + pager: + max_per_page_options: [10,25,50,100] + max_per_page: 25 + domain: + quota: 150000 + max_mailbox_count: 300 + default_mailbox_quota: 20000 + mailbox: + deny_names: [cyrus, postmaster] + max_address_count: 300 + address: + dest_collapse_count: 1 + user: + domain_perm_collapse_count: 3 + server: + default: + pam: + # Method to encrypt Mailbox passwords (should match your pam setting) + # 0: plain = Passwords stored in plaintext + # 1: crypt = Use shadow-compatible crypt(3) function + # 2: md5 = Use md5 function + # 3: sha1 = Use sha1 function + crypt: 1 + imap: + # Client Backend to use for IMAP server communication + # FakeIMAPClient: Returns pseudo data for testing purposes + # IMAPClient: Operates on a standards compliant IMAP server + client: IMAPClient + host: mirell.de + port: 143 + admin: cyrus + pass: secret + diff --git a/apps/admin/config/cache.yml b/apps/admin/config/cache.yml new file mode 100644 index 0000000..9a80ccb --- /dev/null +++ b/apps/admin/config/cache.yml @@ -0,0 +1,4 @@ +default: + enabled: off + with_layout: false + lifetime: 86400 diff --git a/apps/admin/config/config.php b/apps/admin/config/config.php new file mode 100644 index 0000000..4038d49 --- /dev/null +++ b/apps/admin/config/config.php @@ -0,0 +1,8 @@ + diff --git a/apps/admin/lib/imap/IMAPClient.php b/apps/admin/lib/imap/IMAPClient.php new file mode 100644 index 0000000..2271cc9 --- /dev/null +++ b/apps/admin/lib/imap/IMAPClient.php @@ -0,0 +1,498 @@ +socket) + $this->closeConnection(); + } + + // FIXME: Extract server name and version; should probably be moved to own library (?) + /* + Couple of banners: + * OK mail.mirapoint.com Mirapoint IMAP4 3.7.4-GA server ready + * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS] Courier-IMAP ready. Copyright 1998-2004 Double Precision, Inc. See COPYING for distribution information. + * OK mail8.hotbox.ru Cyrus IMAP4 v2.2.3 server ready + * OK dovecot ready. + * OK Microsoft Exchange IMAP4rev1 server version 5.5.2654.50 (wlvexc00.diginsite.com) ready + * OK Microsoft Exchange Server 2003 IMAP4rev1 server version 6.5.6944.0 (stbowa02.stb.sun.ac.za) ready. + * OK [x.x.x.x] IMAP4rev1 Mercury/32 v4.01a server ready. + * OK Messaging Multiplexor (iPlanet Messaging Server 5.2 HotFix 1.26 (built Mar 31 2004)) + * OK [CAPABILITY IMAP4REV1 LOGIN-REFERRALS STARTTLS AUTH=LOGIN] leto IMAP4rev1 2001.315rh at Mon, 31 May 2004 11:06:55 +0200 (CEST) + * OK mail1 Cyrus IMAP4 v2.0.16 server ready + * OK Microsoft Exchange IMAP4rev1 server version Exchange 2000.4208.3 (EX2000.com) ready. + * OK mcis.com Microsoft IMAP4Rev1 Server ready at Thu, 16 Mar 2000 19:03:15 -0800 Version: 5.5.1877.377.37 + */ + + // list of (name, version) regex pairs, first match has to be the value + protected static $servers = array( + array("/(Cyrus\sIMAP)4/", "/Cyrus\sIMAP4\sv((\d+)\.(\d+).(\d+))/"), + array("/(Courier.IMAP)/", null), + ); + + public function getServerName() + { + foreach(self::$servers as $server) + { + if(preg_match($server[0], $this->greeting, $matches)) + { + return $matches[1]; + } + } + + return false; + } + + public function getServerVersion() + { + foreach(self::$servers as $server) + { + if(preg_match($server[0], $this->greeting, $matches)) + { + if($server[1] == null) + return "Unknown"; + + if(preg_match($server[1], $this->greeting, $matches)) + { + return $matches[1]; + } + } + } + + return false; + } + + protected $greeting = null; + public function getGreeting() + { + return $this->greeting; + } + + protected $uri = null; + public function getURI() + { + return $this->uri; + } + + public function openConnection($uri, $timeout = 10) + { + $this->resetClient(); + $this->socket = $this->socket = fsockopen($this->uri = $uri, null, $errno, $errstr); + if(!$this->socket) + throw new Exception('Could not open Socket for IMAP connection: "'.$errstr.'"', $errno); + $this->state = self::STATE_GREETING; + $this->greeting = fgets($this->socket, 1024); + + if (sfConfig::get('sf_logging_enabled')) + { + sfContext::getInstance()->getLogger()->info("{IMAPClient} Greeting: ".trim($this->greeting)); + } + + $this->state = self::STATE_UNAUTH; + + return true; + } + + public function closeConnection() + { + if($this->socket) + { + if(!$this->logout()) + throw new Exception("Logout error."); + fclose($this->socket); + } + $this->resetClient(); + return true; + } + + protected function resetClient() + { + $this->state = self::STATE_GREETING; + $this->capabilities = null; + $this->hierarchydelimiter = null; + } + + protected function sendCommand($tag, $cmd, $args = "") + { + // check if we got a connection + if(!$this->socket) + throw new Exception('Unable to execute "'.$cmd.'" command: Not connected to a server.'); + + if(is_array($args)) + { + $args = " \"" . implode("\" \"", $args) . "\""; + } + + if (sfConfig::get('sf_logging_enabled')) + { + sfContext::getInstance()->getLogger()->info("{IMAPClient} Command: ".$tag." ".$cmd.$args); + } + + //LogEntryPeer::log("{IMAPClient} Command: ".$tag." ".$cmd.$args, LogEntry::PRIO_DEBUG); + + // send command + fputs($this->socket, $tag." ".$cmd.$args."\n"); + + // read response + $response = array(); + do + { + $line = fgets($this->socket, 1024); + $response[] = $line; + + if (sfConfig::get('sf_logging_enabled')) + { + sfContext::getInstance()->getLogger()->info("{IMAPClient} Line: \"".trim($line)."\""); + } + //LogEntryPeer::log("{IMAPClient} Line: \"".trim($line)."\"", LogEntry::PRIO_DEBUG); + } + while(self::getTag($line) != $tag && !feof($this->socket)); + + return $response; + } + + // PARSER API + protected static $tagcounter = 0; + protected static function generateTag() + { + $pattern = "0123456789". + "abcdefghij". + "klmnopqrst". + "uvwxyz"; + + if(self::$tagcounter==0) + self::$tagcounter = rand(0,999999); + + $s = ""; + $r = self::$tagcounter++; + do + { + $m = $r % 36; + $s = $pattern{$m} . $s; + } + while(($r = ($r-$m) / 36) > 0); + return sprintf("%04s", $s); + } + + protected static function getTag($line) + { + return self::getResponseData($line, 0); + } + + protected static function getResponseData($line, $index = 0) + { + $tokens = explode(" ", $line); + return $tokens[$index]; + } + + protected static function getResultStatus($tag, $response) + { + if(is_array($response)) + { + foreach($response as $line) + { + if(self::getTag($line) == $tag) + { + return self::getResponseData($line, 1); + } + } + } + + return null; + } + + protected function runCommandAndGetResult($command, $arguments = "") + { + $tag = self::generateTag(); + $response = $this->sendCommand($tag, $command, $arguments); + return self::getResultStatus($tag, $response); + } + + // IMAP API + + // RFC 3501 - IMAP4rev1 + // RFC 1730 - IMAP4 + public function login($user, $password) + { + $result = $this->runCommandAndGetResult("login", array($user, $password)); + if($result == self::RESULT_OK) + $this->state = self::STATE_AUTH; + + return ($result == self::RESULT_OK); + } + + public function logout() + { + $result = $this->runCommandAndGetResult("logout"); + if($result == self::RESULT_OK) + $this->state = self::STATE_UNAUTH; + + return ($result == self::RESULT_OK); + } + + public function noop() + { + $result = $this->runCommandAndGetResult("noop"); + return ($result == self::RESULT_OK); + } + + protected $hierarchydelimiter = null; + + public function getHierarchyDelimiter() + { + if($this->hierarchydelimiter != null) + return $this->hierarchydelimiter; + + if($info = $this->getlist('', '')) + { + $this->hierarchydelimiter = $info[0]['delimiter']; + return $this->hierarchydelimiter; + } + + return $info; + } + + // API break as "list" is PHP keyword... + public function getlist($reference = '', $mailboxname = '*') + { + $tag = self::generateTag(); + $response = $this->sendCommand($tag, "list", array($reference, $mailboxname)); + $result = self::getResultStatus($tag, $response); + + if($result == self::RESULT_OK) + { + // unserialize response + $list = array(); + + foreach($response as $line) + { + if(preg_match('/\*\sLIST\s\((.*)\)\s\"(.*?)\"\s\"(.*?)\"/', $line, $matches)) + { + $list[] = array('attributes' => $matches[1], + 'delimiter' => $matches[2], + 'name' => $matches[3] + ); + } + } + + return $list; + } + + return false; + } + + protected $capabilities = null; + + public function hasCapability($id) + { + if($this->capabilities == null) + $this->capability(); + + foreach($this->capabilities as $capability) + { + if($id == $capability) + return true; + } + return false; + } + + public function capability() + { + // cache this call + if($this->capabilities) + return $this->capabilities; + + $tag = self::generateTag(); + $response = $this->sendCommand($tag, "capability"); + $result = self::getResultStatus($tag, $response); + + if($result == self::RESULT_OK) + { + foreach($response as $line) + { + if(preg_match('/\*\sCAPABILITY\s(.*?)$/i', $line, $matches)) + { + $this->capabilities = explode(" ", $matches[1]); + return $this->capabilities; + } + } + } + + return false; + } + + public function create($name) + { + $result = $this->runCommandAndGetResult("create", array($name)); + return ($result == self::RESULT_OK); + } + + public function delete($name) + { + $result = $this->runCommandAndGetResult("delete", array($name)); + return ($result == self::RESULT_OK); + } + + public function rename($name, $newname) + { + $result = $this->runCommandAndGetResult("rename", array($name, $newname)); + return ($result == self::RESULT_OK); + } + + // RFC 2087 - QUOTA (Extension) + const QUOTA_TYPE_STORAGE = "STORAGE"; + const QUOTA_TYPE_MESSAGE = "MESSAGE"; + + public function getquota($quotaroot) + { + $tag = self::generateTag(); + $response = $this->sendCommand($tag, "getquota", array($quotaroot)); + $result = self::getResultStatus($tag, $response); + + if($result == self::RESULT_OK) + { + foreach($response as $line) + { + if(preg_match('/\*\sQUOTA\s'.$quotaroot.'\s\((\w)*\s(\d+)\s(\d+)\)/i', $line, $matches)) + { + return array( + 'resource' => $matches[1], + 'current' => $matches[2], + 'max' => $matches[3], + ); + } + } + } + + // OK -> not set, NO -> not set + if($result != self::RESULT_BAD) + { + return array( + 'resource' => null, + 'current' => null, + 'max' => null + ); + } + + return false; + } + + public function setquota($quotaroot, $quota = null, $resource = self::QUOTA_TYPE_STORAGE) + { + $tag = self::generateTag(); + $args = ' "'.$quotaroot.'" ('; + if($quota == 0 || $quota == null) + $args .= ')'; + else + $args .= $resource.' '.intval($quota).')'; + $response = $this->sendCommand($tag, "setquota", $args); + $result = self::getResultStatus($tag, $response); + + return ($result == self::RESULT_OK); + } + + // RFC 4314 - ACL (Extension) + const ACL_NONE = ''; + const ACL_LOOKUP = 'l'; + const ACL_READ = 'r'; + const ACL_SEEN = 's'; + const ACL_WRITE = 'w'; + const ACL_INSERT = 'i'; + const ACL_POST = 'p'; + + const ACL_CREATE = 'c'; // obsolete/depreciated + const ACL_DELETE = 'd'; // obsolete/depreciated + + const ACL_ADMIN = 'a'; + + const ACL_CREATEMB = 'k'; + const ACL_DELETEMB = 'x'; + const ACL_EXPUNGE = 'e'; + const ACL_DELETEMSGS = 't'; + + public function getAvailableACL() + { + $result = self::ACL_LOOKUP. + self::ACL_READ. + self::ACL_SEEN. + self::ACL_WRITE. + self::ACL_INSERT. + self::ACL_POST. + self::ACL_CREATE. + self::ACL_DELETE. + self::ACL_ADMIN; + + // add additional rights set in the capabilities + if($this->capabilities == null) + $this->capability(); + + foreach($this->capabilities as $capability) + { + if(preg_match('/RIGHTS=([kxte]*)/i', $capability, $matches)) + { + $result .= $matches[1]; + break; + } + } + + return $result; + } + + public function getacl($mailboxname) + { + $tag = self::generateTag(); + $response = $this->sendCommand($tag, "getacl", array($mailboxname)); + $result = self::getResultStatus($tag, $response); + + if($result == self::RESULT_OK) + { + foreach($response as $line) + { + // grab acl list + if(preg_match('/\*\sACL\s[^\s]*\s(.*)/', $line, $matches)) + { + // grab all acls + if(preg_match_all('/([^\s]*)\s(['.$this->getAvailableACL().']*)/', $matches[1], $matches)) + { + return array_combine($matches[1], $matches[2]); + } + } + } + } + + return false; + } + + public function setacl($mailboxname, $identifier, $aclmodification) + { + $result = $this->runCommandAndGetResult("setacl", array($mailboxname, $identifier, $aclmodification)); + return ($result == self::RESULT_OK); + } + + public function deleteacl($mailboxname, $identifier) + { + $result = $this->runCommandAndGetResult("deleteacl", array($mailboxname, $identifier)); + return ($result == self::RESULT_OK); + } +} + +?> diff --git a/apps/admin/lib/imap/IMAPManager.php b/apps/admin/lib/imap/IMAPManager.php new file mode 100644 index 0000000..0cac78a --- /dev/null +++ b/apps/admin/lib/imap/IMAPManager.php @@ -0,0 +1,48 @@ +openConnection( + $imap_settings['host'].":". + $imap_settings['port'] + ); + + $success = self::$adminclient->login( + $imap_settings['admin'], + $imap_settings['pass'] + ); + + if(!$success) + throw new Exception("Failed to authenticate on IMAP server."); + + } catch (Exception $e) { + LogEntryPeer::log($e->getMessage(), LogEntry::PRIO_ALERT); + } + + return self::$adminclient; + } + + public static function getAdminUsername() + { + $server_settings = sfConfig::get('app_server_default'); + $imap_settings = $server_settings['imap']; + return $imap_settings['admin']; + } +} + +?> diff --git a/apps/admin/lib/imap/IMAPServerInformation.php b/apps/admin/lib/imap/IMAPServerInformation.php new file mode 100644 index 0000000..e185bae --- /dev/null +++ b/apps/admin/lib/imap/IMAPServerInformation.php @@ -0,0 +1,63 @@ +imap = IMAPManager::getAdminConnection(); + } + + public function getGreeting() + { + return substr($this->imap->getGreeting(), 5); + } + + public function getServerName() + { + return $this->imap->getServerName(); + } + + public function getServerVersion() + { + return $this->imap->getServerVersion(); + } + + public function hasCapability($name) + { + return $this->imap->hasCapability($name); + } + + public function getCapabilties() + { + if(!($c = $this->imap->capability())) + $c = array(); + return $c; + } + + public function getHierarchyDelimiter() + { + return $this->imap->getHierarchyDelimiter(); + } + + public function getAvailableACL() + { + if(!$this->imap->hasCapability('ACL')) + return false; + + return $this->imap->getAvailableACL(); + } + + public function getHost() + { + return substr($this->imap->getURI(), 0, strpos($this->imap->getURI(), ":")); + } + + public function getPort() + { + return substr($this->imap->getURI(), strpos($this->imap->getURI(), ":")+1); + } +} + +?> diff --git a/apps/admin/lib/myChangeNicknameValidator.php b/apps/admin/lib/myChangeNicknameValidator.php new file mode 100644 index 0000000..e8dfdb1 --- /dev/null +++ b/apps/admin/lib/myChangeNicknameValidator.php @@ -0,0 +1,43 @@ +setParameter('change_error', 'Invalid input'); + + $this->getParameterHolder()->add($parameters); + + return true; + } + + public function execute(&$value, &$error) + { + $current_nickname = $this->getContext()->getUser()->getNickname(); + + $new_nickname = $value; + + // changed the nickname? + if($new_nickname == $current_nickname) + return true; + + $c = new Criteria(); + $c->add(UserPeer::NICKNAME, $new_nickname); + $user = UserPeer::doSelectOne($c); + + // nickname exists? + if($user) + { + $error = $this->getParameter('change_error'); + return false; + } + + return true; + } +} + +?> diff --git a/apps/admin/lib/myDenyStringValidator.php b/apps/admin/lib/myDenyStringValidator.php new file mode 100644 index 0000000..d817ea9 --- /dev/null +++ b/apps/admin/lib/myDenyStringValidator.php @@ -0,0 +1,38 @@ +setParameter('values_error', 'Invalid input'); + + $this->getParameterHolder()->add($parameters); + + return true; + } + + public function execute(&$value, &$error) + { + $values = $this->getParameter('values'); + + if(!is_array($values)) + return true; + + foreach($values as $check) + { + if($check==$value) + { + $error = $this->getParameter('values_error'); + return false; + } + } + + return true; + } +} + +?> diff --git a/apps/admin/lib/myLoginValidator.php b/apps/admin/lib/myLoginValidator.php new file mode 100644 index 0000000..03890aa --- /dev/null +++ b/apps/admin/lib/myLoginValidator.php @@ -0,0 +1,45 @@ +setParameter('login_error', 'Invalid input'); + + $this->getParameterHolder()->add($parameters); + + return true; + } + + public function execute(&$value, &$error) + { + $password_param = $this->getParameter('password'); + $password = $this->getContext()->getRequest()->getParameter($password_param); + + $login = $value; + + $c = new Criteria(); + $c->add(UserPeer::NICKNAME, $login); + $user = UserPeer::doSelectOne($c); + + // nickname exists? + if ($user) + { + // password is OK? + if (sha1($user->getSalt().$password) == $user->getSha1Password()) + { + $this->getContext()->getUser()->signIn($user); + return true; + } + } + + $error = $this->getParameter('login_error'); + return false; + } +} + +?> diff --git a/apps/admin/lib/myUser.class.php b/apps/admin/lib/myUser.class.php new file mode 100644 index 0000000..2f67e51 --- /dev/null +++ b/apps/admin/lib/myUser.class.php @@ -0,0 +1,83 @@ +setAuthenticated(true); + + // TODO: set credentials + $this->addCredential($user->getRole()->getCredentials()); + + // set session attributes + $this->updateUserAttributes($user); + + $this->setResultsPerPage(sfConfig::get("app_pagination_results_per_page")); + + LogEntryPeer::log("User logged in.", LogEntry::PRIO_INFO); + + $user->setLastlogin(time()); + $user->save(); + } + + public function updateUserAttributes($user) + { + $this->setAttribute("nickname", $user->getNickname(), "user"); + $this->setAttribute("role", $user->getRole()->getName(), "user"); + $this->setAttribute("role_id", $user->getRole()->getId(), "user"); + $this->setAttribute("user_id", $user->getId(), "user"); + $this->setAttribute("lastlogin", $user->getLastLogin(), "user"); + } + + public function signOut($user) + { + LogEntryPeer::log("User logged out.", LogEntry::PRIO_INFO); + + $this->setAuthenticated(false); + $this->clearCredentials(); + $this->getAttributeHolder()->removeNamespace("user"); + $this->getAttributeHolder()->removeNamespace("pager"); + } + + public function getResultsPerPage() + { + return $this->getAttribute("max_per_page", sfConfig::get("app_pager_max_per_page"), "pager"); + } + + + public function setResultsPerPage($count) + { + $this->setAttribute("max_per_page", $count, "pager"); + } + + public function getDomainPermissions($c = null) + { + $user = UserPeer::retrieveByPK($this->getId()); + return $user->getDomainPermissions($c); + } + + public function getId() + { + return $this->getAttribute("user_id", '', "user"); + } + + public function getLastLogin() + { + return $this->getAttribute("lastlogin", '', "user"); + } + + public function getRoleId() + { + return $this->getAttribute("role_id", '', "user"); + } + + public function getRoleName() + { + return $this->getAttribute("role", '', "user"); + } + + public function getNickname() + { + return $this->getAttribute("nickname", '', "user"); + } +} diff --git a/apps/admin/modules/address/actions/actions.class.php b/apps/admin/modules/address/actions/actions.class.php new file mode 100644 index 0000000..d042fbf --- /dev/null +++ b/apps/admin/modules/address/actions/actions.class.php @@ -0,0 +1,165 @@ +hasRequestParameter("max_per_page")) + $this->getUser()->setResultsPerPage($this->getRequestParameter("max_per_page")); + + return parent::executeList(); + } + + public function executeCreate() + { + $this->setTemplate("edit"); + $result = $this->executeEdit(); + + if($this->getRequest()->getMethod() == sfRequest::GET) + { + if(!$this->hasRequestParameter("id")) + { + $this->updateAddressFromRequest(); + } + $this->address->setActive(true); + $this->address->setSaveInMailbox(true); + } + + return $result; + } + + public function handleErrorCreate() + { + $this->setTemplate("edit"); + return $this->handleErrorEdit(); + } + + public function validateCreate() + { + return $this->validateEdit(); + } + + public function validateEdit() + { + $i18n = sfI18N::getInstance(); + + if($this->getRequest()->getMethod() == sfRequest::GET) + return true; + + $newaddress = $this->getRequestParameter('address'); + if($newaddress["domain_id"]=='') + { + $this->getRequest()->setError('address{alias}', 'A domain must be selected'); + return false; + } + + $address = new Address(); + + if($this->getRequest()->hasParameter('id')) + $address = AddressPeer::retrieveByPk($this->getRequestParameter('id')); + + // if we got different values than the current record already has + if($this->getActionName()=="create" || + $address->getLocalpart() != $newaddress["localpart"] || + $address->getDomainId() != $newaddress["domain_id"] + ) + { + // check if localpart@domain is already used + $c = new Criteria(); + $c->add(AddressPeer::LOCALPART, $newaddress["localpart"]); + $c->add(AddressPeer::DOMAIN_ID, $newaddress["domain_id"]); + $checkaddress = AddressPeer::doSelectOne($c); + if($checkaddress) + { + $this->getRequest()->setError('address{alias}', $i18n->__('The address "%1%" already exists', array("%1%"=>$checkaddress))); + return false; + } + } + + // check if either save to mailbox option or destination is set to satisfy message routing + if(!isset($newaddress["save_in_mailbox"]) && $newaddress["destination"]=='') + { + $this->getRequest()->setError('address{save_in_mailbox}', 'If messages are not saved in the mailbox, the forward destination has to be set'); + $this->getRequest()->setError('address{destination}', 'Destination can not be empty if the message is not saved in the mailbox'); + return false; + + } + + // verify destination list + $ev = new sfEmailValidator(); + $destinations = Address::getDestinationAsArray($newaddress["destination"]); + foreach($destinations as $dest) + { + if($dest=='') + continue; + + // check email + if(strpos($dest, "@") !== false) + { + $error = ''; + $ev->initialize($this->getContext(), array( + 'email_error' => $i18n->__('Invalid E-Mail address "%1%"', array("%1%" => $dest)) + )); + + if(!$ev->execute($dest, $error)) + { + $this->getRequest()->setError('address{destination}', $error); + return false; + } + } + else // check if mailbox name is valid + { + // superadmin has all freedom + if($this->getUser()->hasCredential("superadmin")) + continue; + + $c = new Criteria(); + $c->add(MailboxPeer::NAME, $dest); + $mailbox = MailboxPeer::doSelectOne($c); + if(!$mailbox) + { + // no such target + $this->getRequest()->setError('address{destination}', $i18n->__('Mailbox "%1%" does not exist', array("%1%" => $dest))); + return false; + } + + // check permissions + $c = new Criteria(); + $c->add(DomainPermissionPeer::DOMAIN_ID, $mailbox->getDomainId()); + $permissions = $this->getUser()->getDomainPermissions($c); + if(!$permissions) + { + $this->getRequest()->setError('address{destination}', $i18n->__('No permissions to use Mailbox "%1%" as destination', array("%1%" => $dest))); + return false; + } + } + } + + return true; + } + + protected function updateAddressFromRequest() + { + $address = $this->getRequestParameter('address'); + + if (isset($address['localpart'])) + { + $this->address->setLocalpart($address['localpart']); + } + if (isset($address['domain_id'])) + { + $this->address->setDomainId($address['domain_id']); + } + + return parent::updateAddressFromRequest(); + } +} diff --git a/apps/admin/modules/address/config/generator.yml b/apps/admin/modules/address/config/generator.yml new file mode 100644 index 0000000..2bd2e44 --- /dev/null +++ b/apps/admin/modules/address/config/generator.yml @@ -0,0 +1,48 @@ +generator: + class: sfPropelAdminGenerator + param: + model_class: Address + theme: mailadmin + + fields: + destination: { name: Destination } + mailbox_id: { name: Mailbox } + active: { name: Active } + + list: + peer_method: doSelectJoinAll + title: List of Addresses + display: [=_localpart, _domain_id, _destination, active, _mailbox_id] + filters: [alias, domain_id, active, mailbox_id, destination] + max_per_page: '$this->getUser()->getResultsPerPage("pager")' + sort: [mailbox_id, asc] + fields: + localpart: { name: Address, params: align=right } + domain_id: { params: align=left } + alias: { params: align=left } + destination: { params: align=left } + active: { params: align=center width=1% } + mailbox_id: { params: align=right } + object_actions: + edit: { name: Edit Address, action: edit, icon: edit.gif } + delete: { name: Delete Address, action: delete, icon: trash.gif, params: confirm=Are you sure? } + actions: {} + + create: + title: Create New Address + + edit: + title: 'Editing Address %%alias%%' + display: + 'Address': [_alias, active, mailbox_id] + 'Destination': [save_in_mailbox, destination] + fields: + mailbox_id: { name: For Mailbox, help: 'The primary mailbox for this address' } + alias: { name: Address, help: 'Leave blank if this is a catch all address' } + save_in_mailbox: { name: Save to Mailbox, type: checkbox_tag, help: 'Incoming messages are saved, then forwarded' } + destination: { name: Forward to these Destinations, params: size=51x8, help: 'E-Mail addresses and/or mailbox names, one per line or comma-seperated' } + active: { name: Active, help: Inactive addresses are not routed } + actions: + _save_and_list: { name: Save } + _save_and_add: { name: 'Save, then create new one' } + _list: { name: Cancel } diff --git a/apps/admin/modules/address/templates/_alias.php b/apps/admin/modules/address/templates/_alias.php new file mode 100644 index 0000000..e6550c1 --- /dev/null +++ b/apps/admin/modules/address/templates/_alias.php @@ -0,0 +1,9 @@ + 25, + 'control_name' => 'address[localpart]', + 'style' => 'text-align:right', +)); echo $value ? $value : ' ' ?> @ 'Domain', + 'control_name' => 'address[domain_id]', + 'include_blank' => true, +)); echo $value ? $value : ' ' ?> diff --git a/apps/admin/modules/address/templates/_destination.php b/apps/admin/modules/address/templates/_destination.php new file mode 100644 index 0000000..f01676c --- /dev/null +++ b/apps/admin/modules/address/templates/_destination.php @@ -0,0 +1,23 @@ + +getDestination()); + if($address->getSaveInMailbox()) + $list = array_merge(array($address->getMailbox()->getName()), $list); +?> +
diff --git a/apps/admin/modules/address/templates/_domain_id.php b/apps/admin/modules/address/templates/_domain_id.php new file mode 100644 index 0000000..bb51b3d --- /dev/null +++ b/apps/admin/modules/address/templates/_domain_id.php @@ -0,0 +1 @@ +@getDomain() ?> diff --git a/apps/admin/modules/address/templates/_localpart.php b/apps/admin/modules/address/templates/_localpart.php new file mode 100644 index 0000000..e01fe5d --- /dev/null +++ b/apps/admin/modules/address/templates/_localpart.php @@ -0,0 +1 @@ +isCatchAll() ? "*": $address->getLocalpart() ) ?> diff --git a/apps/admin/modules/address/templates/_mailbox_id.php b/apps/admin/modules/address/templates/_mailbox_id.php new file mode 100644 index 0000000..0ab885b --- /dev/null +++ b/apps/admin/modules/address/templates/_mailbox_id.php @@ -0,0 +1 @@ +getMailbox() ?> diff --git a/apps/admin/modules/address/validate/create.yml b/apps/admin/modules/address/validate/create.yml new file mode 100644 index 0000000..a55efed --- /dev/null +++ b/apps/admin/modules/address/validate/create.yml @@ -0,0 +1,10 @@ +fillin: + enabled: true + +fields: + address{domain_id}: + required: + msg: A domain has to be selected + address{mailbox_id}: + required: + msg: A primary mailbox has to be selected diff --git a/apps/admin/modules/address/validate/edit.yml b/apps/admin/modules/address/validate/edit.yml new file mode 100644 index 0000000..a55efed --- /dev/null +++ b/apps/admin/modules/address/validate/edit.yml @@ -0,0 +1,10 @@ +fillin: + enabled: true + +fields: + address{domain_id}: + required: + msg: A domain has to be selected + address{mailbox_id}: + required: + msg: A primary mailbox has to be selected diff --git a/apps/admin/modules/content/actions/actions.class.php b/apps/admin/modules/content/actions/actions.class.php new file mode 100644 index 0000000..bbc9d08 --- /dev/null +++ b/apps/admin/modules/content/actions/actions.class.php @@ -0,0 +1,18 @@ +redirect($this->getRequest()->getReferer(), '@homepage'); + } +} diff --git a/apps/admin/modules/domain/actions/actions.class.php b/apps/admin/modules/domain/actions/actions.class.php new file mode 100644 index 0000000..badbf03 --- /dev/null +++ b/apps/admin/modules/domain/actions/actions.class.php @@ -0,0 +1,47 @@ +hasRequestParameter("max_per_page")) + $this->getUser()->setResultsPerPage($this->getRequestParameter("max_per_page")); + + return parent::executeList(); + } + + public function executeCreate() + { + // populate preset values + $this->getRequest()->setParameter('domain[creator_id]', $this->getUser()->getId()); + + $this->setTemplate("edit"); + return $this->executeEdit(); + } + + public function handleErrorCreate() + { + $this->setTemplate("edit"); + return $this->handleErrorEdit(); + } + + public function executeCreateMailbox() + { + $domain = DomainPeer::retrieveByPk($this->getRequestParameter('id')); + $this->redirect("mailbox/create?mailbox[domain_id]=".$domain->getId()."&mailbox[name]=".sprintf("%s%d", $domain->getMailboxPrefix(), $domain->getMailboxCount()+1)."&mailbox[max_quota]=".$domain->getDefaultMailboxQuota() ); + } + + public function executeViewMailboxes() + { + $this->redirect("mailbox/list?filter=filter&filters[domain_id]=".$this->getRequestParameter('id')); + } +} diff --git a/apps/admin/modules/domain/config/generator.yml b/apps/admin/modules/domain/config/generator.yml new file mode 100644 index 0000000..df971b3 --- /dev/null +++ b/apps/admin/modules/domain/config/generator.yml @@ -0,0 +1,53 @@ +generator: + class: sfPropelAdminGenerator + param: + model_class: Domain + theme: mailadmin + + fields: + name: { name: Domain } + mailbox_prefix: { name: Mailbox Prefix } + max_mailbox_count: { name: Max Mailbox Count } + quota: { name: Quota } + creator: { name: Created by } + + list: + title: List of Domains + display: [=name, user, mailbox_prefix, _max_mailbox_count, _quota, _default_mailbox_quota] + filters: [name, mailbox_prefix, max_mailbox_count, quota, default_mailbox_quota] + max_per_page: '$this->getUser()->getResultsPerPage("pager")' + sort: [name, asc] + fields: + name: { params: align=left } + mailbox_prefix: { params: align=left } + user: { name: Created By, credentials: [[superadmin]] } + max_mailbox_count: { params: align=right } + mailbox_count: { params: align=right } + quota: { params: align=right } + default_mailbox_quota: { name: Default Mailbox Quota, params: align=right } + object_actions: + viewmailboxes: { name: View Mailboxes, action: viewMailboxes, icon: mail.gif } + createmailbox: { name: Create New Mailbox, action: createMailbox, icon: mail-new.gif } + edit: { name: Edit Domain, action: edit, icon: edit.gif, credentials: [[superadmin, domainmaster]] } + delete: { name: Delete Domain, action: delete, icon: trash.gif, credentials: [[superadmin, domainmaster]], params: confirm=Are you sure? } + actions: {} + + create: + title: Create New Domain + + edit: + title: 'Editing Domain %%name%%' + display: + 'General Settings': [name, mailbox_prefix] + 'Limits': [max_mailbox_count, quota, default_mailbox_quota] + fields: + name: { name: Domain Name, params: size=50 } + mailbox_prefix: { name: Prefix for new Mailboxes, params: size=50 onfocus='updatePrefixFromDomainName(this);' } + max_mailbox_count: { name: Maximum Number of Mailboxes, help: '0 = No Limit', params: size=50 } + quota: { name: Default Quota in kb, help: '0 = No Limit', params: size=50 } + default_mailbox_quota: { name: Quota for Domain in kb, help: '0 = No Limit', params: size=50 } + actions: + _save_and_list: { name: Save } + _save_and_add: { name: 'Save, then create new one' } + _list: { name: Cancel } + diff --git a/apps/admin/modules/domain/config/security.yml b/apps/admin/modules/domain/config/security.yml new file mode 100644 index 0000000..2431ebf --- /dev/null +++ b/apps/admin/modules/domain/config/security.yml @@ -0,0 +1,11 @@ +create: + is_secure: on + credentials: [[superadmin, domainmaster]] + +edit: + is_secure: on + credentials: [[superadmin, domainmaster]] + +all: + is_secure: on + diff --git a/apps/admin/modules/domain/templates/_default_mailbox_quota.php b/apps/admin/modules/domain/templates/_default_mailbox_quota.php new file mode 100644 index 0000000..272ad83 --- /dev/null +++ b/apps/admin/modules/domain/templates/_default_mailbox_quota.php @@ -0,0 +1 @@ +getDefaultMailboxQuota()==0 ? "Unlimited" : format_bytes($domain->getDefaultMailboxQuota()*1000)) ?> diff --git a/apps/admin/modules/domain/templates/_edit_header.php b/apps/admin/modules/domain/templates/_edit_header.php new file mode 100644 index 0000000..fed004a --- /dev/null +++ b/apps/admin/modules/domain/templates/_edit_header.php @@ -0,0 +1,13 @@ + + + diff --git a/apps/admin/modules/domain/templates/_max_mailbox_count.php b/apps/admin/modules/domain/templates/_max_mailbox_count.php new file mode 100644 index 0000000..8b7a70b --- /dev/null +++ b/apps/admin/modules/domain/templates/_max_mailbox_count.php @@ -0,0 +1 @@ +getMailboxCount() ?> / getMaxMailboxCount()==0 ? "Unlimited": $domain->getMaxMailboxCount()) ?> diff --git a/apps/admin/modules/domain/templates/_quota.php b/apps/admin/modules/domain/templates/_quota.php new file mode 100644 index 0000000..0b36b22 --- /dev/null +++ b/apps/admin/modules/domain/templates/_quota.php @@ -0,0 +1 @@ +getUsedQuota()*1000) ?> / getQuota()==0 ? "Unlimited" : format_bytes($domain->getQuota()*1000)) ?> diff --git a/apps/admin/modules/domain/validate/create.yml b/apps/admin/modules/domain/validate/create.yml new file mode 100644 index 0000000..c8183c2 --- /dev/null +++ b/apps/admin/modules/domain/validate/create.yml @@ -0,0 +1,46 @@ +fillin: + enabled: true + +validators: + myStringValidator: + class: sfStringValidator + param: + min: 2 + min_error: This field is too short (2 characters minimum) + max: 100 + max_error: This field is too long (100 characters maximum) + +fields: + domain{name}: + required: + msg: The Domain Name is required + myStringValidator: + sfRegexValidator: + match:..........Yes + match_error: 'The name must be in the form: example.org' + pattern: /[^.]+\.[^.]+$/si + sfPropelUniqueValidator: + class: Domain + column: name + unique_error: This domain already exists + domain{mailbox_prefix}: + required: + msg: The Mailbox Prefix is required + myStringValidator: + sfRegexValidator: + match: Yes + match_error: The prefix must only consist out of alphanumeric characters + pattern: /[A-z0-9]/si + sfPropelUniqueValidator: + class: Domain + column: mailbox_prefix + unique_error: This prefix already exists + domain{max_mailbox_count}: + required: + msg: The Mailbox Count is required + domain{quota}: + required: + msg: The Domain Quota is required + domain{default_mailbox_quota}: + required: + msg: The Mailbox Quota is required diff --git a/apps/admin/modules/domain/validate/edit.yml b/apps/admin/modules/domain/validate/edit.yml new file mode 100644 index 0000000..c8183c2 --- /dev/null +++ b/apps/admin/modules/domain/validate/edit.yml @@ -0,0 +1,46 @@ +fillin: + enabled: true + +validators: + myStringValidator: + class: sfStringValidator + param: + min: 2 + min_error: This field is too short (2 characters minimum) + max: 100 + max_error: This field is too long (100 characters maximum) + +fields: + domain{name}: + required: + msg: The Domain Name is required + myStringValidator: + sfRegexValidator: + match:..........Yes + match_error: 'The name must be in the form: example.org' + pattern: /[^.]+\.[^.]+$/si + sfPropelUniqueValidator: + class: Domain + column: name + unique_error: This domain already exists + domain{mailbox_prefix}: + required: + msg: The Mailbox Prefix is required + myStringValidator: + sfRegexValidator: + match: Yes + match_error: The prefix must only consist out of alphanumeric characters + pattern: /[A-z0-9]/si + sfPropelUniqueValidator: + class: Domain + column: mailbox_prefix + unique_error: This prefix already exists + domain{max_mailbox_count}: + required: + msg: The Mailbox Count is required + domain{quota}: + required: + msg: The Domain Quota is required + domain{default_mailbox_quota}: + required: + msg: The Mailbox Quota is required diff --git a/apps/admin/modules/log/actions/actions.class.php b/apps/admin/modules/log/actions/actions.class.php new file mode 100644 index 0000000..9eed7c7 --- /dev/null +++ b/apps/admin/modules/log/actions/actions.class.php @@ -0,0 +1,46 @@ +hasRequestParameter("max_per_page")) + $this->getUser()->setResultsPerPage($this->getRequestParameter("max_per_page")); + + return parent::executeList(); + } + + public function executeClear() + { + if($this->getRequest()->getMethod() == sfRequest::POST) + { + if($this->getRequestParameter("commit")=="Yes") + { + LogEntryPeer::doDeleteAll(); + return $this->redirect("log", "list"); + } + + } + + return sfView::SUCCESS; + } + + public function executeCreate() + { + return $this->forward404(); + } + + public function executeEdit() + { + return $this->forward404(); + } +} diff --git a/apps/admin/modules/log/config/generator.yml b/apps/admin/modules/log/config/generator.yml new file mode 100644 index 0000000..553b1c2 --- /dev/null +++ b/apps/admin/modules/log/config/generator.yml @@ -0,0 +1,30 @@ +generator: + class: sfPropelAdminGenerator + param: + model_class: LogEntry + theme: mailadmin + + fields: + created_at: { name: Time } + user_id: { name: User } + host: { name: Host } + priority: { name: Type } + + list: + peer_method: doSelectJoinUser + title: Logs + display: [created_at, _priority, message, _user_id, host] + filters: [created_at, priority, message, user_id, host] + max_per_page: '$this->getUser()->getResultsPerPage("pager")' + sort: [created_at, desc] + fields: + created_at: { params: align=left center } + user_id: { params: align=left } + message: { params: align=left } + host: { params: align=left } + priority: { params: align=left } + object_actions: + delete: { name: Delete, action: delete, icon: trash.gif, params: confirm=Are you sure? } + actions: {} + + edit: {} diff --git a/apps/admin/modules/log/config/security.yml b/apps/admin/modules/log/config/security.yml new file mode 100644 index 0000000..60868c9 --- /dev/null +++ b/apps/admin/modules/log/config/security.yml @@ -0,0 +1,2 @@ +all: + credentials: [superadmin] diff --git a/apps/admin/modules/log/templates/_priority.php b/apps/admin/modules/log/templates/_priority.php new file mode 100644 index 0000000..2427ac7 --- /dev/null +++ b/apps/admin/modules/log/templates/_priority.php @@ -0,0 +1 @@ +getPriority()<3?"information.gif":($log_entry->getPriority()<4?"warning.gif":"error.gif")),"alt=[!] border=0") ?>getLevel() ?> diff --git a/apps/admin/modules/log/templates/_user_id.php b/apps/admin/modules/log/templates/_user_id.php new file mode 100644 index 0000000..737a1c7 --- /dev/null +++ b/apps/admin/modules/log/templates/_user_id.php @@ -0,0 +1 @@ +getUser() ? $log_entry->getUser(): "Anonymous") ?> diff --git a/apps/admin/modules/log/templates/clearSuccess.php b/apps/admin/modules/log/templates/clearSuccess.php new file mode 100644 index 0000000..83508eb --- /dev/null +++ b/apps/admin/modules/log/templates/clearSuccess.php @@ -0,0 +1,12 @@ +Connection: | +|
---|---|
Host: | +getHost() ?> | +
Port: | +getPort() ?> | +
General: | +|
Greeting: | +getGreeting() ?> | +
Server: | +getServerName() ?> | +
Version: | +getServerVersion() ?> | +
Hierarchy Delimiter: | +getHierarchyDelimiter() ?> | +
Capabilities: | +", $serverinfo->getCapabilties()) ?> | +
Extension: Access Control List (ACL) | +|
Available ACL: | +getAvailableACL() ?> | +