Skip to content

Commit c91ae11

Browse files
authored
Merge pull request #14502 from nextcloud/feature/noid/add-activities-for-group-membership-changes
Add activities for group membership changes
2 parents 5decee6 + d3d885f commit c91ae11

File tree

6 files changed

+408
-0
lines changed

6 files changed

+408
-0
lines changed

lib/composer/composer/autoload_classmap.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,8 @@
10651065
'OC\\Session\\Internal' => $baseDir . '/lib/private/Session/Internal.php',
10661066
'OC\\Session\\Memory' => $baseDir . '/lib/private/Session/Memory.php',
10671067
'OC\\Session\\Session' => $baseDir . '/lib/private/Session/Session.php',
1068+
'OC\\Settings\\Activity\\GroupProvider' => $baseDir . '/settings/Activity/GroupProvider.php',
1069+
'OC\\Settings\\Activity\\GroupSetting' => $baseDir . '/settings/Activity/GroupSetting.php',
10681070
'OC\\Settings\\Activity\\Provider' => $baseDir . '/settings/Activity/Provider.php',
10691071
'OC\\Settings\\Activity\\SecurityFilter' => $baseDir . '/settings/Activity/SecurityFilter.php',
10701072
'OC\\Settings\\Activity\\SecurityProvider' => $baseDir . '/settings/Activity/SecurityProvider.php',

