Skip to content

Commit d782dbd

Browse files
authored
Merge pull request #140 from julien-nc/fix/139/autoexport-deleted-users
Fix autoexport when some sessions are owned by deleted users
2 parents ba15f63 + 447444e commit d782dbd

6 files changed

Lines changed: 72 additions & 9 deletions

File tree

lib/AppInfo/Application.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212

1313
namespace OCA\PhoneTrack\AppInfo;
1414

15+
use OCA\PhoneTrack\Listener\UserDeletedListener;
1516
use OCA\PhoneTrack\Notification\Notifier;
1617
use OCP\AppFramework\App;
1718
use OCP\AppFramework\Bootstrap\IBootContext;
1819
use OCP\AppFramework\Bootstrap\IBootstrap;
1920

2021
use OCP\AppFramework\Bootstrap\IRegistrationContext;
22+
use OCP\User\Events\UserDeletedEvent;
2123

2224
class Application extends App implements IBootstrap {
2325

@@ -35,6 +37,7 @@ public function __construct(array $urlParams = []) {
3537

3638
public function register(IRegistrationContext $context): void {
3739
$context->registerNotifierService(Notifier::class);
40+
$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
3841
}
3942

4043
public function boot(IBootContext $context): void {

lib/Command/AutoExport.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ protected function configure() {
3131
}
3232

3333
protected function execute(InputInterface $input, OutputInterface $output) {
34-
$this->sessionService->cronAutoExport();
34+
foreach ($this->sessionService->cronAutoExport() as $message) {
35+
$output->writeln($message);
36+
}
3537
return 0;
3638
}
3739
}

lib/Cron/AutoExport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ public function __construct(
2626
}
2727

2828
protected function run($argument): void {
29-
$this->sessionService->cronAutoExport();
29+
iterator_to_array($this->sessionService->cronAutoExport());
3030
}
3131
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OCA\PhoneTrack\Listener;
6+
7+
use OCA\PhoneTrack\Service\SessionService;
8+
use OCP\EventDispatcher\Event;
9+
use OCP\EventDispatcher\IEventListener;
10+
use OCP\User\Events\UserDeletedEvent;
11+
12+
/**
13+
* @template-implements IEventListener<UserDeletedEvent>
14+
*/
15+
class UserDeletedListener implements IEventListener {
16+
public function __construct(
17+
private SessionService $sessionService,
18+
) {
19+
}
20+
21+
public function handle(Event $event): void {
22+
if (!($event instanceof UserDeletedEvent)) {
23+
return;
24+
}
25+
26+
// cleanup user data
27+
$this->sessionService->cleanupUser($event->getUser()->getUID());
28+
}
29+
}

lib/Service/SessionService.php

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ private function cronAutoPurge() {
141141
*
142142
* export sessions
143143
*/
144-
public function cronAutoExport() {
144+
public function cronAutoExport(): \Generator {
145145
$dtz = ini_get('date.timezone');
146146
if ($dtz === '') {
147147
$dtz = 'UTC';
@@ -223,10 +223,24 @@ public function cronAutoExport() {
223223
$phonetrackUserIds = $this->sessionMapper->getUserIds();
224224

225225
foreach ($phonetrackUserIds as $userId) {
226+
$userSessions = $this->sessionMapper->findByUser($userId);
227+
$candidateUserSessions = array_filter($userSessions, static function (Session $session) {
228+
return $session->getAutoexport() !== 'no';
229+
});
230+
$candidateUserSessions = array_values($candidateUserSessions);
231+
// if there is no session with autoexport enabled: skip this user
232+
if (count($candidateUserSessions) === 0) {
233+
continue;
234+
}
235+
236+
// if the user does not exist: skip this this user
237+
if (!$this->userManager->userExists($userId)) {
238+
continue;
239+
}
240+
226241
$userFolder = $this->root->getUserFolder($userId);
227-
$sessions = $this->sessionMapper->findByUser($userId);
228242

229-
foreach ($sessions as $session) {
243+
foreach ($candidateUserSessions as $session) {
230244
$dbname = $session->getName();
231245
$dbtoken = $session->getToken();
232246
$dbexportType = $session->getAutoexport();
@@ -248,14 +262,22 @@ public function cronAutoExport() {
248262
$rel_path = str_replace($userFolder->getPath(), '', $dir->getPath());
249263
$exportPath = $rel_path . '/' . $exportName;
250264
if (!$dir->nodeExists($exportName)) {
251-
$this->exportSession($dbname, $dbtoken, $exportPath, $userId, $filters);
265+
[$done, $warning] = $this->exportSession($dbname, $dbtoken, $exportPath, $userId, $filters);
266+
if ($warning === 1) {
267+
yield "Not exporting session $dbname of $userId in '$exportPath', no points";
268+
} else {
269+
yield "Exporting session $dbname of $userId in '$exportPath'";
270+
}
271+
} else {
272+
yield "Cannot export session $dbname of $userId in '$exportPath', file already exists";
252273
}
253274
}
254275
}
255276
}
256277
// we run the auto purge method AFTER the auto export
257278
// to avoid deleting data before it has been eventually exported
258279
$this->cronAutoPurge();
280+
return [];
259281
}
260282

261283
/**
@@ -298,7 +320,7 @@ public function exportDevice(Device $device, string $userId, string $target): vo
298320
$file->touch();
299321
}
300322

301-
public function exportSession(string $name, string $token, string $target, string $username = '', ?array $filters = null) {
323+
public function exportSession(string $name, string $token, string $target, string $username = '', ?array $filters = null): array {
302324
date_default_timezone_set('UTC');
303325
$done = false;
304326
$warning = 0;
@@ -1191,4 +1213,11 @@ public function deleteSession(Session $session): void {
11911213
}
11921214
$this->sessionMapper->deleteSession($session->getUser(), $session->getId());
11931215
}
1216+
1217+
public function cleanupUser(string $userId): void {
1218+
$sessions = $this->sessionMapper->findByUser($userId);
1219+
foreach ($sessions as $session) {
1220+
$this->deleteSession($session);
1221+
}
1222+
}
11941223
}

tests/php/controller/OldPageControllerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ public function testPage() {
755755
$pointListBeforePurge = $respSession[$token][$deviceid];
756756
$this->assertTrue(count($pointListBeforePurge) > 0);
757757

758-
$this->sessionService->cronAutoExport();
758+
iterator_to_array($this->sessionService->cronAutoExport());
759759

760760
// check number of points
761761
$sessions = [[$token, [$deviceid => 400], null]];
@@ -774,7 +774,7 @@ public function testPage() {
774774
$search[0]->delete();
775775
$resp = $this->pageController->setSessionAutoExport($token, 'weekly');
776776
// do it again to test when export dir already exists and test weekly
777-
$this->sessionService->cronAutoExport();
777+
iterator_to_array($this->sessionService->cronAutoExport());
778778
$search = $userFolder->get('/autoex')->search('.gpx');
779779
$this->assertEquals(count($search), 1);
780780

0 commit comments

Comments
 (0)