--- /dev/null
+<?php
+
+if ($_SESSION['mask'] == 'alias') {
+ $title = "Weiterleitungen";
+ $condition = 'islist = 0';
+ $dest_title = "Ziel-Adresse";
+ $dest_type = 'text';
+ $active_title = "Weiterleitung aktiv";
+ $islist = '0';
+} elseif ($_SESSION['mask'] == 'list') {
+ $title = "Mailing-Listen";
+ $condition = 'islist = 1';
+ $dest_title = "Listen-Mitglieder";
+ $dest_type = 'textarea';
+ $active_title = "Liste aktiv";
+ $islist = '1';
+} else {
+ throw new Exception('Unknown mask ' . $_SESSION['mask']);
+}
+
+JavaScript::instance()->file('vmail.js');
+JavaScript::instance()->add("Hallinta.preDelete = alias_pre_delete;");
+
+$mask = array(
+ 'table' => 'vmail_alias',
+ 'title' => $title,
+ 'join' => array('vmail_domain ON vmail_domain_id = vmail_domain.id'),
+ 'where' => $condition,
+ 'list' => array(
+ 'id' => array(
+ 'name' => 'ID',
+ 'visible' => false,
+ 'sql' => 'vmail_alias.id',
+ ),
+ 'name' => array(
+ 'name' => 'Domain',
+ 'visible' => false,
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 's',
+ ),
+ 'username' => array(
+ 'name' => 'Username',
+ 'visible' => false,
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 't',
+ ),
+ 'email' => array(
+ 'name' => 'Adresse',
+ 'width' => 300,
+ 'type' => 'text',
+ 'filter' => 't',
+ 'sql' => "username || '@' || name",
+ ),
+ 'dest' => array(
+ 'name' => $dest_title,
+ 'width' => 400,
+ 'type' => 'text',
+ 'filter' => 't',
+ 'sql' => "substring(destination from 1 for 100)",
+ ),
+ 'active' => array(
+ 'name' => 'aktiv',
+ 'width' => 40,
+ 'specs' => array('ClassName' => 'aligncenter has-checkbox'),
+ 'control' => "new Rico.TableColumn.checkbox(1,0,0,1)",
+ ),
+ ),
+ 'edit' => array(
+ 'username' => array(
+ 'name' => 'Local Part',
+ 'type' => 'text',
+ 'size' => 21,
+ 'required' => true,
+ ),
+ 'vmail_domain_id' => array(
+ 'name' => 'Domain',
+ 'type' => 'select',
+ 'options' => 'SELECT id,name AS text FROM vmail_domain ORDER BY name',
+ 'option_empty' => '-- select --',
+ 'required' => true,
+ ),
+ 'destination' => array(
+ 'name' => $dest_title,
+ 'type' => $dest_type,
+ 'rows' => 10,
+ 'required' => true,
+ ),
+ 'islist' => array(
+ 'type' => 'hidden',
+ 'default' => $islist,
+ ),
+ 'active' => array(
+ 'name' => $active_title,
+ 'type' => 'boolean',
+ ),
+ ),
+ );
--- /dev/null
+<?php
+
+class VMail_Alias extends DatabaseTable {
+ public function __construct($id=false)
+ {
+ parent::__construct('vmail_alias', $id);
+ }
+
+ public function deleteFromDestination($email, $commit=false)
+ {
+ $report = '';
+ $email = strtolower($email);
+
+ $sql = sprintf("SELECT id, username, vmail_domain_id, destination FROM vmail_alias WHERE destination ILIKE %s",
+ $this->db->quote('%'.$email.'%'));
+
+ foreach ($this->db->fetchObjectList($sql) as $row) {
+ $domain = new VMail_Domain($row->vmail_domain_id);
+ $report .= sprintf("Lösche %s aus Alias %s@%s\n",
+ $email,
+ $row->username, $domain->get('name'));
+
+ $destination = array_map("trim", preg_split("/(\r?\n|\r|,)/", strtolower(trim($row->destination, " \n\r\t\v\x00,"))));
+
+ if (count($destination) == 1) {
+ $alias = new VMail_Alias($row->id);
+ $report .= $alias->deleteAlias($commit);
+ } else {
+ $idx = array_search($email, $destination);
+ if ($idx !== false) {
+ unset($destination[$idx]);
+ if (count($destination) < 5)
+ $dst_new = implode(", ", $destination);
+ else
+ $dst_new = implode("\r\n", $destination);
+ $sql = sprintf("UPDATE vmail_alias SET destination = %s WHERE id = %d",
+ $this->db->quote($dst_new), $row->id);
+ if ($commit)
+ $this->db->execute($sql);
+ }
+ }
+ }
+
+ return $report;
+ }
+
+ public function deleteFromRoundcubeIdentities($email, $commit=false)
+ {
+ $report = '';
+
+ foreach (['ROUNDCUBE_DBDRIVER', 'ROUNDCUBE_DBHOST', 'ROUNDCUBE_DBNAME', 'ROUNDCUBE_DBUSER', 'ROUNDCUBE_DBPASS'] AS $key)
+ if (!defined($key))
+ throw new Exception("Configuration define {$key} not set");
+
+ $rdb = new Database(ROUNDCUBE_DBDRIVER, ROUNDCUBE_DBHOST, ROUNDCUBE_DBNAME, ROUNDCUBE_DBUSER, ROUNDCUBE_DBPASS);
+ if (defined('MAIL_ERROR')) $rdb->setErrorMail(MAIL_ERROR);
+
+ $sql = sprintf("SELECT identity_id,name,email,username FROM identities JOIN users using(user_id) WHERE email ILIKE %s",
+ $rdb->quote($email));
+ foreach ($rdb->fetchObjectList($sql) as $row) {
+ $name = $row->username;
+ if ($row->name)
+ $name .= " (" . $row->name . ")";
+ $report .= sprintf("Lösche %s aus den Roundcube Identitäten des Users %s\n",
+ $email, $name);
+ $sql = sprintf("DELETE FROM identities WHERE identity_id = %d", $row->identity_id);
+ if ($commit)
+ $rdb->execute($sql);
+ }
+
+ $parts = explode('@', $email);
+ $sql = sprintf("SELECT user_id FROM users WHERE username = %s", $rdb->quote($parts[0]));
+ foreach ($rdb->fetchObjectList($sql) as $row) {
+ $report .= sprintf("Lösche User %s aus Roundcube Usern\n", $parts[0]);
+ $sql = sprintf("DELETE FROM users WHERE user_id = %d", $row->user_id);
+ if ($commit)
+ $rdb->execute($sql);
+ }
+
+ return $report;
+ }
+
+ public function deleteAlias($commit=false)
+ {
+ if (!$this->id)
+ throw new Exception("No user id provided");
+
+ $report = '';
+
+ $domain = new VMail_Domain($this->data->vmail_domain_id);
+ $email = sprintf("%s@%s", $this->data->username, $domain->get('name'));
+
+ $report .= $this->deleteFromDestination($email, $commit);
+
+ if (defined('ROUNDCUBE_DBDRIVER')) {
+ $report .= $this->deleteFromRoundcubeIdentities($email, $commit);
+ }
+
+ $report .= sprintf("Lösche %s aus Aliasen\n", $email);
+ $sql = sprintf("DELETE FROM %s WHERE id = %d", $this->table, $this->id);
+ if ($commit)
+ $this->db->execute($sql);
+
+ return $report;
+ }
+
+ public function ajaxDeleteReport(Array $data)
+ {
+ $report = $this->deleteAlias(false);
+ return ['report' => nl2br($report)];
+ }
+
+ public function ajaxDeleteAlias(Array $data)
+ {
+ $domain = new VMail_Domain($this->data->vmail_domain_id);
+ $report = $this->deleteAlias(true);
+
+ return ['text' => sprintf("Alias %s@%s gelöscht", $this->data->username, $domain->get('name'))];
+ }
+}
--- /dev/null
+<?php
+
+class VMail_Domain extends DatabaseTable {
+ public function __construct($id=false)
+ {
+ parent::__construct('vmail_domain', $id);
+ }
+}
--- /dev/null
+<?php
+
+class VMail_Folder extends DatabaseTable {
+ public function __construct($id=false)
+ {
+ parent::__construct('vmail_folder', $id);
+ }
+
+ protected function setMailboxPermissions($row, $value, $other_id)
+ {
+ $sql = sprintf("SELECT username || '@' || name
+FROM vmail_user
+JOIN vmail_domain ON vmail_domain.id = vmail_domain_id
+WHERE vmail_user.id = %d",
+ $other_id);
+ $other = $this->db->fetchValue($sql);
+
+ if ($value) {
+ $sql = sprintf("SELECT id FROM vmail_folder_user WHERE vmail_folder_id = %d AND vmail_user_id = %d",
+ $row->vmail_folder_id,
+ $other_id);
+ $id = $this->db->fetchValue($sql);
+ if ($id)
+ return true;
+
+ $sql = sprintf("INSERT INTO vmail_folder_user (vmail_folder_id,vmail_user_id,sys_user,sys_edit) VALUES (%d,%d,%s,now())",
+ $row->vmail_folder_id,
+ $other_id,
+ $this->db->quote($_SESSION['sys']['login']));
+
+ $cmd = sprintf('sudo -u vmail /etc/dovecot/share-folder-add %s %s %s > /dev/null 2>&1',
+ $row->from_user, $row->folder, $other);
+ } else {
+ $sql = sprintf("DELETE FROM vmail_folder_user WHERE vmail_folder_id = %d AND vmail_user_id = %d",
+ $row->vmail_folder_id,
+ $other_id);
+
+ $cmd = sprintf('sudo -u vmail /etc/dovecot/share-folder-del %s %s %s > /dev/null 2>&1',
+ $row->from_user, $row->folder, $other);
+ }
+
+ debug($cmd);
+ if (file_exists('/etc/dovecot/share-folder-add'))
+ system($cmd);
+
+ return $this->db->execute($sql);
+ }
+
+ public function ajaxAdd(Array $data)
+ {
+ $sql = sprintf("INSERT INTO %s (vmail_user_id,folder,sys_user,sys_edit) VALUES (%d,%s,%s,now())",
+ $this->table,
+ $data['vmail_user_id'],
+ $this->db->quote($data['folder']),
+ $this->db->quote($_SESSION['sys']['login']));
+
+ return $this->db->execute($sql);
+ }
+
+ public function ajaxDelete(Array $data)
+ {
+ if (!$this->id)
+ throw new Exception("No folder id provided");
+
+ $sql = sprintf("SELECT username || '@' || name AS from_user, folder, vmail_folder.id AS vmail_folder_id
+FROM vmail_folder
+JOIN vmail_user ON vmail_user.id = vmail_user_id
+JOIN vmail_domain ON vmail_domain.id = vmail_domain_id
+WHERE vmail_folder.id = %d",
+ $this->id);
+ $row = $this->db->fetchObject($sql);
+
+ $sql = "SELECT id FROM vmail_user";
+ foreach ($this->db->fetchObjectList($sql) as $urow)
+ $this->setMailboxPermissions($row, 0, $urow->id);
+
+ $sql = sprintf("DELETE FROM vmail_folder WHERE id = %d", $this->id);
+
+ return $this->db->execute($sql);
+ }
+
+ public function ajaxNew(Array $data)
+ {
+ $sql = sprintf("SELECT username || '@' || name
+FROM vmail_user
+JOIN vmail_domain ON vmail_domain.id = vmail_domain_id
+WHERE vmail_user.id = %d",
+ $data['vmail_user_id']);
+ $user = $this->db->fetchValue($sql);
+
+ $cmd = sprintf('sudo -u vmail /etc/dovecot/folder-add %s %s > /dev/null 2>&1',
+ $user, escapeshellarg($data['name']));
+
+ debug($cmd);
+ if (file_exists('/etc/dovecot/folder-add'))
+ system($cmd);
+ }
+
+ public function ajaxCheckbox(Array $data)
+ {
+ if (!$this->id)
+ throw new Exception("No folder id provided");
+
+ $sql = sprintf("SELECT id FROM vmail_folder_user WHERE vmail_folder_id = %d AND vmail_user_id = %d",
+ $this->id, $data['vmail_user_id']);
+ $connection = $this->db->fetchValue($sql);
+
+ if ($data['value']) {
+ if (!$connection) {
+ $sql = sprintf("INSERT INTO vmail_folder_user (vmail_folder_id, vmail_user_id, sys_user, sys_edit) VALUES (%d, %d, %s, now())",
+ $this->id, $data['vmail_user_id'], $this->db->quote($this->username));
+ $this->db->execute($sql);
+ }
+ } else {
+ if ($connection) {
+ $sql = sprintf("DELETE FROM vmail_folder_user WHERE id = %d", $connection);
+ $this->db->execute($sql);
+ }
+ }
+
+ $sql = sprintf("SELECT username || '@' || name AS from_user, folder, vmail_folder.id AS vmail_folder_id
+FROM vmail_folder
+JOIN vmail_user ON vmail_user.id = vmail_user_id
+JOIN vmail_domain ON vmail_domain.id = vmail_domain_id
+WHERE vmail_folder.id = %d",
+ $this->id);
+ $row = $this->db->fetchObject($sql);
+
+ return $this->setMailboxPermissions($row, $data['value'], $this->id);
+ }
+
+ public function ajaxCheckboxAll(Array $data)
+ {
+ if (!$this->id)
+ throw new Exception("No folder id provided");
+
+ $sql = sprintf("SELECT username || '@' || name AS from_user, folder, vmail_folder.id AS vmail_folder_id
+FROM vmail_folder
+JOIN vmail_user ON vmail_user.id = vmail_user_id
+JOIN vmail_domain ON vmail_domain.id = vmail_domain_id
+WHERE vmail_folder.id = %d",
+ $this->id);
+ $row = $this->db->fetchObject($sql);
+
+ $sql = "SELECT id FROM vmail_user WHERE active = 1";
+ foreach ($this->db->fetchObjectList($sql) as $urow)
+ $this->setMailboxPermissions($row, $data['value'], $urow->id);
+
+ return true;
+ }
+}
--- /dev/null
+<?php
+
+class VMail_User extends DatabaseTable {
+ public function __construct($id=false)
+ {
+ parent::__construct('vmail_user', $id);
+ }
+
+ public static function getUserList()
+ {
+ if (defined('VMAIL_SHARED_USER')) {
+ $email = Database::get()->quote(VMAIL_SHARED_USER);
+ $sql = <<<EOS
+SELECT vmail_user.id,username || '@' || name AS text
+FROM vmail_user
+JOIN vmail_domain ON vmail_domain.id = vmail_domain_id
+WHERE username || '@' || name = {$email}
+ORDER BY text
+EOS;
+ } else {
+ $sql = <<<EOS
+SELECT vmail_user.id,username || '@' || name AS text
+FROM vmail_user
+JOIN vmail_domain ON vmail_domain.id = vmail_domain_id
+ORDER BY text
+EOS;
+ }
+
+ return Database::get()->fetchObjectList($sql);
+ }
+
+ /*
+ * Import from Password Plugin for Roundcube: password.php
+ * distributed under the GNU GPL v3 or later
+ * Author Aleksander Machniak <alec@alec.pl>
+ */
+ protected static function random_salt($length)
+ {
+ $possible = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./';
+ $str = '';
+
+ while (strlen($str) < $length) {
+ $str .= substr($possible, (rand() % strlen($possible)), 1);
+ }
+
+ return $str;
+ }
+
+ protected static function encryptPasswd_encrypt($pw)
+ {
+ if (!defined('VMAIL_CRYPT_HASH'))
+ return $pw;
+
+ switch (VMAIL_CRYPT_HASH) {
+ case 'MD5': return md5($pw); break;
+ case 'MD5-CRYPT': return crypt($pw, '$1$' . static::random_salt(9)); break;
+ case 'SHA256-CRYPT': return crypt($pw, '$5$' . static::random_salt(16)); break;
+ case 'SHA512-CRYPT': return crypt($pw, '$6$' . static::random_salt(16)); break;
+ default: throw new Exception('Please configure VMAIL_CRYPT_HASH properly');
+ }
+ }
+
+ protected function deleteFromSharedFolder($email, $commit=false)
+ {
+ $report = '';
+
+ $report .= "Suche Mitgliedschaft in gemeinsamen Mail-Foldern\n";
+ $sql = <<<EOS
+ SELECT vmail_folder_user.id, vmail_folder_id, username || '@' || name AS from_user, folder
+ FROM vmail_folder_user
+ JOIN vmail_folder ON vmail_folder.id = vmail_folder_id
+ JOIN vmail_user ON vmail_user.id = vmail_folder.vmail_user_id
+ JOIN vmail_domain ON vmail_domain.id = vmail_domain_id
+ WHERE vmail_folder_user.vmail_user_id = %d
+EOS;
+
+ $sql = sprintf($sql, $this->id);
+
+ foreach ($this->db->fetchObjectList($sql) as $row) {
+ $report .= sprintf("Lösche %s aus gemeinsamem Mail-Folder %s\n",
+ $email, $row->folder);
+
+ $cmd = sprintf('sudo -u vmail /etc/dovecot/share-folder-del %s %s %s > /dev/null 2>&1',
+ $row->from_user, $row->folder, $email);
+ debug($cmd);
+ if ($commit && file_exists('/etc/dovecot/share-folder-add'))
+ system($cmd);
+
+ $sql = sprintf("DELETE FROM vmail_folder_user WHERE id = %d",
+ $row->id);
+ if ($commit)
+ $this->db->execute($sql);
+ }
+
+ return $report;
+ }
+
+ public function deleteUser($commit=false)
+ {
+ if (!$this->id)
+ throw new Exception("No user id provided");
+
+ $report = '';
+
+ $domain = new VMail_Domain($this->data->vmail_domain_id);
+ $email = sprintf("%s@%s", $this->data->username, $domain->get('name'));
+
+ $alias = new VMail_Alias();
+ $report .= $alias->deleteFromDestination($email, $commit);
+
+ $report .= $this->deleteFromSharedFolder($email, $commit);
+
+ if (defined('ROUNDCUBE_DBDRIVER')) {
+ $report .= $alias->deleteFromRoundcubeIdentities($email, $commit);
+ }
+
+ $report .= sprintf("Lösche %s aus Mailboxen\n", $email);
+ $sql = sprintf("DELETE FROM %s WHERE id = %d", $this->table, $this->id);
+ if ($commit)
+ $this->db->execute($sql);
+
+ return $report;
+ }
+
+ public function ajaxCreateMailbox(Array $data)
+ {
+ if (!$this->id)
+ throw new Exception("No user id provided");
+
+ debug('/etc/dovecot/auto-create-mailbox');
+ if (!file_exists('/etc/dovecot/auto-create-mailbox')) return true;
+
+ $sql = sprintf("SELECT username,name FROM vmail_user JOIN vmail_domain ON vmail_domain.id = vmail_domain_id WHERE vmail_user.id = %d",
+ $this->id);
+
+ $row = $this->db->fetchObject($sql);
+
+ $f = popen('sudo -u vmail /etc/dovecot/auto-create-mailbox', 'w');
+ if ($f === false) return false;
+
+ fwrite($f, $row->name . "\n");
+ fwrite($f, $row->username . "\n");
+ pclose($f);
+
+ $rdb = new Database(ROUNDCUBE_DBDRIVER, ROUNDCUBE_DBHOST, ROUNDCUBE_DBNAME, ROUNDCUBE_DBUSER, ROUNDCUBE_DBPASS);
+ if (defined('MAIL_ERROR')) $rdb->setErrorMail(MAIL_ERROR);
+
+ $sql = sprintf("INSERT INTO users (username, mail_host, created, language) VALUES (%s, %s, now(), %s)",
+ $rdb->quote($row->username),
+ $rdb->quote('localhost'),
+ $rdb->quote('de_DE'));
+
+ $rdb->execute($sql);
+ $user_id = $rdb->lastInsertId();
+ if ($user_id == 0) {
+ $sql = sprintf("SELECT user_id FROM users WHERE username = %s",
+ $rdb->quote($row->username));
+ $user_id = $rdb->fetchValue($sql);
+ }
+
+ $sql = sprintf("INSERT INTO identities (user_id, changed, del, standard, name, email) VALUES (%d, now(), 0, 1, %s, %s)",
+ $user_id,
+ $rdb->quote($row->username),
+ $rdb->quote($row->username.'@'.$row->name));
+ $rdb->execute($sql);
+
+ return true;
+ }
+
+ public function ajaxSetPassword(Array $data)
+ {
+ return $this->modify(['password' => static::encryptPasswd_encrypt($data['passwd'])]);
+ }
+
+ public function ajaxSieveCopy(Array $data)
+ {
+ if (!$this->id)
+ throw new Exception("No user id provided");
+
+ debug('/etc/dovecot/sieve-copy');
+ if (!file_exists('/etc/dovecot/sieve-copy'))
+ return true;
+
+ $sql = sprintf("SELECT username,name FROM vmail_user JOIN vmail_domain ON vmail_domain.id = vmail_domain_id WHERE vmail_user.id = %d",
+ $this->id);
+
+ $row = $this->db->fetchObject($sql);
+
+ $f = popen('sudo -u vmail /etc/dovecot/sieve-copy', 'w');
+ if ($f === false) return false;
+
+ fwrite($f, $row->name . "\n");
+ fwrite($f, $row->username . "\n");
+ pclose($f);
+
+
+ $rdb = new Database(ROUNDCUBE_DBDRIVER, ROUNDCUBE_DBHOST, ROUNDCUBE_DBNAME, ROUNDCUBE_DBUSER, ROUNDCUBE_DBPASS);
+ if (defined('MAIL_ERROR')) $rdb->setErrorMail(MAIL_ERROR);
+
+ $sql = sprintf("SELECT name,email FROM identities JOIN users using(user_id) WHERE username = %s AND email not like '%%@localhost'",
+ $rdb->quote($row->username));
+ $row = $rdb->fetchObject($sql);
+
+ if ($row === false) {
+ return array('need_identity' => true);
+ } else {
+ $sql = "SELECT user_id FROM users WHERE username = 'shared'";
+ $shared_id = $rdb->fetchValue($sql);
+
+ $sql = sprintf("SELECT identity_id FROM identities WHERE user_id = %d AND email = %s",
+ $shared_id, $rdb->quote($row->email));
+ $identity = $rdb->fetchValue($sql);
+
+ if ($identity === false) {
+ $sql = sprintf("INSERT INTO identities (user_id, changed, del, standard, name, email) " .
+ "VALUES (%d, now(), 0, 1, %s, %s)",
+ $shared_id, $rdb->quote($row->name), $rdb->quote($row->email));
+ $rdb->execute($sql);
+ }
+ }
+
+ return ['need_identity' => false];
+ }
+
+ public function ajaxSieveRestore(Array $data)
+ {
+ if (!$this->id)
+ throw new Exception("No user id provided");
+
+ debug('/etc/dovecot/sieve-retrieve');
+ if (!file_exists('/etc/dovecot/sieve-retrieve'))
+ return true;
+
+ $sql = sprintf("SELECT username,name FROM vmail_user JOIN vmail_domain ON vmail_domain.id = vmail_domain_id WHERE vmail_user.id = %d",
+ $this->id);
+
+ $row = $this->db->fetchObject($sql);
+
+ $f = popen('sudo -u vmail /etc/dovecot/sieve-retrieve', 'w');
+ if ($f === false) return false;
+
+ fwrite($f, $row->name . "\n");
+ fwrite($f, $row->username . "\n");
+ pclose($f);
+
+
+ $rdb = new Database(ROUNDCUBE_DBDRIVER, ROUNDCUBE_DBHOST, ROUNDCUBE_DBNAME, ROUNDCUBE_DBUSER, ROUNDCUBE_DBPASS);
+ if (defined('MAIL_ERROR')) $rdb->setErrorMail(MAIL_ERROR);
+
+ $sql = sprintf("SELECT name,email FROM identities JOIN users using(user_id) WHERE username = %s AND email not like '%%@localhost'",
+ $rdb->quote($row->username));
+ $row = $rdb->fetchObject($sql);
+
+ if ($row !== false) {
+ $sql = "SELECT user_id FROM users WHERE username = 'shared'";
+ $shared_id = $rdb->fetchValue($sql);
+
+ $sql = sprintf("DELETE FROM identities WHERE user_id = %d AND email = %s",
+ $shared_id, $rdb->quote($row->email));
+ $rdb->execute($sql);
+ }
+
+ return true;
+ }
+
+ public function ajaxDeleteReport(Array $data)
+ {
+ $report = $this->deleteUser(false);
+
+ return ['report' => nl2br($report)];
+ }
+
+ public function ajaxDeleteUser(Array $data)
+ {
+ $report = $this->deleteUser(true);
+
+ return ['text' => sprintf("Mailbox %s gelöscht", $this->data->username)];
+ }
+
+ public function ajaxGetFolderList(Array $data)
+ {
+ if (!$this->id)
+ throw new Exception("No user id provided");
+
+ $sql = sprintf("SELECT folder FROM vmail_folder WHERE vmail_user_id = %d", $this->id);
+
+ $current_list = array();
+ foreach ($this->db->fetchObjectList($sql) as $row)
+ $current_list[] = $row->folder;
+
+ $sql = sprintf("SELECT username || '@' || name FROM vmail_user JOIN vmail_domain ON vmail_domain.id = vmail_domain_id WHERE vmail_user.id = %d",
+ $this->id);
+ $name = $this->db->fetchValue($sql);
+
+ $options = array();
+
+ debug('/etc/dovecot/discover-folderlist ' . $name);
+ if (file_exists('/etc/dovecot/discover-folderlist')) {
+ if (($f = popen(sprintf('sudo -u vmail /etc/dovecot/discover-folderlist %s', $name), 'r')) !== false) {
+ while (!feof($f)) {
+ $line = trim(fgets($f));
+ if (!strlen($line)) continue;
+ if (in_array($line, $current_list)) continue;
+ $options[] = array('id' => $line, 'text' => $line);
+ }
+ pclose($f);
+ }
+ }
+
+ return ['options' => $options];
+ }
+}
--- /dev/null
+<?php
+
+JavaScript::instance()->file('lib/ricoTableColumnDB.js');
+JavaScript::instance()->file('vmail.js');
+
+Actions::instance()->addLink(new Link(array('id' => 'btn_import',
+ 'icon' => Hallinta::instance()->urlbase().'masks/vmail/import.png',
+ 'title' => 'Neuen Shared Folder hinzufügen',
+ 'function' => 'discover_folder')));
+
+$mask = array(
+ 'title' => 'Shared Folder',
+ 'table' => 'vmail_folder',
+ 'join' => array('vmail_user ON vmail_user_id = vmail_user.id',
+ 'vmail_domain ON vmail_domain_id = vmail_domain.id'),
+ 'list' => array(
+ 'id' => array(
+ 'name' => 'ID',
+ 'visible' => false,
+ 'sql' => 'vmail_folder.id',
+ ),
+ 'folder' => array(
+ 'name' => 'Folder',
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 't',
+ ),
+ 'name' => array(
+ 'name' => 'Domain',
+ 'visible' => false,
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 's',
+ ),
+ 'username' => array(
+ 'name' => 'User',
+ 'visible' => false,
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 't',
+ ),
+ 'email' => array(
+ 'name' => 'Username',
+ 'width' => 300,
+ 'type' => 'text',
+ 'filter' => 't',
+ 'sql' => "username || '@' || name",
+ ),
+ 'delete' => array(
+ 'name' => 'Del',
+ 'width' => 25,
+ 'specs' => array('ClassName' => 'aligncenter', 'canSort' => false),
+ 'control' => "new Rico.TableColumn.link('javascript:folder_del({0})')",
+ 'sql' => "'<img src=\"".Hallinta::instance()->urlbase()."masks/vmail/delete.png\" title=\"Löschen\">'",
+ ),
+ ),
+ 'second' => array(
+ 'perms' => array(
+ 'title' => 'Freigaben',
+ 'table' => 'vmail_user',
+ 'rows' => 10,
+ 'width' => 400,
+ 'join' => array('vmail_domain ON vmail_domain_id = vmail_domain.id'),
+ 'where' => 'vmail_user.id <> (SELECT vmail_user_id FROM vmail_folder WHERE id = {id}) AND active = 1',
+ 'list' => array(
+ 'id' => array(
+ 'name' => 'ID',
+ 'visible' => false,
+ 'sql' => 'vmail_user.id',
+ ),
+ 'name' => array(
+ 'name' => 'Domain',
+ 'visible' => false,
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 's',
+ ),
+ 'username' => array(
+ 'name' => 'Username',
+ 'visible' => false,
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 't',
+ ),
+ 'email' => array(
+ 'name' => 'Username',
+ 'width' => 300,
+ 'type' => 'text',
+ 'sql' => "username || '@' || name",
+ 'filter' => 't',
+ ),
+ 'checked' => array(
+ 'name' => 'OK',
+ 'width' => 40,
+ 'sql' => '(SELECT count(*)
+ FROM vmail_folder_user
+ WHERE vmail_user_id = vmail_user.id
+ AND vmail_folder_id = {id})',
+ 'control' => "new Rico.TableColumn.checkboxFunction(folder_checkbox_change, folder_checkbox_all)",
+ 'filter' => 'c',
+ 'specs' => array('ClassName' => 'aligncenter has-checkbox', 'canSort' => false),
+ ),
+ ),
+ ),
+ ),
+ );
--- /dev/null
+alias.php
\ No newline at end of file
--- /dev/null
+<div>
+<div id="report" style="margin-top:1ex;margin-bottom:3ex;font-weight:normal;width:500px;max-height:500px;overflow-y:auto;">
+</div>
+
+<div style="text-align:center;margin-bottom:1ex;">
+<button id="btn_delete_really" class="builtin" onclick="delete_confirmation(this)" title="Wirklich löschen">Wirklich Löschen</button>
+
+<button id="btn_delete_close" class="builtin" onclick="delete_popup.closePopup()" title="Schließen">Abbrechen</button>
+</div>
+
+</div>
--- /dev/null
+<div class="form" style="margin-left: 10px; margin-right: 12px; padding-left: 10px; padding-bottom: 7px;">
+<label for="discover_vmail_user_id">Username:</label><br>
+<select name="vmail_user_id" id="discover_vmail_user_id" onchange="discover_folderlist()">
+<option value="">-- bitte wählen --</option>
+<?php foreach (VMail_User::getUserList() as $row) { ?>
+<option value="<?php echo $row->id; ?>"><?php echo $row->text; ?></option>
+<?php } ?>
+</select>
+<div style="height: 5px;"></div>
+<?php if (file_exists('/etc/dovecot/folder-add')) { ?>
+<label for="new_folder">Neuer Folder:</label><br>
+<input name="new_folder" id="new_folder">
+ <button onclick="return folder_new()">Anlegen</button>
+<br>
+<?php } ?>
+<label for="discover_folder">Shared Folder:</label><br>
+<select name="folder" id="discover_folder"><option value="">-- bitte wählen --</option></select>
+ <button onclick="return folder_add()">Hinzufügen</button>
+</div>
<?php
-
$buttons = <<<EOC
<p style="margin-top: 5px; margin-bottom: 4px; text-align: center;">
-<button class="custom" onclick="return passwd_delete()">Passwort löschen</button>
<button class="custom" onclick="return passwd_set()">Passwort setzen</button>
</p>
EOC;
-$jscode[] = <<<EOC
-var post_save = user_post_save;
-var pre_insert = user_pre_save;
-var pre_save = user_pre_save;
-
-function user_pre_save()
-{
- if ($('edit_username').value == '*' && !$('edit_forward').value.length) {
- alert("Fehler aufgetreten!\\n\\nFür Catch-All-Einträge muß zwingend\\neine Forward-Adresse angegeben werden.");
- $('edit_forward').focus();
- return false;
- }
-
- return true;
-}
-
-function user_post_save()
-{
- grid_update(grid);
-
- if (!$('edit_id').value.length && !$('edit_forward').value.length)
- alert("Bitte als nächstes ein Passwort setzen.\\nUnd danach direkt mit Mailprogram aktivieren.");
-}
-
-function passwd_delete_callback(data)
-{
- grid_update(grid);
- info('Preis gespeichert');
-}
-
-function passwd_delete()
-{
- var eid = document.getElementById('edit_id');
- if (!eid || !eid.value.length) return false;
-
- var source = document.getElementById('source');
- if (!source) return false;
-
- var parms = 'source=' + source.innerHTML + '&callback=delete&';
- parms += 'id=' + eid.value;
-
- ajax_request('function', parms, passwd_delete_callback);
-
- return false;
-}
-
-var passwd_popup = false;
-function passwd_setpw_callback(data)
-{
- grid_update(grid);
- info('Neues Passwort gespeichert');
-}
+if (file_exists('/etc/dovecot/sieve-copy') && file_exists('/etc/dovecot/sieve-retrieve') && defined('SIEVEADDR')) {
+ $title_copy = sprintf("Sieve-Skript zu %s kopieren", SIEVEADDR);
+ $title_retrieve = sprintf("Sieve-Skript von %s zurückholen", SIEVEADDR);
-function passwd_setpw()
-{
- passwd_popup.closePopup();
-
- var pw1 = document.getElementById('pw_pass1');
- var pw2 = document.getElementById('pw_pass2');
-
- if (!pw1.value.length || !pw2.value.length || pw1.value != pw2.value) {
- alert("Die Passwörter stimmen nicht überein!");
- return false;
- }
-
- var source = document.getElementById('source');
- var pw_id = document.getElementById('pw_id');
- var pw_pass = document.getElementById('pw_pass1');
-
- var parms = 'source=' + source.innerHTML + '&callback=setpw';
- parms += '&id=' + pw_id.value;
- parms += '&passwd=' + pw_pass.value;
-
- ajax_request('function', parms, passwd_setpw_callback);
+ $sieve_buttons = <<<EOC
+<div style="border: 1px solid #BBB; padding-left: 2px; padding-right: 2px;">
+<p style="margin-top: 5px; margin-bottom: 4px; text-align: left;">
+Sieve-Skript (u.a. Vacation) bearbeiten
+</p>
+<p style="margin-top: 5px; margin-bottom: 4px; text-align: center;">
+<button class="custom" onclick="return sieve_copy()" title="$title_copy">Skript kopieren</button>
+<button class="custom" onclick="return sieve_retrieve()" title="$title_retrieve">Skript zurückholen</button>
+</p>
+</div>
+EOC;
- return false;
+ $buttons .= $sieve_buttons;
}
-function passwd_set()
-{
- var edit_id = document.getElementById('edit_id');
-
- if (!edit_id.value.length) return false;
-
- var width = 245;
- var height = 163;
-
- if (!passwd_popup) {
- var options = {hideOnClick: false, canDragFunc: true };
- passwd_popup = new Rico.Popup(options);
- passwd_popup.createWindow('<b>Neues Passwort setzen</b>','',height+'px',width+'px');
- passwd_popup.contentDiv.style.backgroundColor='#e0e0e0';
- passwd_popup.contentDiv.innerHTML = [
- '<div class="form" style="margin-left: 10px; margin-right: 12px; padding-left: 10px; padding-bottom: 7px;">',
- '<input type="hidden" name="pw_id" id="pw_id">',
- '<label for="pw_email">E-Mail Adresse:</label><br>',
- '<input type="text" name="pw_email" id="pw_email" size="23" readonly>',
- '<div style="height: 5px;"></div>',
- '<label for="pw_pass1">Neues Passwort:</label><br>',
- '<input type="password" name="pw_pass1" id="pw_pass1" size="23">',
- '<div style="height: 5px;"></div>',
- '<label for="pw_pass2">erneut eingeben:</label><br>',
- '<input type="password" name="pw_pass2" id="pw_pass2" size="23">',
- '<div style="height: 5px;"></div>',
- '<button onclick="return passwd_setpw()">Passwort setzen</button>',
- '</div>',
- ].join('');
- }
-
- var edit_username = document.getElementById('edit_username');
- var edit_vmail_domain_id = document.getElementById('edit_vmail_domain_id');
-
- var pw_id = document.getElementById('pw_id');
- var pw_email = document.getElementById('pw_email');
-
- pw_id.value = edit_id.value;
- pw_email.value = edit_username.value + '@' + edit_vmail_domain_id.options[edit_vmail_domain_id.selectedIndex].innerHTML;
-
- var x = Math.floor((RicoUtil.windowWidth()-width)/2);
- var y = Math.floor((RicoUtil.windowHeight()-height)/2);
- passwd_popup.openPopup(x,y);
+JavaScript::instance()->file('vmail.js');
+JavaScript::instance()->add("Hallinta.preSave = user_pre_save;");
+JavaScript::instance()->add("Hallinta.preInsert = user_pre_save;");
+JavaScript::instance()->add("Hallinta.postInsert = user_post_insert;");
+JavaScript::instance()->add("Hallinta.preDelete = user_pre_delete;");
+JavaScript::instance()->add("Hallinta.fetchItemAfterInsert = true;");
- var pw_pass1 = document.getElementById('pw_pass1');
- pw_pass1.value = '';
- var pw_pass2 = document.getElementById('pw_pass2');
- pw_pass2.value = '';
- pw_pass1.focus();
-
- return false;
-}
-EOC;
+if (defined('SIEVEADDR'))
+ JavaScript::instance()->add(sprintf("var SIEVEADDR = '%s';", SIEVEADDR));
$mask = array(
'table' => 'vmail_user',
- 'title' => 'Mailboxen und Weiterleitungen',
+ 'title' => 'Mailboxen und Adressen',
'join' => array('vmail_domain ON vmail_domain_id = vmail_domain.id'),
'list' => array(
'id' => array(
'visible' => false,
'sql' => 'vmail_user.id',
),
+ 'name' => array(
+ 'name' => 'Domain',
+ 'visible' => false,
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 's',
+ ),
+ 'username' => array(
+ 'name' => 'Username',
+ 'visible' => false,
+ 'width' => 200,
+ 'type' => 'text',
+ 'filter' => 't',
+ ),
'email' => array(
'name' => 'E-Mail',
- 'width' => 330,
+ 'width' => 400,
'type' => 'text',
+ 'filter' => 't',
'sql' => "username || '@' || name",
- 'specs' => "filterUI: 't'",
- ),
- 'forward' => array(
- 'name' => 'Forward',
- 'width' => 330,
- 'specs' => "filterUI: 't'",
- ),
- 'pw' => array(
- 'name' => 'Pass',
- 'width' => 40,
- 'specs' => "ClassName: 'aligncenter'",
- 'control' => "new Rico.TableColumn.checkbox('t', 'f',0,1)",
- 'sql' => 'password IS NOT NULL AND length(password) > 0',
),
'active' => array(
- 'name' => 'on',
+ 'name' => 'aktiv',
'width' => 40,
- 'specs' => "ClassName: 'aligncenter'",
- 'control' => "new Rico.TableColumn.checkbox(1, 0,0,1)",
+ 'specs' => array('ClassName' => 'aligncenter has-checkbox'),
+ 'control' => "new Rico.TableColumn.checkbox(1,0,0,1)",
),
),
'edit' => array(
'username' => array(
- 'name' => 'Usename',
+ 'name' => 'Local Part',
'type' => 'text',
'size' => 21,
'required' => true,
'option_empty' => '-- select --',
'required' => true,
),
- 'forward' => array(
- 'name' => 'Forward',
- 'type' => 'text',
- 'size' => 21,
- 'null' => true,
- ),
-/*
- 'password' => array(
- 'name' => 'Passwort',
- 'type' => 'passwd',
- 'size' => 21,
- 'null' => true,
- 'func' => 'passwd_encrypt',
- ),
-*/
'active' => array(
- 'name' => 'aktiviert',
+ 'name' => 'Mailbox aktiv',
'type' => 'boolean',
),
'buttons' => array(
'sql' => false,
),
),
- 'callbacks' => array(
- 'delete' => 'cb_delete',
- 'setpw' => 'cb_setpw',
- ),
);
-
-function passwd_encrypt($pw)
-{
- return md5($pw);
-}
-
-function cb_delete()
-{
- global $db;
-
- $sql = sprintf("UPDATE vmail_user SET password = NULL WHERE id = %d", $_POST['id']);
-
- $sth = $db->query($sql);
-
- return true;
-}
-
-function cb_setpw()
-{
- global $db;
-
- $sql = sprintf("UPDATE vmail_user SET password = '%s' WHERE id = %d",
- passwd_encrypt($_POST['passwd']),
- $_POST['id']);
-
- $sth = $db->query($sql);
-
- return true;
-}
-
-?>
--- /dev/null
+var passwd_popup = false;
+var delete_popup = false;
+var discover_popup = false;
+
+function user_pre_save()
+{
+ if ($('#edit_username').val() == '*') {
+ alert("Fehler aufgetreten!\\nCatch-All-Einträge sind nur bei Weiterleitungen zulässig.");
+ $('#edit_username').focus();
+ return false;
+ }
+
+ return true;
+}
+
+function user_post_insert(data)
+{
+ Hallinta.showMsg("Bitte als nächstes ein Passwort setzen die Mailbox direkt mit Mailprogram aktivieren.", {timeout: 10});
+ ajax_request('VMail_User/CreateMailbox', 'id='+data.id);
+}
+
+function passwd_setpw()
+{
+ passwd_popup.closePopup();
+
+ if (!$('#pw_pass1').val().length || !$('#pw_pass2').val().length || $('#pw_pass1').val() != $('#pw_pass2').val()) {
+ alert("Die Passwörter stimmen nicht überein!");
+ return false;
+ }
+
+ var parms = 'id=' + $('#pw_id').val();
+ parms += '&passwd=' + $('#pw_pass1').val();
+
+ ajax_request('VMail_User/SetPassword', parms, function(data){
+ info('Passwort gespeichert');
+ Hallinta.showMsg('Neues Passwort gespeichert', {timeout: 3});
+ });
+
+ return false;
+}
+
+function passwd_set()
+{
+ if (!$('#edit_id').val().length) return false;
+
+ var centerDialog = false;
+
+ if (!passwd_popup) {
+ passwd_popup = new Rico.Window('<b>Neues Passwort setzen</b>', {zIndex: 100});
+ $(passwd_popup.contentDiv).html([
+ '<div class="form" style="margin-left: 10px; margin-right: 12px; padding-left: 10px; padding-bottom: 7px;">',
+ '<input type="hidden" name="pw_id" id="pw_id">',
+ '<label for="pw_email">E-Mail Adresse:</label><br>',
+ '<input type="text" name="pw_email" id="pw_email" size="23" readonly style="background:#eee;">',
+ '<div style="height: 5px;"></div>',
+ '<label for="pw_pass1">Neues Passwort:</label><br>',
+ '<input type="password" name="pw_pass1" id="pw_pass1" size="23">',
+ '<div style="height: 5px;"></div>',
+ '<label for="pw_pass2">erneut eingeben:</label><br>',
+ '<input type="password" name="pw_pass2" id="pw_pass2" size="23">',
+ '<div style="height: 5px;"></div>',
+ '<button onclick="return passwd_setpw()">Passwort setzen</button>',
+ '</div>',
+ ].join(''));
+ centerDialog = true;;
+ }
+
+ $('#pw_id').val($('#edit_id').val());
+ $('#pw_email').val($('#edit_username').val() + '@' + $('#edit_vmail_domain_id option[value="'+$('#edit_vmail_domain_id').val()+'"]').text());
+
+ $('#pw_pass1').val('');
+ $('#pw_pass2').val('');
+
+ if (centerDialog)
+ passwd_popup.centerPopup();
+ else
+ passwd_popup.openPopup();
+
+ $('#pw_pass1').focus();
+ return false;
+}
+
+function sieve_copy()
+{
+ ajax_request('VMail_User/SieveCopy', 'id=' + $('#edit_id').val(), function(data){
+ info('Skript kopiert');
+
+ if (typeof data == 'object' && data.need_identity === true)
+ Hallinta.showMsg('Sieve-Skript zu ' + SIEVEADDR + ' kopiert, neue Identität muß angelegt werden.',
+ {timeout: 5});
+ else
+ Hallinta.showMsg('Sieve-Skript zu ' + SIEVEADDR + ' kopiert.', {timeout: 5});
+ });
+
+ return false;
+}
+
+function sieve_retrieve()
+{
+ ajax_request('VMail_User/SieveRestore', 'id=' + $('#edit_id').val(), function(data){
+ info('Skript zurückgeholt');
+ Hallinta.showMsg('Sieve-Skript von ' + SIEVEADDR + ' zurückgeholt.', {timeout: 5});
+ });
+
+ return false;
+}
+
+function user_pre_delete()
+{
+ Hallinta.showMsg("Löschen wird vorbereitet...");
+ ajax_request('VMail_User/DeleteReport', {id: $('#edit_id').val()}, function(data){
+ Hallinta.hideMsg();
+
+ if (!delete_popup) {
+ delete_popup = new Rico.Window('Delete Report', {zIndex: 100});
+
+ ajax_request('Template/Load', 'id=delete', function(html){
+ $(delete_popup.contentDiv).html(html.data);
+ $(delete_popup.contentDiv).find('#report').html(data.report);
+ $(delete_popup.contentDiv).find('#btn_delete_really').attr('data-what', 'user');
+ delete_popup.centerPopup();
+ });
+ } else {
+ $(delete_popup.contentDiv).find('#report').html(data.report);
+ delete_popup.openPopup();
+ }
+ });
+
+ return false;
+}
+
+function alias_pre_delete()
+{
+ Hallinta.showMsg("Löschen wird vorbereitet...");
+ ajax_request('VMail_Alias/DeleteReport', {id: $('#edit_id').val()}, function(data){
+ Hallinta.hideMsg();
+
+ if (!delete_popup) {
+ delete_popup = new Rico.Window('Delete Report', {zIndex: 100});
+
+ ajax_request('Template/Load', 'id=delete', function(html){
+ $(delete_popup.contentDiv).html(html.data);
+ $(delete_popup.contentDiv).find('#report').html(data.report);
+ $(delete_popup.contentDiv).find('#btn_delete_really').attr('data-what', 'alias');
+ delete_popup.centerPopup();
+ });
+ } else {
+ $(delete_popup.contentDiv).find('#report').html(data.report);
+ delete_popup.openPopup();
+ }
+ });
+
+ return false;
+}
+
+function delete_confirmation(obj)
+{
+ if ($(obj).attr('data-what') == 'user')
+ var backend = 'VMail_User/DeleteUser';
+ else if ($(obj).attr('data-what') == 'alias')
+ var backend = 'VMail_Alias/DeleteAlias';
+ else {
+ delete_popup.closePopup();
+ return Hallinta.showMsg('Unbekannte Betriebsart ' + $(obj).attr('data-what'), {timeout: 5});
+ }
+
+ ajax_request(backend, {id: $('#edit_id').val()}, function(data){
+ Hallinta.showMsg(data.text, {timeout: 3});
+ grid_update(Hallinta.grid);
+ delete_popup.closePopup();
+ Hallinta.editDialog.closePopup();
+ });
+}
+
+function discover_folder()
+{
+ if (!discover_popup) {
+ discover_popup = new Rico.Window('<b>Shared Folder</b>', {zIndex: 100});
+
+ ajax_request('Template/Load', 'id=folder', function(html){
+ $(discover_popup.contentDiv).html(html.data);
+
+ if ($('#discover_vmail_user_id option').length == 2) {
+ $('#discover_vmail_user_id').val($('#discover_vmail_user_id option:nth-child(2)').val());
+ discover_folderlist();
+ }
+
+ discover_popup.centerPopup();
+ });
+ } else {
+ discover_popup.openPopup();
+ }
+
+ return false;
+}
+
+function discover_folderlist(callback)
+{
+ if (!$('#discover_vmail_user_id').val().length) {
+ select_update('discover_folder', {}, 1);
+ return false;
+ }
+
+ ajax_request('VMail_User/GetFolderList', 'id='+$('#discover_vmail_user_id').val(), function(data){
+ console.log(data);
+ select_update('discover_folder', data.options, 1);
+ info('Folderliste geladen');
+ if (typeof callback == 'function')
+ callback();
+ });
+}
+
+function folder_add()
+{
+ if ($('#discover_folder').val().length) {
+ ajax_request('VMail_Folder/Add',
+ 'vmail_user_id='+$('#discover_vmail_user_id').val()+'&folder='+$('#discover_folder').val(),
+ function(data){
+ grid_update(Hallinta.grid);
+ });
+ }
+ discover_popup.closePopup();
+}
+
+function folder_checkbox_change(checkbox, row, value)
+{
+ if (Hallinta.mainId === false) return;
+
+ var id = checkbox.liveGrid.columns[0].getValue(row);
+
+ ajax_request('VMail_Folder/Checkbox',
+ 'id='+Hallinta.mainId+'&vmail_user_id='+id+'&value='+value);
+}
+
+function folder_checkbox_all(formdata)
+{
+ if (Hallinta.mainId === false) return;
+
+ ajax_request('VMail_Folder/CheckboxAll',
+ 'id='+Hallinta.mainId+'&'+formdata);
+}
+
+function folder_del(id)
+{
+ var ok = confirm("Möchten Sie wirklich alle Abonnements löschen?");
+
+ if (!ok) return;
+
+ ajax_request('VMail_Folder/Delete',
+ 'id='+id,
+ function(data){
+ info('Shared Folder gelöscht');
+ Hallinta.showMsg('Shared Folder und Abonnements gelöscht', {timeout: 3});
+ grid_update(Hallinta.grid);
+ });
+ return;
+}
+
+function folder_new()
+{
+ var name = $('#new_folder').val();
+ if (name.indexOf('.') > -1) {
+ alert('Punkte sind in Foldernamen nicht erlaubt');
+ return;
+ }
+
+ if (name.indexOf('/') == 0) {
+ alert('Slash am Anfang eines Foldernamen nicht erlaubt');
+ return;
+ }
+
+ var userid = $('#discover_vmail_user_id').val();
+ if (!userid.length) {
+ alert('Bitte erst einen User auswählen');
+ return;
+ }
+
+ ajax_request('VMail_Folder/New',
+ 'vmail_user_id='+userid+'&name='+encodeURIComponent(name),
+ function(data){
+ Hallinta.showMsg('Folder angelegt, kann jetzt hinzugefügt werden', {timeout: 3});
+ discover_folderlist(function(){
+ $('#discover_folder').val(name);
+ });
+ });
+}
id SERIAL,
name character varying(100) NOT NULL,
sys_user character varying(10) NOT NULL,
- sys_edit timestamp without time zone NOT NULL
+ sys_edit timestamp without time zone NOT NULL,
+ UNIQUE(name)
);
CREATE UNIQUE INDEX vmail_domain_id ON vmail_domain USING btree (id);
vmail_domain_id integer NOT NULL,
username character varying(50) NOT NULL,
password character varying(50),
- forward character varying(150),
active integer DEFAULT 0 NOT NULL,
sys_user character varying(10) NOT NULL,
- sys_edit timestamp without time zone NOT NULL
+ sys_edit timestamp without time zone NOT NULL,
+ UNIQUE(vmail_domain_id,username)
);
CREATE UNIQUE INDEX vmail_user_id ON vmail_user USING btree (id);
CREATE INDEX vmail_user_vmail_domain_id ON vmail_user USING btree (vmail_domain_id);
+-- ALTER TABLE ONLY vmail_user
+-- ADD CONSTRAINT vmail_user_vmail_domain_id_username_key UNIQUE (vmail_domain_id, username);
+
+CREATE TABLE vmail_alias (
+ id SERIAL,
+ vmail_domain_id integer NOT NULL,
+ username character varying(50) NOT NULL,
+ destination TEXT DEFAULT NULL,
+ islist integer DEFAULT 0 NOT NULL,
+ active integer DEFAULT 0 NOT NULL,
+ sys_user character varying(10) NOT NULL,
+ sys_edit timestamp without time zone NOT NULL,
+ UNIQUE(vmail_domain_id,username)
+);
+
+CREATE UNIQUE INDEX vmail_alias_id ON vmail_alias USING btree (id);
+CREATE INDEX vmail_alias_vmail_domain_id ON vmail_alias USING btree (vmail_domain_id);
+
+ALTER TABLE ONLY vmail_user
+ ADD CONSTRAINT "$1" FOREIGN KEY (vmail_domain_id) REFERENCES vmail_domain(id);
+
+ALTER TABLE ONLY vmail_alias
+ ADD CONSTRAINT "$1" FOREIGN KEY (vmail_domain_id) REFERENCES vmail_domain(id);
+
REVOKE ALL ON TABLE vmail_user FROM PUBLIC;
GRANT SELECT ON TABLE vmail_user TO "vmail";
GRANT ALL ON TABLE vmail_user TO "hallinta";
REVOKE ALL ON SEQUENCE vmail_user_id_seq FROM PUBLIC;
GRANT ALL ON SEQUENCE vmail_user_id_seq TO "hallinta";
+REVOKE ALL ON TABLE vmail_alias FROM PUBLIC;
+GRANT SELECT ON TABLE vmail_alias TO "vmail";
+GRANT ALL ON TABLE vmail_alias TO "hallinta";
+
+REVOKE ALL ON SEQUENCE vmail_alias_id_seq FROM PUBLIC;
+GRANT ALL ON SEQUENCE vmail_alias_id_seq TO "hallinta";
+
REVOKE ALL ON TABLE vmail_domain FROM PUBLIC;
GRANT SELECT ON TABLE vmail_domain TO "vmail";
GRANT ALL ON TABLE vmail_domain TO "hallinta";
REVOKE ALL ON SEQUENCE vmail_domain_id_seq FROM PUBLIC;
GRANT ALL ON SEQUENCE vmail_domain_id_seq TO "hallinta";
+-- Shared Folders -------------------------------------------------------
+
+CREATE TABLE vmail_shares (
+ id SERIAL,
+ from_user varchar(100) not null,
+ to_user varchar(100) not null,
+ isset char(1) DEFAULT '1', -- always '1' currently
+ primary key (from_user, to_user)
+);
+
+CREATE INDEX to_user ON vmail_shares (to_user); -- because we always search for to_user
+
+REVOKE ALL ON TABLE vmail_shares FROM PUBLIC;
+GRANT SELECT ON TABLE vmail_shares TO "vmail";
+GRANT ALL ON TABLE vmail_shares TO "hallinta";
+
+REVOKE ALL ON SEQUENCE vmail_shares_id_seq FROM PUBLIC;
+GRANT ALL ON SEQUENCE vmail_shares_id_seq TO "hallinta";
+
+
+CREATE TABLE vmail_anyone_shares (
+ id SERIAL,
+ from_user varchar(100) not null,
+ isset char(1) DEFAULT '1', -- always '1' currently
+ primary key (from_user)
+);
+
+REVOKE ALL ON TABLE vmail_anyone_shares FROM PUBLIC;
+GRANT SELECT ON TABLE vmail_anyone_shares TO "vmail";
+GRANT ALL ON TABLE vmail_anyone_shares TO "hallinta";
+
+REVOKE ALL ON SEQUENCE vmail_anyone_shares_id_seq FROM PUBLIC;
+GRANT ALL ON SEQUENCE vmail_anyone_shares_id_seq TO "hallinta";
+
+
+CREATE TABLE vmail_folder (
+ id SERIAL,
+ vmail_user_id integer NOT NULL,
+ folder character varying(100) NOT NULL,
+ sys_user character varying(10) NOT NULL,
+ sys_edit timestamp without time zone NOT NULL,
+ UNIQUE(vmail_user_id,folder)
+);
+
+CREATE UNIQUE INDEX vmail_folder_id ON vmail_folder USING btree (id);
+CREATE INDEX vmail_folder_vmail_user_id ON vmail_folder USING btree (vmail_user_id);
+
+ALTER TABLE ONLY vmail_folder
+ ADD CONSTRAINT "$1" FOREIGN KEY (vmail_user_id) REFERENCES vmail_user(id);
+
+REVOKE ALL ON TABLE vmail_folder FROM PUBLIC;
+GRANT ALL ON TABLE vmail_folder TO "hallinta";
+
+REVOKE ALL ON SEQUENCE vmail_folder_id_seq FROM PUBLIC;
+GRANT ALL ON SEQUENCE vmail_folder_id_seq TO "hallinta";
+
+
+CREATE TABLE vmail_folder_user (
+ id SERIAL,
+ vmail_folder_id integer NOT NULL,
+ vmail_user_id integer NOT NULL,
+ sys_user character varying(10) NOT NULL,
+ sys_edit timestamp without time zone NOT NULL,
+ UNIQUE(vmail_folder_id,vmail_user_id)
+);
+
+CREATE UNIQUE INDEX vmail_folder_user_id ON vmail_folder_user USING btree (id);
+CREATE INDEX vmail_folder_user_vmail_folder_id ON vmail_folder_user USING btree (vmail_folder_id);
+CREATE INDEX vmail_folder_user_vmail_user_id ON vmail_folder_user USING btree (vmail_user_id);
+
+ALTER TABLE ONLY vmail_folder_user
+ ADD CONSTRAINT "$1" FOREIGN KEY (vmail_folder_id) REFERENCES vmail_folder(id);
+ALTER TABLE ONLY vmail_folder_user
+ ADD CONSTRAINT "$2" FOREIGN KEY (vmail_user_id) REFERENCES vmail_user(id);
+
+REVOKE ALL ON TABLE vmail_folder_user FROM PUBLIC;
+GRANT SELECT ON TABLE vmail_folder_user TO "vmail";
+GRANT ALL ON TABLE vmail_folder_user TO "hallinta";
+
+REVOKE ALL ON SEQUENCE vmail_folder_user_id_seq FROM PUBLIC;
+GRANT ALL ON SEQUENCE vmail_folder_user_id_seq TO "hallinta";
+
+----------------------------------------------------------------------
+
+CREATE TABLE vmail_filter_extension (
+ id SERIAL PRIMARY KEY,
+ extension varchar(10) NOT NULL,
+ sys_user character varying(10) NOT NULL,
+ sys_edit timestamp without time zone NOT NULL,
+ UNIQUE(extension)
+);
+
+CREATE UNIQUE INDEX vmail_filter_extension_id ON vmail_filter_extension USING btree (id);
+CREATE UNIQUE INDEX vmail_filter_extension_extension ON vmail_filter_extension USING btree (extension);
+
+REVOKE ALL ON TABLE vmail_filter_extension FROM PUBLIC;
+GRANT SELECT ON TABLE vmail_filter_extension TO "vmail";
+GRANT ALL ON TABLE vmail_filter_extension TO "hallinta";
+
+REVOKE ALL ON SEQUENCE vmail_filter_extension_id_seq FROM PUBLIC;
+GRANT ALL ON SEQUENCE vmail_filter_extension_id_seq TO "hallinta";