Aleksander Machniak
2013-08-04 b825f86108a91957f6467176e418cfc257874658
Move identity selection based on non-standard headers into (new) identity_select plugin (#1488553)
3 files added
3 files modified
170 ■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
plugins/identity_select/identity_select.php 68 ●●●●● patch | view | raw | blame | history
plugins/identity_select/package.xml 53 ●●●●● patch | view | raw | blame | history
plugins/identity_select/tests/IdentitySelect.php 22 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_storage.php 2 ●●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 24 ●●●● patch | view | raw | blame | history
CHANGELOG
@@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Move identity selection based on non-standard headers into (new) identity_select plugin (#1488553)
- Fix colorspace issue on image conversion using ImageMagick (#1489270)
- Fix XSS vulnerability when editing a message "as new" or draft (#1489251)
- Fix downloading binary files with (wrong) text/* content-type (#1489267)
plugins/identity_select/identity_select.php
New file
@@ -0,0 +1,68 @@
<?php
/**
 * Identity selection based on additional message headers.
 *
 * On reply to a message user identity selection is based on
 * content of standard headers i.e. From, To, Cc and Return-Path.
 * Here you can add header(s) set by your SMTP server (e.g.
 * Delivered-To, Envelope-To, X-Envelope-To, X-RCPT-TO) to make
 * identity selection more accurate.
 *
 * Enable the plugin in config.inc.php and add your desired headers:
 *   $rcmail_config['identity_select_headers'] = array('Delivered-To');
 *
 * @version @package_version@
 * @author Aleksander Machniak <alec@alec.pl>
 * @license GNU GPLv3+
 */
class identity_select extends rcube_plugin
{
    public $task = 'mail';
    function init()
    {
        $this->add_hook('identity_select', array($this, 'select'));
        $this->add_hook('storage_init', array($this, 'storage_init'));
    }
    /**
     * Adds additional headers to supported headers list
     */
    function storage_init($p)
    {
        $rcmail = rcmail::get_instance();
        if ($add_headers = (array)$rcmail->config->get('identity_select_headers', array())) {
            $p['fetch_headers'] = trim($p['fetch_headers'] . ' ' . strtoupper(join(' ', $add_headers)));
        }
        return $p;
    }
    /**
     * Identity selection
     */
    function select($p)
    {
        if ($p['selected'] !== null) {
            return $p;
        }
        $rcmail = rcmail::get_instance();
        foreach ((array)$rcmail->config->get('identity_select_headers', array()) as $header) {
            if ($header = $p['message']->headers->get($header, false)) {
                foreach ($p['identities'] as $idx => $ident) {
                    if (in_array($ident['email_ascii'], (array)$header)) {
                        $p['selected'] = $idx;
                        break 2;
                    }
                }
            }
        }
        return $p;
    }
}
plugins/identity_select/package.xml
New file
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<package 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" packagerversion="1.9.0" version="2.0" 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>identity_select</name>
    <channel>pear.roundcube.net</channel>
    <summary>Extended identity selection</summary>
    <description>
        On reply to a message user identity selection is based on
        content of standard headers like From, To, Cc and Return-Path.
        Here you can add header(s) set by your SMTP server (e.g.
        Delivered-To, Envelope-To, X-Envelope-To, X-RCPT-TO) to make
        identity selection more accurate.
    </description>
    <lead>
        <name>Aleksander Machniak</name>
        <user>alec</user>
        <email>alec@alec.pl</email>
        <active>yes</active>
    </lead>
    <date>2013-08-04</date>
    <version>
        <release>1.0</release>
        <api>1.0</api>
    </version>
    <stability>
        <release>stable</release>
        <api>stable</api>
    </stability>
    <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
    <notes>-</notes>
    <contents>
        <dir baseinstalldir="/" name="/">
            <file name="identity_select.php" role="php">
                <tasks:replace from="@name@" to="name" type="package-info"/>
                <tasks:replace from="@package_version@" to="version" type="package-info"/>
            </file>
        </dir>
        <!-- / -->
    </contents>
    <dependencies>
        <required>
            <php>
                <min>5.2.1</min>
            </php>
            <pearinstaller>
                <min>1.7.0</min>
            </pearinstaller>
        </required>
    </dependencies>
    <phprelease/>
</package>
plugins/identity_select/tests/IdentitySelect.php
New file
@@ -0,0 +1,22 @@
<?php
class IdentitySelect_Plugin extends PHPUnit_Framework_TestCase
{
    function setUp()
    {
        include_once dirname(__FILE__) . '/../identity_select.php';
    }
    /**
     * Plugin object construction test
     */
    function test_constructor()
    {
        $rcube  = rcube::get_instance();
        $plugin = new identity_select($rcube->api);
        $this->assertInstanceOf('identity_select', $plugin);
        $this->assertInstanceOf('rcube_plugin', $plugin);
    }
}
program/lib/Roundcube/rcube_storage.php
@@ -61,8 +61,6 @@
        'MAIL-FOLLOWUP-TO',
        'MAIL-REPLY-TO',
        'RETURN-PATH',
        'DELIVERED-TO',
        'ENVELOPE-TO',
    );
    const UNKNOWN       = 0;
program/steps/mail/func.inc
@@ -1798,27 +1798,13 @@
        }
    }
    // Fallback using Delivered-To
    if ($from_idx === null && ($delivered_to = $MESSAGE->headers->others['delivered-to'])) {
        foreach ($identities as $idx => $ident) {
            if (in_array($ident['email_ascii'], (array)$delivered_to)) {
                $from_idx = $idx;
                break;
            }
        }
    }
    // See identity_select plugin for example usage of this hook
    $plugin = rcmail::get_instance()->plugins->exec_hook('identity_select',
        array('message' => $MESSAGE, 'identities' => $identities, 'selected' => $from_idx));
    // Fallback using Envelope-To
    if ($from_idx === null && ($envelope_to = $MESSAGE->headers->others['envelope-to'])) {
        foreach ($identities as $idx => $ident) {
            if (in_array($ident['email_ascii'], (array)$envelope_to)) {
                $from_idx = $idx;
                break;
            }
        }
    }
    $selected = $plugin['selected'];
    return $identities[$from_idx !== null ? $from_idx : $default_identity];
    return $identities[$selected !== null ? $selected : $default_identity];
}
// Fixes some content-type names