Skip to content

Commit 7f7d082

Browse files
committed
Add FirstLoginListener to accept shares upon first ldap user login
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
1 parent 130d3bd commit 7f7d082

2 files changed

Lines changed: 154 additions & 2 deletions

File tree

apps/user_ldap/lib/AppInfo/Application.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@
3131
use OCA\User_LDAP\Controller\RenewPasswordController;
3232
use OCA\User_LDAP\Events\GroupBackendRegistered;
3333
use OCA\User_LDAP\Events\UserBackendRegistered;
34-
use OCA\User_LDAP\Group_Proxy;
3534
use OCA\User_LDAP\GroupPluginManager;
35+
use OCA\User_LDAP\Group_Proxy;
3636
use OCA\User_LDAP\Handler\ExtStorageConfigHandler;
3737
use OCA\User_LDAP\Helper;
3838
use OCA\User_LDAP\ILDAPWrapper;
3939
use OCA\User_LDAP\LDAP;
4040
use OCA\User_LDAP\Notification\Notifier;
41-
use OCA\User_LDAP\User_Proxy;
4241
use OCA\User_LDAP\UserPluginManager;
42+
use OCA\User_LDAP\User_Proxy;
4343
use OCP\AppFramework\App;
4444
use OCP\AppFramework\Bootstrap\IBootContext;
4545
use OCP\AppFramework\Bootstrap\IBootstrap;
@@ -50,6 +50,7 @@
5050
use OCP\IL10N;
5151
use OCP\IServerContainer;
5252
use OCP\Notification\IManager as INotificationManager;
53+
use OCP\User\Events\PostLoginEvent;
5354
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
5455

5556
class Application extends App implements IBootstrap {
@@ -117,6 +118,7 @@ public function boot(IBootContext $context): void {
117118
});
118119

119120
$context->injectFn(Closure::fromCallable([$this, 'registerBackendDependents']));
121+
$context->injectFn(Closure::fromCallable([$this, 'registerFirstLoginListener']));
120122

121123
\OCP\Util::connectHook(
122124
'\OCA\Files_Sharing\API\Server2Server',
@@ -137,4 +139,14 @@ function () use ($appContainer) {
137139
}
138140
);
139141
}
142+
143+
private function registerFirstLoginListener(EventDispatcherInterface $dispatcher) {
144+
$dispatcher->addServiceListener(PostLoginEvent::class, FirstLoginListener::class);
145+
\OCP\Util::connectHook(
146+
'\OC\User',
147+
'assignedUserId',
148+
FirstLoginListener::class,
149+
'onAssignedId'
150+
);
151+
}
140152
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* @copyright Copyright (c) 2022, Côme Chilliet <come.chilliet@nextcloud.com>
7+
*
8+
* @author Côme Chilliet <come.chilliet@nextcloud.com>
9+
*
10+
* @license GNU AGPL version 3 or any later version
11+
*
12+
* This program is free software: you can redistribute it and/or modify
13+
* it under the terms of the GNU Affero General Public License as
14+
* published by the Free Software Foundation, either version 3 of the
15+
* License, or (at your option) any later version.
16+
*
17+
* This program is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU Affero General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU Affero General Public License
23+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
*
25+
*/
26+
namespace OCA\User_LDAP;
27+
28+
use OCP\EventDispatcher\Event;
29+
use OCP\EventDispatcher\IEventDispatcher;
30+
use OCP\EventDispatcher\IEventListener;
31+
use OCP\Group\Events\UserAddedEvent;
32+
use OCP\IDBConnection;
33+
use OCP\IGroupManager;
34+
use OCP\IUser;
35+
use OCP\IUserManager;
36+
use OCP\User\Events\PostLoginEvent;
37+
use Psr\Log\LoggerInterface;
38+
39+
class FirstLoginListener implements IEventListener {
40+
protected $somekindofstatefulhandler;
41+
42+
/** @var Group_Proxy */
43+
private $groupBackend;
44+
/** @var IEventDispatcher */
45+
private $dispatcher;
46+
/** @var IGroupManager */
47+
private $groupManager;
48+
/** @var IUserManager */
49+
private $userManager;
50+
/** @var LoggerInterface */
51+
private $logger;
52+
/** @var IDBConnection */
53+
private $dbc;
54+
55+
public function __construct(
56+
Group_Proxy $groupBackend,
57+
IEventDispatcher $dispatcher,
58+
IGroupManager $groupManager,
59+
IUserManager $userManager,
60+
LoggerInterface $logger,
61+
IDBConnection $dbc
62+
) {
63+
$this->groupBackend = $groupBackend;
64+
$this->dispatcher = $dispatcher;
65+
$this->groupManager = $groupManager;
66+
$this->userManager = $userManager;
67+
$this->logger = $logger;
68+
$this->dbc = $dbc;
69+
}
70+
71+
public function handle(Event $event): void {
72+
if ($event instanceof PostLoginEvent) {
73+
$this->onPostLogin($event->getUser());
74+
}
75+
}
76+
77+
public function onAssignedId(string $username): void {
78+
$this->somekindofstatefulhandler[$username]['id'] = 1;
79+
$this->triggerUpdateGroups($username);
80+
}
81+
82+
public function onPostLogin(string $username): void {
83+
$this->somekindofstatefulhandler[$username]['login'] = 1;
84+
$this->triggerUpdateGroups($username);
85+
}
86+
87+
private function triggerUpdateGroups(string $username): void {
88+
if (array_sum($this->somekindofstatefulhandler[$username] ?? []) >= 2) {
89+
$this->updateGroups($username);
90+
}
91+
}
92+
93+
private function updateGroups(string $username): void {
94+
$groups = $this->groupBackend->getUserGroups($username);
95+
96+
$qb = $this->dbc->getQueryBuilder();
97+
$qb->select(['owncloudusers'])
98+
->from('ldap_group_members')
99+
->where($qb->expr()->eq('owncloudname', $qb->createParameter('groupId')));
100+
101+
$qbUpdate = $this->dbc->getQueryBuilder();
102+
$qbUpdate->update('ldap_group_members')
103+
->set('owncloudusers', $qb->createParameter('members'))
104+
->where($qb->expr()->eq('owncloudname', $qb->createParameter('groupId')));
105+
106+
foreach ($groups as $group) {
107+
$qb->setParameters([
108+
'groupId' => $group
109+
]);
110+
111+
$qResult = $qb->execute();
112+
$data = $qResult->fetchOne();
113+
$qResult->closeCursor();
114+
115+
$knownUsers = unserialize($data['owncloudusers']);
116+
$hasChanged = false;
117+
118+
$groupObject = $this->groupManager->get($group);
119+
if (!in_array($username, $knownUsers)) {
120+
$userObject = $this->userManager->get($username);
121+
if ($userObject instanceof IUser) {
122+
$this->dispatcher->dispatchTyped(new UserAddedEvent($groupObject, $userObject));
123+
$this->logger->info(
124+
__CLASS__ . ' – {user} added to {group}',
125+
[
126+
'app' => 'user_ldap',
127+
'user' => $username,
128+
'group' => $group
129+
]
130+
);
131+
$qbUpdate->setParameters([
132+
'members' => serialize(array_merge($knownUsers, [$username])),
133+
'groupId' => $group
134+
]);
135+
$qbUpdate->execute();
136+
}
137+
}
138+
}
139+
}
140+
}

0 commit comments

Comments
 (0)