Skip to content

Commit

Permalink
Support setting roundcube's default addressbook to an addressbook fro…
Browse files Browse the repository at this point in the history
…m a preset (Fixes #440)
  • Loading branch information
mstilkerich committed Aug 19, 2023
1 parent 7f27a2d commit bd2abfe
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Allow to hide contacts without email also for user-defined addressbooks (Fixes #429)
- Re-introduced option `preemptive_basic_auth` to send HTTP basic Authorization header with every request (Fixes #407)
- Support setting roundcube's default addressbook to an addressbook from a preset (Fixes #440)

## Version 5.0.1 (to 5.0.0)

Expand Down
12 changes: 10 additions & 2 deletions config.inc.php.dist
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
$prefs['_GLOBAL']['loglevel'] = \Psr\Log\LogLevel::WARNING;
$prefs['_GLOBAL']['loglevel_http'] = \Psr\Log\LogLevel::ERROR;

// Select addressbook from preset to use as Roundcube's collected recipients or collected/trusted senders addressbook,
// corresponding to the roundcube options of the same name available since roundcube 1.5.
// Select addressbook from preset to use as Roundcube's collected recipients, collected/trusted senders or default
// addressbook, corresponding to the roundcube options of the same name available since roundcube 1.5.
// Note that only writeable addressbooks can be used for this. If you do not want to use these options, simply do not
// define them
// If no/several addressbooks match, the roundcube setting will not be changed
Expand All @@ -50,6 +50,14 @@ $prefs['_GLOBAL']['loglevel_http'] = \Psr\Log\LogLevel::ERROR;
// 'matchname' => '/collected recipients/i',
// 'matchurl' => '#http://carddav.example.com/abooks/%u/CollectedRecipients#',
//];
//$prefs['_GLOBAL']['default_addressbook'] = [
// // Key of the preset, i.e. whatever is used for <Presetname> in the template below
// 'preset' => '<Presetname>',
// // The placeholders that can be used in the url attribute can also be used inside these regular rexpressions
// // If both matchname and matchurl are given, both need to match for the addressbook to be used
// 'matchname' => '/collected recipients/i',
// 'matchurl' => '#http://carddav.example.com/abooks/%u/CollectedRecipients#',
//];

//// ** ACCOUNT PRESETS

Expand Down
14 changes: 9 additions & 5 deletions doc/ADMIN-SETTINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,15 +304,16 @@ Preconfigured addressbooks are processed when the user logs into roundcube.
- If the user has addressbooks created from a preset that no longer exists (identified by the Presetname), the
addressbooks are deleted from the database.

### Using presets for the roundcube trusted senders/collected recipients addressbooks
### Using presets for the roundcube trusted senders/collected recipients addressbooks and default addressbook

Roundcube 1.5 and newer has two special internal addressbooks to automatically collect all addresses the user previously
sent mail to (roundcube config option: `collected_recipients`) and to collect addresses of trusted senders (roundcube
config option: `collected_senders`).

It is possible for a user to manually select CardDAV addressbooks for these two special purpose addressbooks using
the roundcube settings interface. When using preconfigured CardDAV addressbooks, the admin may want to also set these
special addressbooks by configuration, which is possible using the following configuration options:
It is possible for a user to manually select CardDAV addressbooks for these two special purpose addressbooks and the
roundcube default addressbook using the roundcube settings interface. When using preconfigured CardDAV addressbooks, the
admin may want to also set these special addressbooks or the default addressbook by configuration, which is possible
using the following configuration options:

```php
$prefs['_GLOBAL']['collected_recipients'] = [
Expand All @@ -325,6 +326,9 @@ $prefs['_GLOBAL']['collected_recipients'] = [
$prefs['_GLOBAL']['collected_senders'] = [
// Configuration analog to collected recipients
];
$prefs['_GLOBAL']['default_addressbook'] = [
// Configuration analog to collected recipients
];
```

Each of the above RCMCardDAV settings will cause the roundcube setting of the same name to be overridden in case a
Expand Down Expand Up @@ -355,7 +359,7 @@ Configuration of these addressbooks by the user can be disabled using the follow
roundcube (not RCMCardDAV) configuration:

```php
$config['dont_override'] = ['collected_recipients', 'collected_senders'];
$config['dont_override'] = ['collected_recipients', 'collected_senders', 'default_addressbook'];
```

When using the trusted senders addressbook, please also configure the roundcube options `show_images` and `mdn_requests`
Expand Down
4 changes: 2 additions & 2 deletions src/Frontend/AdminSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
* @psalm-type ConfigurablePresetAttr = 'accountname'|'discovery_url'|'username'|'password'|'rediscover_time'|
* 'active'|'refresh_time'|'use_categories'|'readonly'|'require_always_email'|
* 'name'|'preemptive_basic_auth'|'ssl_noverify'
* @psalm-type SpecialAbookType = 'collected_recipients'|'collected_senders'
* @psalm-type SpecialAbookType = 'collected_recipients'|'collected_senders'|'default_addressbook'
* @psalm-type SpecialAbookMatch = array{preset: string, matchname?: string, matchurl?: string}
*
* @psalm-type PresetExtraAbook = array{
Expand Down Expand Up @@ -258,7 +258,7 @@ public function __construct(string $configfile, LoggerInterface $logger, LoggerI
}

// Extract filter for special addressbooks
foreach ([ 'collected_recipients', 'collected_senders' ] as $setting) {
foreach ([ 'collected_recipients', 'collected_senders', 'default_addressbook' ] as $setting) {
if (isset($gprefs[$setting]) && is_array($gprefs[$setting])) {
$matchSettings = $gprefs[$setting];

Expand Down
46 changes: 11 additions & 35 deletions tests/Unit/AdminSettingsWithDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,35 +56,38 @@ public function tearDown(): void
}

/**
* @return array<string, list{string, list{?string,?string}}>
* @return array<string, list{string, list{?string,?string, ?string}}>
*/
public function specialAbookTestProvider(): array
{
$base = 'tests/Unit/data/adminSettingsWithDataTest';

return [
'Two matchers, one match' => [ "$base/matchBoth.php", ['43', '43'] ],
'Two matchers, one match' => [ "$base/matchBoth.php", ['43', '43', '43'] ],
'No matches (invalid preset, AND condition eval)' => [
"$base/noMatch.php",
[
'Setting for collected_recipients must include a valid preset attribute',
'Cannot set special addressbook collected_senders, there are 0 candidates (need: 1)'
'Cannot set special addressbook collected_senders, there are 0 candidates (need: 1)',
'Cannot set special addressbook default_addressbook, there are 0 candidates (need: 1)'
]
],
'Multiple matches' => [
"$base/matchMultiple.php",
[
'Cannot set special addressbook collected_recipients, there are 2 candidates (need: 1)',
'Cannot set special addressbook collected_senders, there are 2 candidates (need: 1)'
'Cannot set special addressbook collected_senders, there are 2 candidates (need: 1)',
'Cannot set special addressbook default_addressbook, there are 2 candidates (need: 1)'
]
],
'Preset not yet in DB' => [ "$base/presetNotInDbYet.php", [null, null] ],
'Preset not yet in DB' => [ "$base/presetNotInDbYet.php", [null, null, null] ],
];
}

/**
* @param string $admSettingsPath Path name of config.inc.php file
* @param list{?string,?string} $expIds Expected abook IDs for 0: collected_recipients, 1: collected_senders
* @param list{?string,?string,?string} $expIds Expected abook IDs for 0: collected_recipients,
* 1: collected_senders, 2: default_addressbook
* @dataProvider specialAbookTestProvider
*/
public function testSpecialAddressbooksReturnedCorrectly(string $admSettingsPath, array $expIds): void
Expand All @@ -100,7 +103,7 @@ public function testSpecialAddressbooksReturnedCorrectly(string $admSettingsPath
$specialAbooks = $admPrefs->getSpecialAddressbooks($abMgr, $infra);

$i = 0;
foreach (['collected_recipients', 'collected_senders'] as $abookType) {
foreach (['collected_recipients', 'collected_senders', 'default_addressbook'] as $abookType) {
if (isset($expIds[$i])) {
if (strpos($expIds[$i], ' ') === false) {
$this->assertArrayHasKey($abookType, $specialAbooks);
Expand All @@ -113,7 +116,7 @@ public function testSpecialAddressbooksReturnedCorrectly(string $admSettingsPath
$this->assertArrayNotHasKey($abookType, $specialAbooks);
}

$i = 1;
$i++;
}
}

Expand Down Expand Up @@ -194,33 +197,6 @@ public function testTemplateAddressbookProvidedCorrectly(): void
$this->assertArrayNotHasKey('template', $tmpl);
}

/**
* @return array<string, list{string, list{?string,?string}}>
*/
public function initPresetDataProvider(): array
{
$base = 'tests/Unit/data/adminSettingsWithDataTest';

return [
'Two matchers, one match' => [ "$base/matchBoth.php", ['43', '43'] ],
'No matches (invalid preset, AND condition eval)' => [
"$base/noMatch.php",
[
'Setting for collected_recipients must include a valid preset attribute',
'Cannot set special addressbook collected_senders, there are 0 candidates (need: 1)'
]
],
'Multiple matches' => [
"$base/matchMultiple.php",
[
'Cannot set special addressbook collected_recipients, there are 2 candidates (need: 1)',
'Cannot set special addressbook collected_senders, there are 2 candidates (need: 1)'
]
],
'Preset not yet in DB' => [ "$base/presetNotInDbYet.php", [null, null] ],
];
}

/**
* Tests that presets are initialized and updated properly by AdminSettings::initPresets().
*
Expand Down
4 changes: 4 additions & 0 deletions tests/Unit/data/adminSettingsTest/fullconfig.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
'preset' => 'OnlyShared',
'matchname' => '/shared %d addressbook/i',
];
$prefs['_GLOBAL']['default_addressbook'] = [
'preset' => 'Preset1',
'matchurl' => '#.*\.example\.com/%d/%l/%u#',
];

$prefs['Preset1'] = [
'accountname' => 'First Preset',
Expand Down
4 changes: 4 additions & 0 deletions tests/Unit/data/adminSettingsTest/fullconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"collected_senders": {
"preset": "OnlyShared",
"matchname": "/shared example\\.com addressbook/i"
},
"default_addressbook": {
"preset": "Preset1",
"matchurl": "#.*\\.example\\.com/example\\.com/user/user@example\\.com#"
}
},
"presets": {
Expand Down
7 changes: 7 additions & 0 deletions tests/Unit/data/adminSettingsWithDataTest/matchBoth.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
'matchurl' => '#^https://carddav.example.com/books/%l/book43/$#',
];

$prefs['_GLOBAL']['default_addressbook'] = [
'preset' => 'AdmPreset',
'matchname' => '/Add/i',
'matchurl' => '#^https://carddav.example.com/books/%l/book43/$#',
];


$prefs['AdmPreset'] = [
'accountname' => 'Admin Preset',
'discovery_url' => 'https://carddav.example.com/',
Expand Down
5 changes: 5 additions & 0 deletions tests/Unit/data/adminSettingsWithDataTest/matchMultiple.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
'matchurl' => '/%u/',
];

$prefs['_GLOBAL']['default_addressbook'] = [
'preset' => 'AdmPreset',
'matchname' => '/Add/',
];

$prefs['AdmPreset'] = [
'accountname' => 'Admin Preset',
'discovery_url' => 'https://carddav.example.com/',
Expand Down
6 changes: 6 additions & 0 deletions tests/Unit/data/adminSettingsWithDataTest/noMatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
'matchurl' => '#^https://carddav.example.com/books/%l/book43/$#',
];

$prefs['_GLOBAL']['default_addressbook'] = [
'preset' => 'AdmPreset',
'matchname' => '/Addr/i',
'matchurl' => '#^https://carddav.example.com/books/%l/book43/$#',
];

$prefs['AdmPreset'] = [
'accountname' => 'Admin Preset',
'discovery_url' => 'https://carddav.example.com/',
Expand Down

0 comments on commit bd2abfe

Please sign in to comment.