Skip to content

Commit 940a313

Browse files
authored
Merge pull request #15143 from nextcloud/bugfix/noid/lookup-server-connector-background-jobs-problem
Fix lookup server connector background jobs problem
2 parents a65c004 + 30051e7 commit 940a313

File tree

6 files changed

+216
-178
lines changed

6 files changed

+216
-178
lines changed

apps/lookup_server_connector/appinfo/app.php

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,5 @@
1919
*
2020
*/
2121

22-
$dispatcher = \OC::$server->getEventDispatcher();
23-
24-
$dispatcher->addListener('OC\AccountManager::userUpdated', function(\Symfony\Component\EventDispatcher\GenericEvent $event) {
25-
/** @var \OCP\IUser $user */
26-
$user = $event->getSubject();
27-
28-
/** @var \OCA\LookupServerConnector\UpdateLookupServer $updateLookupServer */
29-
$updateLookupServer = \OC::$server->query(\OCA\LookupServerConnector\UpdateLookupServer::class);
30-
$updateLookupServer->userUpdated($user);
31-
});
22+
$app = new \OCA\LookupServerConnector\AppInfo\Application();
23+
$app->register();

apps/lookup_server_connector/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
$baseDir = $vendorDir;
77

88
return array(
9+
'OCA\\LookupServerConnector\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
910
'OCA\\LookupServerConnector\\BackgroundJobs\\RetryJob' => $baseDir . '/../lib/BackgroundJobs/RetryJob.php',
1011
'OCA\\LookupServerConnector\\UpdateLookupServer' => $baseDir . '/../lib/UpdateLookupServer.php',
1112
);

apps/lookup_server_connector/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class ComposerStaticInitLookupServerConnector
2121
);
2222

2323
public static $classMap = array (
24+
'OCA\\LookupServerConnector\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
2425
'OCA\\LookupServerConnector\\BackgroundJobs\\RetryJob' => __DIR__ . '/..' . '/../lib/BackgroundJobs/RetryJob.php',
2526
'OCA\\LookupServerConnector\\UpdateLookupServer' => __DIR__ . '/..' . '/../lib/UpdateLookupServer.php',
2627
);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
declare(strict_types=1);
3+
/**
4+
* @copyright Copyright (c) 2019 Joas Schilling <[email protected]>
5+
*
6+
* @license GNU AGPL version 3 or any later version
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License as
10+
* published by the Free Software Foundation, either version 3 of the
11+
* License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU Affero General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Affero General Public License
19+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
namespace OCA\LookupServerConnector\AppInfo;
23+
24+
use OCA\LookupServerConnector\UpdateLookupServer;
25+
use OCP\AppFramework\App;
26+
use OCP\IUser;
27+
use Symfony\Component\EventDispatcher\GenericEvent;
28+
29+
class Application extends App {
30+
public function __construct () {
31+
parent::__construct('lookup_server_connector');
32+
}
33+
34+
/**
35+
* Register the different app parts
36+
*/
37+
public function register(): void {
38+
$this->registerHooksAndEvents();
39+
}
40+
41+
/**
42+
* Register the hooks and events
43+
*/
44+
public function registerHooksAndEvents(): void {
45+
$dispatcher = $this->getContainer()->getServer()->getEventDispatcher();
46+
$dispatcher->addListener('OC\AccountManager::userUpdated', static function(GenericEvent $event) {
47+
/** @var IUser $user */
48+
$user = $event->getSubject();
49+
50+
/** @var UpdateLookupServer $updateLookupServer */
51+
$updateLookupServer = \OC::$server->query(UpdateLookupServer::class);
52+
$updateLookupServer->userUpdated($user);
53+
});
54+
55+
}
56+
}
Lines changed: 136 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
2+
declare(strict_types=1);
23
/**
34
* @copyright Copyright (c) 2016 Bjoern Schiessle <[email protected]>
5+
* @copyright Copyright (c) 2019 Joas Schilling <[email protected]>
46
*
57
* @license GNU AGPL version 3 or any later version
68
*
@@ -22,40 +24,55 @@
2224
namespace OCA\LookupServerConnector\BackgroundJobs;
2325

2426

25-
use OC\BackgroundJob\Job;
26-
use OC\BackgroundJob\JobList;
27+
use OC\Security\IdentityProof\Signer;
28+
use OCP\Accounts\IAccountManager;
29+
use OCP\AppFramework\Utility\ITimeFactory;
30+
use OCP\BackgroundJob\Job;
2731
use OCP\BackgroundJob\IJobList;
2832
use OCP\Http\Client\IClientService;
2933
use OCP\IConfig;
3034
use OCP\ILogger;
35+
use OCP\IUser;
36+
use OCP\IUserManager;
3137

3238
class RetryJob extends Job {
3339
/** @var IClientService */
3440
private $clientService;
35-
/** @var IJobList */
36-
private $jobList;
3741
/** @var string */
3842
private $lookupServer;
39-
/** @var int how much time should be between two, will be increased for each retry */
40-
private $interval = 100;
4143
/** @var IConfig */
4244
private $config;
45+
/** @var IUserManager */
46+
private $userManager;
47+
/** @var IAccountManager */
48+
private $accountManager;
49+
/** @var Signer */
50+
private $signer;
51+
/** @var int */
52+
protected $retries = 0;
53+
/** @var bool */
54+
protected $retainJob = false;
4355

