Show spam aliases #

This commit is contained in:
andryyy
2017-02-21 22:27:11 +01:00
parent 76426b65b2
commit 0eb932b3ab
2737 changed files with 357639 additions and 22 deletions

View File

@@ -0,0 +1,10 @@
language: php
install:
- pear install Net_Socket PEAR Auth_SASL
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
script: cd tests && pear run-tests .

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
{
"authors": [
{
"email": "jan@horde.org",
"name": "Jan Schneider",
"role": "Lead"
},
{
"email": "richard@php.net",
"name": "Richard Heyes",
"role": "Lead"
},
{
"email": "damlists@cnba.uba.ar",
"name": "Damian Fernandez Sosa",
"role": "Lead"
},
{
"email": "amistry@am-productions.biz",
"name": "Anish Mistry",
"role": "Lead"
}
],
"autoload": {
"classmap": [
"./"
]
},
"description": "This is a fork of http://pear.php.net/package/Net_Sieve",
"license": "BSD",
"name": "roundcube/net_sieve",
"support": {
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Net_Sieve",
"source": "https://github.com/roundcube/Net_Sieve"
},
"type": "library",
"repositories": [
{
"type": "pear",
"url": "https://pear.php.net/"
}
],
"require": {
"pear/pear-core-minimal": "*",
"pear-pear.php.net/net_socket": "*"
},
"require-dev": {
"phpunit/phpunit": "*"
},
"suggest": {
"pear/auth_sasl": "Install optionally via your project's composer.json"
},
"config": {
"secure-http": false
}
}

View File