lib/composer/composer/autoload_static.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
10951095
'OC\\Session\\Internal' => __DIR__ . '/../../..' . '/lib/private/Session/Internal.php',
10961096
'OC\\Session\\Memory' => __DIR__ . '/../../..' . '/lib/private/Session/Memory.php',
10971097
'OC\\Session\\Session' => __DIR__ . '/../../..' . '/lib/private/Session/Session.php',
1098+
'OC\\Settings\\Activity\\GroupProvider' => __DIR__ . '/../../..' . '/settings/Activity/GroupProvider.php',
1099+
'OC\\Settings\\Activity\\GroupSetting' => __DIR__ . '/../../..' . '/settings/Activity/GroupSetting.php',
10981100
'OC\\Settings\\Activity\\Provider' => __DIR__ . '/../../..' . '/settings/Activity/Provider.php',
10991101
'OC\\Settings\\Activity\\SecurityFilter' => __DIR__ . '/../../..' . '/settings/Activity/SecurityFilter.php',
11001102
'OC\\Settings\\Activity\\SecurityProvider' => __DIR__ . '/../../..' . '/settings/Activity/SecurityProvider.php',
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
<?php
2+
/**
3+
* @copyright Copyright (c) 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
4+
*
5+
* @author Christoph Wurst <christoph@owncloud.com>
6+
* @author Joas Schilling <coding@schilljs.com>
7+
*
8+
* @license GNU AGPL version 3 or any later version
9+
*
10+
* This program is free software: you can redistribute it and/or modify
11+
* it under the terms of the GNU Affero General Public License as
12+
* published by the Free Software Foundation, either version 3 of the
13+
* License, or (at your option) any later version.
14+
*
15+
* This program is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU Affero General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU Affero General Public License
21+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
*
23+
*/
24+
25+
namespace OC\Settings\Activity;
26+
27+
use InvalidArgumentException;
28+
use OCP\Activity\IEvent;
29+
use OCP\Activity\IManager;
30+
use OCP\Activity\IProvider;
31+
use OCP\IGroup;
32+
use OCP\IGroupManager;
33+
use OCP\IURLGenerator;
34+
use OCP\IUser;
35+
use OCP\IUserManager;
36+
use OCP\L10N\IFactory as L10nFactory;
37+
38+
class GroupProvider implements IProvider {
39+
40+
public const ADDED_TO_GROUP = 'group_added';
41+
public const REMOVED_FROM_GROUP = 'group_removed';
42+
43+
/** @var L10nFactory */
44+
private $l10n;
45+
/** @var IURLGenerator */
46+
private $urlGenerator;
47+
/** @var IManager */
48+
private $activityManager;
49+
/** @var IUserManager */
50+
protected $userManager;
51+
/** @var IGroupManager */
52+
protected $groupManager;
53+
54+
/** @var string[] */
55+
protected $groupDisplayNames = [];
56+
/** @var string[] */
57+
protected $userDisplayNames = [];
58+
59+
60+
public function __construct(L10nFactory $l10n,
61+
IURLGenerator $urlGenerator,
62+
IManager $activityManager,
63+
IUserManager $userManager,
64+
IGroupManager $groupManager) {
65+
$this->urlGenerator = $urlGenerator;
66+
$this->l10n = $l10n;
67+
$this->activityManager = $activityManager;
68+
$this->userManager = $userManager;
69+
$this->groupManager = $groupManager;
70+
}
71+
72+
public function parse($language, IEvent $event, IEvent $previousEvent = null) {
73+
if ($event->getType() !== 'group_settings') {
74+
throw new InvalidArgumentException();
75+
}
76+
77+
$l = $this->l10n->get('settings', $language);
78+
79+
$params = $event->getSubjectParameters();
80+
$parsedParameters = [
81+
'user' => $this->generateUserParameter($params['user']),
82+
'group' => $this->generateGroupParameter($params['group']),
83+
];
84+
85+
if (isset($params['actor'])) {
86+
$parsedParameters['actor'] = $this->generateUserParameter($params['actor']);
87+
}
88+
89+
switch ($event->getSubject()) {
90+
case self::ADDED_TO_GROUP:
91+
if (isset($parsedParameters['actor'])) {
92+
if ($this->activityManager->getCurrentUserId() === $params['user']) {
93+
$subject = $l->t('{actor} added you to group {group}');
94+
} elseif (isset($params['actor']) && $this->activityManager->getCurrentUserId() === $params['actor']) {
95+
$subject = $l->t('You added {user} to group {group}');
96+
} else {
97+
$subject = $l->t('{actor} added {user} to group {group}');
98+
}
99+
} else if ($this->activityManager->getCurrentUserId() === $params['user']) {
100+
$subject = $l->t('An administrator added you to group {group}');
101+
} else {
102+
$subject = $l->t('An administrator added {user} to group {group}');
103+
}
104+
break;
105+
case self::REMOVED_FROM_GROUP:
106+
if (isset($parsedParameters['actor'])) {
107+
if ($this->activityManager->getCurrentUserId() === $params['user']) {
108+
$subject = $l->t('{actor} removed you from group {group}');
109+
} elseif (isset($params['actor']) && $this->activityManager->getCurrentUserId() === $params['actor']) {
110+
$subject = $l->t('You removed {user} from group {group}');
111+
} else {
112+
$subject = $l->t('{actor} removed {user} from group {group}');
113+
}
114+
} else if ($this->activityManager->getCurrentUserId() === $params['user']) {
115+
$subject = $l->t('An administrator removed you from group {group}');
116+
} else {
117+
$subject = $l->t('An administrator removed {user} from group {group}');
118+
}
119+
break;
120+
default:
121+
throw new InvalidArgumentException();
122+
}
123+
124+
$this->setSubjects($event, $subject, $parsedParameters);
125+
126+
return $event;
127+
}
128+
129+
/**
130+
* @param IEvent $event
131+
* @param string $subject
132+
* @param array $parameters
133+
* @throws \InvalidArgumentException
134+
*/
135+
protected function setSubjects(IEvent $event, string $subject, array $parameters): void {
136+
$placeholders = $replacements = [];
137+
foreach ($parameters as $placeholder => $parameter) {
138+
$placeholders[] = '{' . $placeholder . '}';
139+
$replacements[] = $parameter['name'];
140+
}
141+
142+
$event->setParsedSubject(str_replace($placeholders, $replacements, $subject))
143+
->setRichSubject($subject, $parameters);
144+
}
145+
146+
/**
147+
* @param string $gid
148+
* @return array
149+
*/
150+
protected function generateGroupParameter(string $gid): array {
151+
if (!isset($this->groupDisplayNames[$gid])) {
152+
$this->groupDisplayNames[$gid] = $this->getGroupDisplayName($gid);
153+
}
154+
155+
return [
156+
'type' => 'user-group',
157+
'id' => $gid,
158+
'name' => $this->groupDisplayNames[$gid],
159+
];
160+
}
161+
162+
/**
163+
* @param string $gid
164+
* @return string
165+
*/
166+
protected function getGroupDisplayName(string $gid): string {
167+
$group = $this->groupManager->get($gid);
168+
if ($group instanceof IGroup) {
169+
return $group->getDisplayName();
170+
}
171+
return $gid;
172+
}
173+
174+
/**
175+
* @param string $uid
176+
* @return array
177+
*/
178+
protected function generateUserParameter(string $uid): array {
179+
if (!isset($this->displayNames[$uid])) {
180+
$this->userDisplayNames[$uid] = $this->getDisplayName($uid);
181+
}
182+
183+
return [
184+
'type' => 'user',
185+
'id' => $uid,
186+
'name' => $this->userDisplayNames[$uid],
187+
];
188+
}
189+
190+
/**
191+
* @param string $uid
192+
* @return string
193+
*/
194+
protected function getDisplayName(string $uid): string {
195+
$user = $this->userManager->get($uid);
196+
if ($user instanceof IUser) {
197+
return $user->getDisplayName();
198+
} else {
199+
return $uid;
200+
}
201+
}
202+
}