4456
/**
57+
* @param ITimeFactory $time
4558
* @param IClientService $clientService
46-
* @param IJobList $jobList
4759
* @param IConfig $config
60+
* @param IUserManager $userManager
61+
* @param IAccountManager $accountManager
62+
* @param Signer $signer
4863
*/
49-
public function __construct(IClientService $clientService,
50-
IJobList $jobList,
51-
IConfig $config) {
64+
public function __construct(ITimeFactory $time,
65+
IClientService $clientService,
66+
IConfig $config,
67+
IUserManager $userManager,
68+
IAccountManager $accountManager,
69+
Signer $signer) {
70+
parent::__construct($time);
5271
$this->clientService = $clientService;
53-
$this->jobList = $jobList;
5472
$this->config = $config;
55-
56-
if ($config->getSystemValue('has_internet_connection', true) === false) {
57-
return;
58-
}
73+
$this->userManager = $userManager;
74+
$this->accountManager = $accountManager;
75+
$this->signer = $signer;
5976

6077
$this->lookupServer = $config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com');
6178
if (!empty($this->lookupServer)) {
@@ -67,71 +84,129 @@ public function __construct(IClientService $clientService,
6784
/**
6885
* run the job, then remove it from the jobList
6986
*
70-
* @param JobList $jobList
87+
* @param IJobList $jobList
7188
* @param ILogger|null $logger
7289
*/
73-
public function execute($jobList, ILogger $logger = null) {
74-
if ($this->shouldRun($this->argument)) {
75-
parent::execute($jobList, $logger);
90+
public function execute($jobList, ILogger $logger = null): void {
91+
if (!isset($this->argument['userId'])) {
92+
// Old background job without user id, just drop it.
7693
$jobList->remove($this, $this->argument);
94+
return;
95+
}
96+
97+
$this->retries = (int) $this->config->getUserValue($this->argument['userId'], 'lookup_server_connector', 'update_retries', 0);
98+
99+
if ($this->shouldRemoveBackgroundJob()) {
100+
$jobList->remove($this, $this->argument);
101+
return;
102+
}
103+
104+
if ($this->shouldRun()) {
105+
parent::execute($jobList, $logger);
106+
if (!$this->retainJob) {
107+
$jobList->remove($this, $this->argument);
108+
}
77109
}
78110
}
79111

80-
protected function run($argument) {
81-
if ($this->killBackgroundJob((int)$argument['retryNo'])) {
112+
/**
113+
* Check if we should kill the background job:
114+
*
115+
* - internet connection is disabled
116+
* - no valid lookup server URL given
117+
* - lookup server was disabled by the admin
118+
* - max retries are reached (set to 5)
119+
*
120+
* @return bool
121+
*/
122+
protected function shouldRemoveBackgroundJob(): bool {
123+
return $this->config->getSystemValueBool('has_internet_connection', true) === false ||
124+
$this->config->getSystemValueString('lookup_server', 'https://lookup.nextcloud.com') === '' ||
125+
$this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes') !== 'yes' ||
126+
$this->retries >= 5;
127+
}
128+
129+
protected function shouldRun(): bool {
130+
$delay = 100 * 6 ** $this->retries;
131+
return ($this->time->getTime() - $this->lastRun) > $delay;
132+
}
133+
134+
protected function run($argument): void {
135+
$user = $this->userManager->get($this->argument['userId']);
136+
if (!$user instanceof IUser) {
137+
// User does not exist anymore
82138
return;
83139
}
84140

141+
$data = $this->getUserAccountData($user);
142+
$signedData = $this->signer->sign('lookupserver', $data, $user);
85143
$client = $this->clientService->newClient();
86144

87145
try {
88-
$client->post($this->lookupServer,
89-
[
90-
'body' => json_encode($argument['dataArray']),
91-
'timeout' => 10,
92-
'connect_timeout' => 3,
93-
]
146+
if (count($data) === 1) {
147+
// No public data, just the federation Id
148+
$client->delete($this->lookupServer,
149+
[
150+
'body' => json_encode($signedData),
151+
'timeout' => 10,
152+
'connect_timeout' => 3,
153+
]
154+
);
155+
} else {
156+
$client->post($this->lookupServer,
157+
[
158+
'body' => json_encode($signedData),
159+
'timeout' => 10,
160+
'connect_timeout' => 3,
161+
]
162+
);
163+
}
164+
165+
// Reset retry counter
166+
$this->config->deleteUserValue(
167+
$user->getUID(),
168+
'lookup_server_connector',
169+
'update_retries'
94170
);
171+
95172
} catch (\Exception $e) {
96-
$this->jobList->add(RetryJob::class,
97-
[
98-
'dataArray' => $argument['dataArray'],
99-
'retryNo' => $argument['retryNo'] + 1,
100-
'lastRun' => time(),
101-
]
173+
// An error occurred, retry later
174+
$this->retainJob = true;
175+
$this->config->setUserValue(
176+
$user->getUID(),
177+
'lookup_server_connector',
178+
'update_retries',
179+
$this->retries + 1
102180
);
103-
104181
}
105182
}
106183

107-
/**
108-
* test if it is time for the next run
109-
*
110-
* @param array $argument
111-
* @return bool
112-
*/
113-
protected function shouldRun($argument) {
114-
$retryNo = (int)$argument['retryNo'];
115-
$delay = $this->interval * 6 ** $retryNo;
116-
return !isset($argument['lastRun']) || ((time() - $argument['lastRun']) > $delay);
117-
}
184+
protected function getUserAccountData(IUser $user): array {
185+
$account = $this->accountManager->getAccount($user);
118186

119-
/**
120-
* check if we should kill the background job
121-
*
122-
* The lookup server should no longer be contacted if:
123-
*
124-
* - max retries are reached (set to 5)
125-
* - lookup server was disabled by the admin
126-
* - no valid lookup server URL given
127-
*
128-
* @param int $retryCount
129-
* @return bool
130-
*/
131-
protected function killBackgroundJob($retryCount) {
132-
$maxTriesReached = $retryCount >= 5;
133-
$lookupServerDisabled = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes') !== 'yes';
187+
$publicData = [];
188+
foreach ($account->getProperties() as $property) {
189+
if ($property->getScope() === IAccountManager::VISIBILITY_PUBLIC) {
190+
$publicData[$property->getName()] = $property->getValue();
191+
}
192+
}
193+
194+
$data = ['federationId' => $user->getCloudId()];
195+
if (!empty($publicData)) {
196+
$data['name'] = $publicData[IAccountManager::PROPERTY_DISPLAYNAME]['value'] ?? '';
197+
$data['email'] = $publicData[IAccountManager::PROPERTY_EMAIL]['value'] ?? '';
198+
$data['address'] = $publicData[IAccountManager::PROPERTY_ADDRESS]['value'] ?? '';
199+
$data['website'] = $publicData[IAccountManager::PROPERTY_WEBSITE]['value'] ?? '';
200+
$data['twitter'] = $publicData[IAccountManager::PROPERTY_TWITTER]['value'] ?? '';
201+
$data['phone'] = $publicData[IAccountManager::PROPERTY_PHONE]['value'] ?? '';
202+
$data['twitter_signature'] = $publicData[IAccountManager::PROPERTY_TWITTER]['signature'] ?? '';
203+
$data['website_signature'] = $publicData[IAccountManager::PROPERTY_WEBSITE]['signature'] ?? '';
204+
$data['verificationStatus'] = [
205+
IAccountManager::PROPERTY_WEBSITE => $publicData[IAccountManager::PROPERTY_WEBSITE]['verified'] ?? '',
206+
IAccountManager::PROPERTY_TWITTER => $publicData[IAccountManager::PROPERTY_TWITTER]['verified'] ?? '',
207+
];
208+
}
134209

135-
return $maxTriesReached || $lookupServerDisabled || empty($this->lookupServer);
210+
return $data;
136211
}
137212
}

0 commit comments

Comments
 (0)