@@ -0,0 +1,460 @@
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.4.6" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd">
<name>Net_Sieve</name>
<channel>pear.php.net</channel>
<summary>Handles talking to a sieve server.</summary>
<description>This package provides an API to talk to servers implementing the managesieve protocol. It can be used to install and remove sieve scripts, mark them active etc.</description>
<lead>
<name>Jan Schneider</name>
<user>yunosh</user>
<email>jan@horde.org</email>
<active>yes</active>
</lead>
<lead>
<name>Richard Heyes</name>
<user>richard</user>
<email>richard@php.net</email>
<active>no</active>
</lead>
<lead>
<name>Damian Fernandez Sosa</name>
<user>damian</user>
<email>damlists@cnba.uba.ar</email>
<active>no</active>
</lead>
<lead>
<name>Anish Mistry</name>
<user>amistry</user>
<email>amistry@am-productions.biz</email>
<active>no</active>
</lead>
<date>2015-08-02</date>
<version>
<release>1.5.0</release>
<api>1.5.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Dropped PHP4 support, fixed PHP7 warnings
</notes>
<contents>
<dir name="/" baseinstalldir="Net">
<dir name="tests">
<file name="largescript.siv" role="test" />
<file name="config.php.dist" role="test" />
<file name="SieveTest.php" role="test" />
</dir> <!-- /tests -->
<file name="Sieve.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
</dir> <!-- / -->
</contents>
<dependencies>
<required>
<php>
<min>5.0.0</min>
</php>
<pearinstaller>
<min>1.4.0b1</min>
</pearinstaller>
<package>
<name>Net_Socket</name>
<channel>pear.php.net</channel>
<min>1.0</min>
</package>
<package>
<name>PEAR</name>
<channel>pear.php.net</channel>
<min>1.0</min>
</package>
</required>
<optional>
<package>
<name>Auth_SASL</name>
<channel>pear.php.net</channel>
<min>1.0</min>
</package>
</optional>
</dependencies>
<phprelease />
<changelog>
<release>
<date>2015-01-20</date>
<version>
<release>1.3.4</release>
<api>1.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Remove erroneous and unnecessary active script caching (Bug #20472).
</notes>
</release>
<release>
<date>2014-09-24</date>
<version>
<release>1.3.3</release>
<api>1.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fix notices from non-static calling of PEAR methods.
* Fix reading OK responses with string literal messages.
</notes>
</release>
<release>
<date>2011-08-06</date>
<version>
<release>1.3.2</release>
<api>1.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fix referrals if host data or user credentials are passed to connect() and login() instead of the constructor (Aleksander Machniak, Bug #17107).
</notes>
</release>
<release>
<date>2011-08-05</date>
<version>
<release>1.3.1</release>
<api>1.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Query capabilities again after successful authentication (Jesse Crawford, Request #18382).
* Escape quotes and backslashes in script names, and use literal strings for script names with non-ASCII characters (Aleksander Machniak, Bug #16691).
* Work around broken STARTTLS behavior in Cyrus versions before 2.3.10 (Aleksander Machniak, Bug #18241).
* Improve string literal parsing (Aleksander Machniak, Bug #18228).</notes>
</release>
<release>
<date>2010-07-01</date>
<version>
<release>1.3.0</release>
<api>1.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Add debug handler parameter to constructor.
* Fix LOGIN authentication (Agustín Eijo, Aleksander Machniak, Bug #17527).</notes>
</release>
<release>
<date>2010-06-13</date>
<version>
<release>1.2.2</release>
<api>1.2.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fix SASL authentication without Auth_SASL (Bug #17489).</notes>
</release>
<release>
<date>2010-04-19</date>
<version>
<release>1.2.1</release>
<api>1.2.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fix DIGEST-MD5 authentication with Dovecot (Stef Simoens, Bug #17320).</notes>
</release>
<release>
<date>2010-04-01</date>
<version>
<release>1.2.0</release>
<api>1.2.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>Changes since version 1.2.0b1:
* Fix DIGEST-MD5 authentication (Aleksander Machniak, Bug #17285).
* Don't try to call dl() if mbstring extension isn't loaded (Bug #17038).
Changes since version 1.1.7:
* Added support for adding a custom debug handler (Aleksander Machniak, Request #16681).
* Fix breakage with certain locales, especially Turkish.
* Fix reading authentication responses without literals (Bug #16647).
* Code cleanup.</notes>
</release>
<release>
<date>2009-10-07</date>
<version>
<release>1.2.0b1</release>
<api>1.2.0</api>
</version>
<stability>
<release>beta</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Added support for adding a custom debug handler (Aleksander Machniak, Request #16681).
* Fix breakage with certain locales, especially Turkish.
* Fix reading authentication responses without literals (Bug #16647).
* Code cleanup.</notes>
</release>
<release>
<date>2009-07-24</date>
<version>
<release>1.1.7</release>
<api>1.1.6</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fixed STARTTLS support (Bug #14205).
* Added connect options and EXTERNAL authentication.</notes>
</release>
<release>
<date>2008-03-22</date>
<version>
<release>1.1.6</release>
<api>1.1.6</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>
* Fixed Bug #9273
* Fixed copy/paste error in CRAM and DIGEST authentication error case.
</notes>
</release>
<release>
<date>2006-10-24</date>
<version>
<release>1.1.5</release>
<api>1.1.5</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>
* Fixed Bug connect() bug
* Fixed Request #8071
</notes>
</release>
<release>
<date>2006-09-09</date>
<version>
<release>1.1.4</release>
<api>1.1.4</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>
* Fixed Bug #8452 Unterminated read loop
* Fixed Bug #7845 Add mbstring support
* Added Request #8071 Enable the ability to toggle TLS support if available.
* Added Request #8453 Clean up PHPDoc and comments
</notes>
</release>
<release>
<date>2006-05-21</date>
<version>
<release>1.1.3</release>
<api>1.1.3</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>
* Correctly Fixed Bug #3519 Net_Sieve w/ externally established sockets
* Fixed Bug #7197 getScript() truncates long scripts
* Added PHPUnit2 regression test script
</notes>
</release>
<release>
<date>2006-02-09</date>
<version>
<release>1.1.2</release>
<api>1.1.2</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fixed Request #4053 Added STARTTLS support for PHP 5.1 and above
* Fixed Bug #3519 Net_Sieve w/ externally established sockets
* Fixed Bug #4794 drops protocol prefix, e.g. &quot;ssl://&quot; in referrals
* Fixed STARTTLS detection
* Allow $options[] to be passed to Net_Socket
</notes>
</release>
<release>
<version>
<release>1.1.1</release>
<api>1.1.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2005-02-02</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fixed Bug #3242 cyrus murder referrals not followed
</notes>
</release>
<release>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2004-12-18</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fixed Bug #2728 Linebreaks not being read using getScript()
</notes>
</release>
<release>
<version>
<release>1.0.1</release>
<api>1.0.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2004-03-13</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fixed BUG #1006
</notes>
</release>
<release>
<version>
<release>1.0.0</release>
<api>1.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2004-03-10</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Fixed DIGEST-MD5 sasl version handling (sasl v1.xx responses are diferent than v2.xx)
* Fixed LOGIN Method
</notes>
</release>
<release>
<version>
<release>0.9.1</release>
<api>0.9.1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2004-02-29</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* There is an issue whith the DIGEST-MD5 method. in one installation it does not work but in my server it works perfect! please send me debug info to solve the problem if
it affects you or disable DIGEST-MD5
* some optimizations to the code
* added haveSpace() to check if the server has space to store the script. Use with care HAVESPACE seems to be broken in cyrus 2.0.16
* added hasExtension()
* added getExtensions()
* added referral support and automatic following of them. (it also handles the following of multireferrals).
* removed _getResponse replaced by _doCmd. (thanks to Etienne Goyer for this)
* added supportsAuthMech()
* if installed automatically uses Auth_SASL
* added CRAM-MD5 auth Method
* added DIGEST-MD5 auth Method
* added getAuthMechs() returns an array containing all the auth methods the server supports
* added hasAuthMech() to check if the server has a particular auth method
* _connect --&gt; connect: now is a public method (without breaking BC)
* _login --&gt; login: now is a public method (without breaking BC)
* fix typo cmdAuthenticate() ---&gt; _cmdAuthenticate()
* _doCmd() now parses string responses also.
</notes>
</release>
<release>
<version>
<release>0.9.0</release>
<api>0.9.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2004-01-31</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>* Added setDebug() method and debugging capabilities
* added disconnect() method
* added sample file test_sieve.php
* fixed bug #591
* automagically selects the best auth method
</notes>
</release>
<release>
<version>
<release>0.8.1</release>
<api>0.8.1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2002-07-27</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
<notes>Initial release
</notes>
</release>
<release>
<version>
<release>0.8</release>
<api>0.8</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2002-05-10</date>
<license uri="http://www.php.net/license">PHP</license>
<notes>Initial release
</notes>
</release>
</changelog>
</package>

View File

@@ -0,0 +1,271 @@
<?php
/**
* This file contains the PHPUnit test case for Net_Sieve.
*
* PHP version 5
*
* +-----------------------------------------------------------------------+
* | All rights reserved. |
* | |
* | Redistribution and use in source and binary forms, with or without |
* | modification, are permitted provided that the following conditions |
* | are met: |
* | |
* | o Redistributions of source code must retain the above copyright |
* | notice, this list of conditions and the following disclaimer. |
* | o Redistributions in binary form must reproduce the above copyright |
* | notice, this list of conditions and the following disclaimer in the |
* | documentation and/or other materials provided with the distribution.|
* | |
* | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
* | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
* | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
* | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
* | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
* | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
* | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
* | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* +-----------------------------------------------------------------------+
*
* @category Networking
* @package Net_Sieve
* @author Anish Mistry <amistry@am-productions.biz>
* @copyright 2006 Anish Mistry
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version SVN: $Id$
* @link http://pear.php.net/package/Net_Sieve
*/
require_once dirname(__FILE__) . '/../Sieve.php';
/**
* PHPUnit test case for Net_Sieve.
*
* @category Networking
* @package Net_Sieve
* @author Anish Mistry <amistry@am-productions.biz>
* @copyright 2006 Anish Mistry
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version Release: @package_version@
* @link http://pear.php.net/package/Net_Sieve
*/
class SieveTest extends PHPUnit_Framework_TestCase
{
// contains the object handle of the string class
protected $fixture;
protected function setUp()
{
if (!file_exists(dirname(__FILE__) . '/config.php')) {
$this->markTestSkipped('Test configuration incomplete. Copy config.php.dist to config.php.');
}
require_once dirname(__FILE__) . '/config.php';
// Create a new instance of Net_Sieve.
$this->_pear = new PEAR();
$this->fixture = new Net_Sieve();
$this->scripts = array(
'test script1' => "require \"fileinto\";\n\rif header :contains \"From\" \"@cnba.uba.ar\" \n\r{fileinto \"INBOX.Test1\";}\r\nelse \r\n{fileinto \"INBOX\";}",
'test script2' => "require \"fileinto\";\n\rif header :contains \"From\" \"@cnba.uba.ar\" \n\r{fileinto \"INBOX.Test\";}\r\nelse \r\n{fileinto \"INBOX\";}",
'test"scriptäöü3' => "require \"vacation\";\nvacation\n:days 7\n:addresses [\"matthew@de-construct.com\"]\n:subject \"This is a test\"\n\"I'm on my holiday!\nsadfafs\";",
'test script4' => file_get_contents(dirname(__FILE__) . '/largescript.siv'));
}
protected function tearDown()
{
// Delete the instance.
unset($this->fixture);
}
protected function login()
{
$result = $this->fixture->connect(HOST, PORT);
$this->assertTrue($this->check($result), 'Can not connect');
$result = $this->fixture->login(USERNAME, PASSWORD, null, '', false);
$this->assertTrue($this->check($result), 'Can not login');
}
protected function logout()
{
$result = $this->fixture->disconnect();
$this->assertFalse($this->_pear->isError($result), 'Error on disconnect');
}
protected function clear()
{
// Clear all the scripts in the account.
$this->login();
$active = $this->fixture->getActive();
if (isset($this->scripts[$active])) {
$this->fixture->setActive(null);
}
foreach (array_keys($this->scripts) as $script) {
$this->fixture->removeScript($script);
}
$this->logout();
}
protected function check($result)
{
if ($this->_pear->isError($result)) {
throw new Exception($result->getMessage());
}
return $result;
}
public function testConnect()
{
$result = $this->fixture->connect(HOST, PORT);
$this->assertTrue($this->check($result), 'Cannot connect');
}
public function testLogin()
{
$result = $this->fixture->connect(HOST, PORT);
$this->assertTrue($this->check($result), 'Cannot connect');
$result = $this->fixture->login(USERNAME, PASSWORD, null, '', false);
$this->assertTrue($this->check($result), 'Cannot login');
}
public function testDisconnect()
{
$result = $this->fixture->connect(HOST, PORT);
$this->assertFalse($this->_pear->isError($result), 'Cannot connect');
$result = $this->fixture->login(USERNAME, PASSWORD, null, '', false);
$this->assertFalse($this->_pear->isError($result), 'Cannot login');
$result = $this->fixture->disconnect();
$this->assertFalse($this->_pear->isError($result), 'Error on disconnect');
}
public function testListScripts()
{
$this->login();
$scripts = $this->fixture->listScripts();
$this->logout();
$this->assertFalse($this->_pear->isError($scripts), 'Can not list scripts');
}
public function testInstallScript()
{
$this->clear();
$this->login();
// First script.
$scriptname = 'test script1';
$before_scripts = $this->fixture->listScripts();
$result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
$this->assertFalse($this->_pear->isError($result), 'Can not install script ' . $scriptname);
$after_scripts = $this->fixture->listScripts();
$diff_scripts = array_values(array_diff($after_scripts, $before_scripts));
$this->assertTrue(count($diff_scripts) > 0, 'Script not installed');
$this->assertEquals($scriptname, $diff_scripts[0], 'Added script has a different name');
// Second script (install and activate)
$scriptname = 'test script2';
$before_scripts = $this->fixture->listScripts();
$result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname], true);
$this->assertFalse($this->_pear->isError($result), 'Can not install script ' . $scriptname);
$after_scripts = $this->fixture->listScripts();
$diff_scripts = array_values(array_diff($after_scripts, $before_scripts));
$this->assertTrue(count($diff_scripts) > 0, 'Script not installed');
$this->assertEquals($scriptname, $diff_scripts[0], 'Added script has a different name');
$active_script = $this->fixture->getActive();
$this->assertEquals($scriptname, $active_script, 'Added script has a different name');
$this->logout();
}
/**
* There is a good chance that this test will fail since most servers have
* a 32KB limit on uploaded scripts.
*/
public function testInstallScriptLarge()
{
$this->clear();
$this->login();
$scriptname = 'test script4';
$before_scripts = $this->fixture->listScripts();
$result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
$this->assertFalse($this->_pear->isError($result), 'Unable to upload large script (expected behavior for most servers)');
$after_scripts = $this->fixture->listScripts();
$diff_scripts = array_diff($after_scripts, $before_scripts);
$this->assertEquals($scriptname, reset($diff_scripts), 'Added script has a different name');
$this->logout();
}
/**
* See bug #16691.
*/
public function testInstallNonAsciiScript()
{
$this->clear();
$this->login();
$scriptname = 'test"scriptäöü3';
$before_scripts = $this->fixture->listScripts();
$result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
$this->assertFalse($this->_pear->isError($result), 'Can not install script ' . $scriptname);
$after_scripts = $this->fixture->listScripts();
$diff_scripts = array_values(array_diff($after_scripts, $before_scripts));
$this->assertTrue(count($diff_scripts) > 0, 'Script not installed');
$this->assertEquals($scriptname, $diff_scripts[0], 'Added script has a different name');
$this->logout();
}
public function testGetScript()
{
$this->clear();
$this->login();
$scriptname = 'test script1';
$before_scripts = $this->fixture->listScripts();
$result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
$this->assertFalse($this->_pear->isError($result), 'Can not install script ' . $scriptname);
$after_scripts = $this->fixture->listScripts();
$diff_scripts = array_values(array_diff($after_scripts, $before_scripts));
$this->assertTrue(count($diff_scripts) > 0);
$this->assertEquals($scriptname, $diff_scripts[0], 'Added script has a different name');
$script = $this->fixture->getScript($scriptname);
$this->assertEquals(trim($this->scripts[$scriptname]), trim($script), 'Script installed it not the same script retrieved');
$this->logout();
}
public function testGetActive()
{
$this->clear();
$this->login();
$active_script = $this->fixture->getActive();
$this->assertFalse($this->_pear->isError($active_script), 'Error getting the active script');
$this->logout();
}
public function testSetActive()
{
$this->clear();
$scriptname = 'test script1';
$this->login();
$result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
$result = $this->fixture->setActive($scriptname);
$this->assertFalse($this->_pear->isError($result), 'Can not set active script');
$active_script = $this->fixture->getActive();
$this->assertEquals($scriptname, $active_script, 'Active script does not match');
// Test for non-existant script.
$result = $this->fixture->setActive('non existant script');
$this->assertTrue($this->_pear->isError($result));
$this->logout();
}
public function testRemoveScript()
{
$this->clear();
$scriptname = 'test script1';
$this->login();
$result = $this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
$result = $this->fixture->removeScript($scriptname);
$this->assertFalse($this->_pear->isError($result), 'Error removing active script');
$this->logout();
}
}

View File

@@ -0,0 +1,5 @@
<?php
define('HOST', 'localhost');
define('PORT', 4190);
define('USERNAME', 'user');
define('PASSWORD', 'pass');

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
# Plugin Installer for Roundcube
This installer ensures that plugins end up in the correct directory:
* `<roundcube-root>/plugins/plugin-name`
## Minimum setup
* create a `composer.json` file in your plugin's repository
* add the following contents
### sample composer.json for plugins
{
"name": "yourvendor/plugin-name",
"license": "the license",
"description": "tell the world what your plugin is good at",
"type": "roundcube-plugin",
"authors": [
{
"name": "<your-name>",
"email": "<your-email>"
}
],
"repositories": [
{
"type": "composer",
"url": "http://plugins.roundcube.net"
}
]
"require": {
"roundcube/plugin-installer": "*"
},
"minimum-stability": "dev-master"
}
* Submit your plugin to [plugins.roundcube.net](http://plugins.roundcube.net).
## Installation
* clone Roundcube
* `cp composer.json-dist composer.json`
* add your plugin in the `require` section of composer.json
* `composer.phar install`
Read the whole story at [plugins.roundcube.net](http://plugins.roundcube.net/about).

View File

@@ -0,0 +1,33 @@
{
"name": "roundcube/plugin-installer",
"description": "A composer-installer for Roundcube plugins.",
"type": "composer-installer",
"license": "GPL-3.0+",
"authors": [
{
"name": "Thomas Bruederli",
"email": "thomas@roundcube.net"
},
{
"name": "Till Klampaeckel",
"email": "till@php.net"
}
],
"autoload": {
"psr-0": {
"Roundcube\\Composer": "src/"
}
},
"extra": {
"class": "Roundcube\\Composer\\PluginInstaller"
},
"bin": [
"src/bin/rcubeinitdb.sh"
],
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"composer/composer": "*"
}
}

View File

@@ -0,0 +1,266 @@
<?php
namespace Roundcube\Composer;
use Composer\Installer\LibraryInstaller;
use Composer\Package\Version\VersionParser;
use Composer\Package\LinkConstraint\VersionConstraint;
use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Util\ProcessExecutor;
/**
* @category Plugins
* @package PluginInstaller
* @author Till Klampaeckel <till@php.net>
* @author Thomas Bruederli <thomas@roundcube.net>
* @license GPL-3.0+
* @version GIT: <git_id>
* @link http://github.com/roundcube/plugin-installer
*/
class PluginInstaller extends LibraryInstaller
{
const INSTALLER_TYPE = 'roundcube-plugin';
/**
* {@inheritDoc}
*/
public function getInstallPath(PackageInterface $package)
{
static $vendorDir;
if ($vendorDir === null) {
$vendorDir = $this->getVendorDir();
}
return sprintf('%s/%s', $vendorDir, $this->getPluginName($package));
}
/**
* {@inheritDoc}
*/
public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
{
$this->rcubeVersionCheck($package);
parent::install($repo, $package);
// post-install: activate plugin in Roundcube config
$config_file = $this->rcubeConfigFile();
$extra = $package->getExtra();
$plugin_name = $this->getPluginName($package);
if (is_writeable($config_file) && php_sapi_name() == 'cli') {
$answer = $this->io->askConfirmation("Do you want to activate the plugin $plugin_name? [N|y] ", false);
if (true === $answer) {
$this->rcubeAlterConfig($plugin_name, true);
}
}
// initialize database schema
if (!empty($extra['roundcube']['sql-dir'])) {
if ($sqldir = realpath($this->getVendorDir() . "/$plugin_name/" . $extra['roundcube']['sql-dir'])) {
system(getcwd() . "/vendor/bin/rcubeinitdb.sh --package=$plugin_name --dir=$sqldir");
}
}
// run post-install script
if (!empty($extra['roundcube']['post-install-script'])) {
$this->rcubeRunScript($extra['roundcube']['post-install-script'], $package);
}
}
/**
* {@inheritDoc}
*/
public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
{
$this->rcubeVersionCheck($target);
parent::update($repo, $initial, $target);
$extra = $target->getExtra();
// trigger updatedb.sh
if (!empty($extra['roundcube']['sql-dir'])) {
$plugin_name = $this->getPluginName($target);
if ($sqldir = realpath($this->getVendorDir() . "/$plugin_name/" . $extra['roundcube']['sql-dir'])) {
system(getcwd() . "/bin/updatedb.sh --package=$plugin_name --dir=$sqldir", $res);
}
}
// run post-update script
if (!empty($extra['roundcube']['post-update-script'])) {
$this->rcubeRunScript($extra['roundcube']['post-update-script'], $target);
}
}
/**
* {@inheritDoc}
*/
public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
{
parent::uninstall($repo, $package);
// post-uninstall: deactivate plugin
$plugin_name = $this->getPluginName($package);
$this->rcubeAlterConfig($plugin_name, false);
// run post-uninstall script
$extra = $package->getExtra();
if (!empty($extra['roundcube']['post-uninstall-script'])) {
$this->rcubeRunScript($extra['roundcube']['post-uninstall-script'], $package);
}
}
/**
* {@inheritDoc}
*/
public function supports($packageType)
{
return $packageType === self::INSTALLER_TYPE;
}
/**
* Setup vendor directory to one of these two:
* ./plugins
*
* @return string
*/
public function getVendorDir()
{
$pluginDir = getcwd();
$pluginDir .= '/plugins';
return $pluginDir;
}
/**
* Extract the (valid) plugin name from the package object
*/
private function getPluginName(PackageInterface $package)
{
@list($vendor, $pluginName) = explode('/', $package->getPrettyName());
return strtr($pluginName, '-', '_');
}
/**
* Check version requirements from the "extra" block of a package
* against the local Roundcube version
*/
private function rcubeVersionCheck($package)
{
$parser = new VersionParser;
// read rcube version from iniset
$rootdir = getcwd();
$iniset = @file_get_contents($rootdir . '/program/include/iniset.php');
if (preg_match('/define\(.RCMAIL_VERSION.,\s*.([0-9.]+[a-z-]*)?/', $iniset, $m)) {
$rcubeVersion = $parser->normalize(str_replace('-git', '.999', $m[1]));
} else {
throw new \Exception("Unable to find a Roundcube installation in $rootdir");
}
$extra = $package->getExtra();
if (!empty($extra['roundcube'])) {
foreach (array('min-version' => '>=', 'max-version' => '<=') as $key => $operator) {
if (!empty($extra['roundcube'][$key])) {
$version = $parser->normalize(str_replace('-git', '.999', $extra['roundcube'][$key]));
$constraint = new VersionConstraint($operator, $version);
if (!$constraint->versionCompare($rcubeVersion, $version, $operator)) {
throw new \Exception("Version check failed! " . $package->getName() . " requires Roundcube version $operator $version, $rcubeVersion was detected.");
}
}
}
}
}
/**
* Add or remove the given plugin to the list of active plugins in the Roundcube config.
*/
private function rcubeAlterConfig($plugin_name, $add)
{
$config_file = $this->rcubeConfigFile();
@include($config_file);
$success = false;
$varname = '$config';
if (empty($config) && !empty($rcmail_config)) {
$config = $rcmail_config;
$varname = '$rcmail_config';
}
if (is_array($config) && is_writeable($config_file)) {
$config_templ = @file_get_contents($config_file) ?: '';
$config_plugins = !empty($config['plugins']) ? ((array) $config['plugins']) : array();
$active_plugins = $config_plugins;
if ($add && !in_array($plugin_name, $active_plugins)) {
$active_plugins[] = $plugin_name;
} elseif (!$add && ($i = array_search($plugin_name, $active_plugins)) !== false) {
unset($active_plugins[$i]);
}
if ($active_plugins != $config_plugins) {
$count = 0;
$var_export = "array(\n\t'" . join("',\n\t'", $active_plugins) . "',\n);";
$new_config = preg_replace(
"/(\\$varname\['plugins'\])\s+=\s+(.+);/Uims",
"\\1 = " . $var_export,
$config_templ, -1, $count);
// 'plugins' option does not exist yet, add it...
if (!$count) {
$var_txt = "\n{$varname}['plugins'] = $var_export;\n";
$new_config = str_replace('?>', $var_txt . '?>', $config_templ, $count);
if (!$count) {
$new_config = $config_templ . $var_txt;
}
}
$success = file_put_contents($config_file, $new_config);
}
}
if ($success && php_sapi_name() == 'cli') {
$this->io->write("<info>Updated local config at $config_file</info>");
}
return $success;
}
/**
* Helper method to get an absolute path to the local Roundcube config file
*/
private function rcubeConfigFile()
{
return realpath(getcwd() . '/config/config.inc.php');
}
/**
* Run the given script file
*/
private function rcubeRunScript($script, PackageInterface $package)
{
@list($vendor, $plugin_name) = explode('/', $package->getPrettyName());
// run executable shell script
if (($scriptfile = realpath($this->getVendorDir() . "/$plugin_name/$script")) && is_executable($scriptfile)) {
system($scriptfile, $res);
}
// run PHP script in Roundcube context
else if ($scriptfile && preg_match('/\.php$/', $scriptfile)) {
$incdir = realpath(getcwd() . '/program/include');
include_once($incdir . '/iniset.php');
include($scriptfile);
}
// attempt to execute the given string as shell commands
else {
$process = new ProcessExecutor();
$exitCode = $process->execute($script);
if ($exitCode !== 0) {
throw new \RuntimeException('Error executing script: '. $process->getErrorOutput(), $exitCode);
}
}
}
}

View File

@@ -0,0 +1,130 @@
#!/usr/bin/env php
<?php
define('INSTALL_PATH', getcwd() . '/' );
require_once INSTALL_PATH . 'program/include/clisetup.php';
// get arguments
$opts = rcube_utils::get_opt(array(
'd' => 'dir',
'p' => 'package',
));
if (empty($opts['dir'])) {
rcube::raise_error("Database schema directory not specified (--dir).", false, true);
}
if (empty($opts['package'])) {
rcube::raise_error("Database schema package name not specified (--package).", false, true);
}
// Check if directory exists
if (!file_exists($opts['dir'])) {
rcube::raise_error("Specified database schema directory doesn't exist.", false, true);
}
$RC = rcube::get_instance();
$DB = rcube_db::factory($RC->config->get('db_dsnw'));
// Connect to database
$DB->db_connect('w');
if (!$DB->is_connected()) {
rcube::raise_error("Error connecting to database: " . $DB->is_error(), false, true);
}
$opts['dir'] = rtrim($opts['dir'], DIRECTORY_SEPARATOR);
$file = $opts['dir'] . DIRECTORY_SEPARATOR . $DB->db_provider . '.initial.sql';
if (!file_exists($file)) {
rcube::raise_error("No DDL file found for " . $DB->db_provider . " driver.", false, true);
}
$package = $opts['package'];
$error = false;
// read DDL file
if ($lines = file($file)) {
$sql = '';
foreach ($lines as $line) {
if (preg_match('/^--/', $line) || trim($line) == '')
continue;
$sql .= $line . "\n";
if (preg_match('/(;|^GO)$/', trim($line))) {
@$DB->query(fix_table_names($sql));
$sql = '';
if ($error = $DB->is_error()) {
break;
}
}
}
}
if (!$error) {
$version = date('Ymd00');
$system_table = $DB->quote_identifier($DB->table_name('system'));
$name_col = $DB->quote_identifier('name');
$value_col = $DB->quote_identifier('value');
$package_version = $package . '-version';
$DB->query("SELECT * FROM $system_table WHERE $name_col=?",
$package_version);
if ($DB->fetch_assoc()) {
$DB->query("UPDATE $system_table SET $value_col=? WHERE $name_col=?",
$version, $package_version);
}
else {
$DB->query("INSERT INTO $system_table ($name_col, $value_col) VALUES (?, ?)",
$package_version, $version);
}
$error = $DB->is_error();
}
if ($error) {
echo "[FAILED]\n";
rcube::raise_error("Error in DDL schema $file: $error", false, true);
}
echo "[OK]\n";
function fix_table_names($sql)
{
global $DB, $RC;
$prefix = $RC->config->get('db_prefix');
$engine = $DB->db_provider;
if (empty($prefix)) {
return $sql;
}
$tables = array();
$sequences = array();
// find table names
if (preg_match_all('/CREATE TABLE (\[dbo\]\.|IF NOT EXISTS )?[`"\[\]]*([^`"\[\] \r\n]+)/i', $sql, $matches)) {
foreach ($matches[2] as $table) {
$tables[$table] = $prefix . $table;
}
}
// find sequence names
if ($engine == 'postgres' && preg_match_all('/CREATE SEQUENCE (IF NOT EXISTS )?"?([^" \n\r]+)/i', $sql, $matches)) {
foreach ($matches[2] as $sequence) {
$sequences[$sequence] = $prefix . $sequence;
}
}
// replace table names
foreach ($tables as $table => $real_table) {
$sql = preg_replace("/([^a-zA-Z0-9_])$table([^a-zA-Z0-9_])/", "\\1$real_table\\2", $sql);
}
// replace sequence names
foreach ($sequences as $sequence => $real_sequence) {
$sql = preg_replace("/([^a-zA-Z0-9_])$sequence([^a-zA-Z0-9_])/", "\\1$real_sequence\\2", $sql);
}
return $sql;
}
?>