settings/Activity/GroupSetting.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
/**
3+
* @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
4+
*
5+
* @author Joas Schilling <coding@schilljs.com>
6+
*
7+
* @license GNU AGPL version 3 or any later version
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
namespace OC\Settings\Activity;
25+
26+
use OCP\Activity\ISetting;
27+
use OCP\IL10N;
28+
29+
class GroupSetting implements ISetting {
30+
31+
/** @var IL10N */
32+
protected $l;
33+
34+
/**
35+
* @param IL10N $l10n
36+
*/
37+
public function __construct(IL10N $l10n) {
38+
$this->l = $l10n;
39+
}
40+
41+
/**
42+
* @return string Lowercase a-z and underscore only identifier
43+
* @since 11.0.0
44+
*/
45+
public function getIdentifier(): string {
46+
return 'group_settings';
47+
}
48+
49+
/**
50+
* @return string A translated string
51+
* @since 11.0.0
52+
*/
53+
public function getName(): string {
54+
return $this->l->t('Your <strong>group memberships</strong> were modified');
55+
}
56+
57+
/**
58+
* @return int whether the filter should be rather on the top or bottom of
59+
* the admin section. The filters are arranged in ascending order of the
60+
* priority values. It is required to return a value between 0 and 100.
61+
* @since 11.0.0
62+
*/
63+
public function getPriority(): int {
64+
return 0;
65+
}
66+
67+
/**
68+
* @return bool True when the option can be changed for the stream
69+
* @since 11.0.0
70+
*/
71+
public function canChangeStream(): bool {
72+
return false;
73+
}
74+
75+
/**
76+
* @return bool True when the option can be changed for the stream
77+
* @since 11.0.0
78+
*/
79+
public function isDefaultEnabledStream(): bool {
80+
return true;
81+
}
82+
83+
/**
84+
* @return bool True when the option can be changed for the mail
85+
* @since 11.0.0
86+
*/
87+
public function canChangeMail(): bool {
88+
return false;
89+
}
90+
91+
/**
92+
* @return bool True when the option can be changed for the stream
93+
* @since 11.0.0
94+
*/
95+
public function isDefaultEnabledMail(): bool {
96+
return true;
97+
}
98+
}

settings/Application.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
use OC\Authentication\Token\IProvider;
3434
use OC\Authentication\Token\IToken;
3535
use OC\Server;
36+
use OC\Settings\Activity\GroupProvider;
37+
use OC\Settings\Activity\GroupSetting;
3638
use OC\Settings\Activity\Provider;
3739
use OC\Settings\Activity\SecurityFilter;
3840
use OC\Settings\Activity\SecurityProvider;
@@ -44,7 +46,9 @@
4446
use OCP\AppFramework\App;
4547
use OCP\Defaults;
4648
use OCP\IContainer;
49+
use OCP\IGroup;
4750
use OCP\ILogger;
51+
use OCP\IUser;
4852
use OCP\Settings\IManager;
4953
use OCP\Util;
5054
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -149,13 +153,32 @@ public function register() {
149153
$activityManager->registerFilter(SecurityFilter::class); // FIXME move to info.xml
150154
$activityManager->registerSetting(SecuritySetting::class); // FIXME move to info.xml
151155
$activityManager->registerProvider(SecurityProvider::class); // FIXME move to info.xml
156+
$activityManager->registerSetting(GroupSetting::class); // FIXME move to info.xml
157+
$activityManager->registerProvider(GroupProvider::class); // FIXME move to info.xml
152158

153159
Util::connectHook('OC_User', 'post_setPassword', $this, 'onChangePassword');
154160
Util::connectHook('OC_User', 'changeUser', $this, 'onChangeInfo');
155161

162+
$groupManager = $this->getContainer()->getServer()->getGroupManager();
163+
$groupManager->listen('\OC\Group', 'postRemoveUser', [$this, 'removeUserFromGroup']);
164+
$groupManager->listen('\OC\Group', 'postAddUser', [$this, 'addUserToGroup']);
165+
156166
Util::connectHook('\OCP\Config', 'js', $this, 'extendJsConfig');
157167
}
158168

169+
public function addUserToGroup(IGroup $group, IUser $user): void {
170+
/** @var Hooks $hooks */
171+
$hooks = $this->getContainer()->query(Hooks::class);
172+
$hooks->addUserToGroup($group, $user);
173+
174+
}
175+
176+
public function removeUserFromGroup(IGroup $group, IUser $user): void {
177+
/** @var Hooks $hooks */
178+
$hooks = $this->getContainer()->query(Hooks::class);
179+
$hooks->removeUserFromGroup($group, $user);
180+
}
181+
159182
/**
160183
* @param array $parameters
161184
* @throws \InvalidArgumentException

0 commit comments

Comments
 (0)