Skip to content

Commit f81e58d

Browse files
committed
Fix overwrite-groups config
This is a new implementation of the group handling introduced in #125 The previous implementation failed to preserve provider groups properly. This also adds tests for the behaviour.
1 parent 406863f commit f81e58d

File tree

2 files changed

+91
-20
lines changed

2 files changed

+91
-20
lines changed

OAuthManager.php

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,20 @@ protected function processUserData($userdata, $servicename)
239239
if (!in_array($auth->cleanGroup($servicename), $localUserInfo['grps'])) {
240240
throw new Exception('authnotenabled', [$servicename]);
241241
}
242+
243+
$helper = plugin_load('helper', 'oauth');
244+
242245
$userdata['user'] = $localUser;
243246
$userdata['name'] = $localUserInfo['name'];
244-
$userdata['grps'] = $this->mergeGroups($localUserInfo['grps'], $userdata, $servicename, $auth->getConf('overwrite-groups'));
247+
$userdata['grps'] = $this->mergeGroups(
248+
$localUserInfo['grps'],
249+
$userdata['grps'] ?? [],
250+
array_keys($helper->listServices(false)),
251+
$auth->getConf('overwrite-groups')
252+
);
245253

246254
// update user
247-
$auth->modifyUser($localUser, $userdata);
255+
$auth->modifyUser($localUser, $userdata);
248256
} elseif (actionOK('register') || $auth->getConf('register-on-auth')) {
249257
if (!$auth->registerOAuthUser($userdata, $servicename)) {
250258
throw new Exception('generic create error');
@@ -260,33 +268,23 @@ protected function processUserData($userdata, $servicename)
260268
* Merges local and provider user groups. Keeps internal
261269
* Dokuwiki groups unless configured to overwrite all ('overwrite-groups' setting)
262270
*
263-
* @param array $localGroups Local user groups
264-
* @param array $userdata User data from provider, may contain groups
265-
* @param string $servicename
271+
* @param string[] $localGroups Local user groups
272+
* @param string[] $providerGroups Groups fetched from the provider
273+
* @param string[] $servicenames Service names that should be kept if set
266274
* @param bool $overwrite Config setting to overwrite local DokuWiki groups
267275
*
268276
* @return array
269277
*/
270-
protected function mergeGroups($localGroups, $userdata, $servicename, $overwrite)
278+
protected function mergeGroups($localGroups, $providerGroups, $servicenames, $overwrite)
271279
{
272-
// no groups from provider, simply use local ones
273-
if (empty($userdata['grps'])) {
274-
return $localGroups;
275-
}
280+
global $conf;
276281

277-
// overwrite-groups set in config, use only groups from provider
282+
// overwrite-groups set in config - remove all local groups except services and default
278283
if ($overwrite) {
279-
return $userdata['grps'];
284+
$localGroups = array_intersect($localGroups, array_merge($servicenames, [$conf['defaultgroup']]));
280285
}
281286

282-
// otherwise keep reserved local groups and add those from provider
283-
global $conf;
284-
$helper = plugin_load('helper', 'oauth');
285-
$services = $helper->listServices(false);
286-
$localOauth = array_intersect($localGroups, array_keys($services));
287-
$reservedLocal = array_merge([$conf['defaultgroup']], $localOauth);
288-
289-
return array_merge($userdata['grps'], $reservedLocal);
287+
return array_unique(array_merge($localGroups, $providerGroups));
290288
}
291289

292290
/**

_test/MergeGroupsTest.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\oauth\test;
4+
5+
use dokuwiki\plugin\oauth\Exception;
6+
use dokuwiki\plugin\oauth\OAuthManager;
7+
use DokuWikiTest;
8+
9+
/**
10+
* user data validation tests for the oauth plugin
11+
*
12+
* @group plugin_oauth
13+
* @group plugins
14+
*/
15+
class MergeGroupsTest extends DokuWikiTest
16+
{
17+
18+
protected $pluginsEnabled = ['oauth'];
19+
20+
/**
21+
* @see testMergeGroups
22+
*/
23+
public function provideTestData()
24+
{
25+
return [
26+
[
27+
['hello', 'provider1', 'service', 'user'],
28+
['provider1', 'provider2'],
29+
['service', 'service2'],
30+
false,
31+
['hello', 'provider1', 'provider2', 'service', 'user']
32+
],
33+
[
34+
['hello', 'provider1', 'service', 'user'],
35+
['provider1', 'provider2'],
36+
['service', 'service2'],
37+
true,
38+
['provider1', 'provider2', 'service', 'user']
39+
],
40+
[
41+
['hello', 'provider1', 'service', 'user'],
42+
[],
43+
['service', 'service2'],
44+
false,
45+
['hello', 'provider1', 'service', 'user']
46+
],
47+
[
48+
['hello', 'provider1', 'service', 'user'],
49+
[],
50+
['service', 'service2'],
51+
true,
52+
['service', 'user']
53+
]
54+
];
55+
}
56+
57+
/**
58+
* @dataProvider provideTestData
59+
*/
60+
public function testMergeGroups($localGroups, $providerGroups, $services, $overwrite, $expect)
61+
{
62+
$oauthMgr = new OAuthManager();
63+
$result = $this->callInaccessibleMethod(
64+
$oauthMgr, 'mergeGroups',
65+
[$localGroups, $providerGroups, $services, $overwrite]
66+
);
67+
sort($expect);
68+
sort($result);
69+
70+
$this->assertEquals($expect, $result);
71+
}
72+
73+
}

0 commit comments

Comments
 (0)