Completed
Push — master ( ecba44...9bc77f )
by Lukas
62:05 queued 50:00
created
settings/BackgroundJobs/VerifyUserData.php 1 patch
Indentation   +249 added lines, -249 removed lines patch added patch discarded remove patch
@@ -35,254 +35,254 @@
 block discarded – undo
35 35
 
36 36
 class VerifyUserData extends Job {
37 37
 
38
-	/** @var  bool */
39
-	private $retainJob = true;
40
-
41
-	/** @var int max number of attempts to send the request */
42
-	private $maxTry = 24;
43
-
44
-	/** @var int how much time should be between two tries (1 hour) */
45
-	private $interval = 3600;
46
-
47
-	/** @var AccountManager */
48
-	private $accountManager;
49
-
50
-	/** @var IUserManager */
51
-	private $userManager;
52
-
53
-	/** @var IClientService */
54
-	private $httpClientService;
55
-
56
-	/** @var ILogger */
57
-	private $logger;
58
-
59
-	/** @var string */
60
-	private $lookupServerUrl;
61
-
62
-	/**
63
-	 * VerifyUserData constructor.
64
-	 *
65
-	 * @param AccountManager $accountManager
66
-	 * @param IUserManager $userManager
67
-	 * @param IClientService $clientService
68
-	 * @param ILogger $logger
69
-	 * @param IConfig $config
70
-	 */
71
-	public function __construct(AccountManager $accountManager,
72
-								IUserManager $userManager,
73
-								IClientService $clientService,
74
-								ILogger $logger,
75
-								IConfig $config
76
-	) {
77
-		$this->accountManager = $accountManager;
78
-		$this->userManager = $userManager;
79
-		$this->httpClientService = $clientService;
80
-		$this->logger = $logger;
81
-
82
-		$lookupServerUrl = $config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com');
83
-		$this->lookupServerUrl = rtrim($lookupServerUrl, '/');
84
-	}
85
-
86
-	/**
87
-	 * run the job, then remove it from the jobList
88
-	 *
89
-	 * @param JobList $jobList
90
-	 * @param ILogger $logger
91
-	 */
92
-	public function execute($jobList, ILogger $logger = null) {
93
-
94
-		if ($this->shouldRun($this->argument)) {
95
-			parent::execute($jobList, $logger);
96
-			$jobList->remove($this, $this->argument);
97
-			if ($this->retainJob) {
98
-				$this->reAddJob($jobList, $this->argument);
99
-			} else {
100
-				$this->resetVerificationState();
101
-			}
102
-		}
103
-
104
-	}
105
-
106
-	protected function run($argument) {
107
-
108
-		$try = (int)$argument['try'] + 1;
109
-
110
-		switch($argument['type']) {
111
-			case AccountManager::PROPERTY_WEBSITE:
112
-				$result = $this->verifyWebsite($argument);
113
-				break;
114
-			case AccountManager::PROPERTY_TWITTER:
115
-			case AccountManager::PROPERTY_EMAIL:
116
-				$result = $this->verifyViaLookupServer($argument, $argument['type']);
117
-				break;
118
-			default:
119
-				// no valid type given, no need to retry
120
-				$this->logger->error($argument['type'] . ' is no valid type for user account data.');
121
-				$result = true;
122
-		}
123
-
124
-		if ($result === true || $try > $this->maxTry) {
125
-			$this->retainJob = false;
126
-		}
127
-	}
128
-
129
-	/**
130
-	 * verify web page
131
-	 *
132
-	 * @param array $argument
133
-	 * @return bool true if we could check the verification code, otherwise false
134
-	 */
135
-	protected function verifyWebsite(array $argument) {
136
-
137
-		$result = false;
138
-
139
-		$url = rtrim($argument['data'], '/') . '/.well-known/' . 'CloudIdVerificationCode.txt';
140
-
141
-		$client = $this->httpClientService->newClient();
142
-		try {
143
-			$response = $client->get($url);
144
-		} catch (\Exception $e) {
145
-			return false;
146
-		}
147
-
148
-		if ($response->getStatusCode() === Http::STATUS_OK) {
149
-			$result = true;
150
-			$publishedCode = $response->getBody();
151
-			// remove new lines and spaces
152
-			$publishedCodeSanitized = trim(preg_replace('/\s\s+/', ' ', $publishedCode));
153
-			$user = $this->userManager->get($argument['uid']);
154
-			// we don't check a valid user -> give up
155
-			if ($user === null) {
156
-				$this->logger->error($argument['uid'] . ' doesn\'t exist, can\'t verify user data.');
157
-				return $result;
158
-			}
159
-			$userData = $this->accountManager->getUser($user);
160
-
161
-			if ($publishedCodeSanitized === $argument['verificationCode']) {
162
-				$userData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFIED;
163
-			} else {
164
-				$userData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::NOT_VERIFIED;
165
-			}
166
-
167
-			$this->accountManager->updateUser($user, $userData);
168
-		}
169
-
170
-		return $result;
171
-	}
172
-
173
-	/**
174
-	 * verify email address
175
-	 *
176
-	 * @param array $argument
177
-	 * @param string $dataType
178
-	 * @return bool true if we could check the verification code, otherwise false
179
-	 */
180
-	protected function verifyViaLookupServer(array $argument, $dataType) {
181
-
182
-		$user = $this->userManager->get($argument['uid']);
183
-
184
-		// we don't check a valid user -> give up
185
-		if ($user === null) {
186
-			$this->logger->error($argument['uid'] . ' doesn\'t exist, can\'t verify user data.');
187
-			return true;
188
-		}
189
-
190
-		$localUserData = $this->accountManager->getUser($user);
191
-		$cloudId = $user->getCloudId();
192
-
193
-		// ask lookup-server for user data
194
-		$lookupServerData = $this->queryLookupServer($cloudId);
195
-
196
-		// for some reasons we couldn't read any data from the lookup server, try again later
197
-		if (empty($lookupServerData)) {
198
-			return false;
199
-		}
200
-
201
-		// lookup server has verification data for wrong user data (e.g. email address), try again later
202
-		if ($lookupServerData[$dataType]['value'] !== $argument['data']) {
203
-			return false;
204
-		}
205
-
206
-		// lookup server hasn't verified the email address so far, try again later
207
-		if ($lookupServerData[$dataType]['verified'] === AccountManager::NOT_VERIFIED) {
208
-			return false;
209
-		}
210
-
211
-		$localUserData[$dataType]['verified'] = AccountManager::VERIFIED;
212
-		$this->accountManager->updateUser($user, $localUserData);
213
-
214
-		return true;
215
-	}
216
-
217
-	/**
218
-	 * @param string $cloudId
219
-	 * @return array
220
-	 */
221
-	protected function queryLookupServer($cloudId) {
222
-		try {
223
-			$client = $this->httpClientService->newClient();
224
-			$response = $client->get(
225
-				$this->lookupServerUrl . '/users?search=' . urlencode($cloudId) . '&exactCloudId=1',
226
-				[
227
-					'timeout' => 10,
228
-					'connect_timeout' => 3,
229
-				]
230
-			);
231
-
232
-			$body = json_decode($response->getBody(), true);
233
-
234
-			if ($body['federationId'] === $cloudId) {
235
-				return $body;
236
-			}
237
-
238
-		} catch (\Exception $e) {
239
-			// do nothing, we will just re-try later
240
-		}
241
-
242
-		return [];
243
-	}
244
-
245
-	/**
246
-	 * re-add background job with new arguments
247
-	 *
248
-	 * @param IJobList $jobList
249
-	 * @param array $argument
250
-	 */
251
-	protected function reAddJob(IJobList $jobList, array $argument) {
252
-		$jobList->add('OC\Settings\BackgroundJobs\VerifyUserData',
253
-			[
254
-				'verificationCode' => $argument['verificationCode'],
255
-				'data' => $argument['data'],
256
-				'type' => $argument['type'],
257
-				'uid' => $argument['uid'],
258
-				'try' => (int)$argument['try'] + 1,
259
-				'lastRun' => time()
260
-			]
261
-		);
262
-	}
263
-
264
-	/**
265
-	 * test if it is time for the next run
266
-	 *
267
-	 * @param array $argument
268
-	 * @return bool
269
-	 */
270
-	protected function shouldRun(array $argument) {
271
-		$lastRun = (int)$argument['lastRun'];
272
-		return ((time() - $lastRun) > $this->interval);
273
-	}
274
-
275
-
276
-	/**
277
-	 * reset verification state after max tries are reached
278
-	 */
279
-	protected function resetVerificationState() {
280
-		$user = $this->userManager->get($this->argument['uid']);
281
-		if ($user !== null) {
282
-			$accountData = $this->accountManager->getUser($user);
283
-			$accountData[$this->argument['type']]['verified'] = AccountManager::NOT_VERIFIED;
284
-			$this->accountManager->updateUser($user, $accountData);
285
-		}
286
-	}
38
+    /** @var  bool */
39
+    private $retainJob = true;
40
+
41
+    /** @var int max number of attempts to send the request */
42
+    private $maxTry = 24;
43
+
44
+    /** @var int how much time should be between two tries (1 hour) */
45
+    private $interval = 3600;
46
+
47
+    /** @var AccountManager */
48
+    private $accountManager;
49
+
50
+    /** @var IUserManager */
51
+    private $userManager;
52
+
53
+    /** @var IClientService */
54
+    private $httpClientService;
55
+
56
+    /** @var ILogger */
57
+    private $logger;
58
+
59
+    /** @var string */
60
+    private $lookupServerUrl;
61
+
62
+    /**
63
+     * VerifyUserData constructor.
64
+     *
65
+     * @param AccountManager $accountManager
66
+     * @param IUserManager $userManager
67
+     * @param IClientService $clientService
68
+     * @param ILogger $logger
69
+     * @param IConfig $config
70
+     */
71
+    public function __construct(AccountManager $accountManager,
72
+                                IUserManager $userManager,
73
+                                IClientService $clientService,
74
+                                ILogger $logger,
75
+                                IConfig $config
76
+    ) {
77
+        $this->accountManager = $accountManager;
78
+        $this->userManager = $userManager;
79
+        $this->httpClientService = $clientService;
80
+        $this->logger = $logger;
81
+
82
+        $lookupServerUrl = $config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com');
83
+        $this->lookupServerUrl = rtrim($lookupServerUrl, '/');
84
+    }
85
+
86
+    /**
87
+     * run the job, then remove it from the jobList
88
+     *
89
+     * @param JobList $jobList
90
+     * @param ILogger $logger
91
+     */
92
+    public function execute($jobList, ILogger $logger = null) {
93
+
94
+        if ($this->shouldRun($this->argument)) {
95
+            parent::execute($jobList, $logger);
96
+            $jobList->remove($this, $this->argument);
97
+            if ($this->retainJob) {
98
+                $this->reAddJob($jobList, $this->argument);
99
+            } else {
100
+                $this->resetVerificationState();
101
+            }
102
+        }
103
+
104
+    }
105
+
106
+    protected function run($argument) {
107
+
108
+        $try = (int)$argument['try'] + 1;
109
+
110
+        switch($argument['type']) {
111
+            case AccountManager::PROPERTY_WEBSITE:
112
+                $result = $this->verifyWebsite($argument);
113
+                break;
114
+            case AccountManager::PROPERTY_TWITTER:
115
+            case AccountManager::PROPERTY_EMAIL:
116
+                $result = $this->verifyViaLookupServer($argument, $argument['type']);
117
+                break;
118
+            default:
119
+                // no valid type given, no need to retry
120
+                $this->logger->error($argument['type'] . ' is no valid type for user account data.');
121
+                $result = true;
122
+        }
123
+
124
+        if ($result === true || $try > $this->maxTry) {
125
+            $this->retainJob = false;
126
+        }
127
+    }
128
+
129
+    /**
130
+     * verify web page
131
+     *
132
+     * @param array $argument
133
+     * @return bool true if we could check the verification code, otherwise false
134
+     */
135
+    protected function verifyWebsite(array $argument) {
136
+
137
+        $result = false;
138
+
139
+        $url = rtrim($argument['data'], '/') . '/.well-known/' . 'CloudIdVerificationCode.txt';
140
+
141
+        $client = $this->httpClientService->newClient();
142
+        try {
143
+            $response = $client->get($url);
144
+        } catch (\Exception $e) {
145
+            return false;
146
+        }
147
+
148
+        if ($response->getStatusCode() === Http::STATUS_OK) {
149
+            $result = true;
150
+            $publishedCode = $response->getBody();
151
+            // remove new lines and spaces
152
+            $publishedCodeSanitized = trim(preg_replace('/\s\s+/', ' ', $publishedCode));
153
+            $user = $this->userManager->get($argument['uid']);
154
+            // we don't check a valid user -> give up
155
+            if ($user === null) {
156
+                $this->logger->error($argument['uid'] . ' doesn\'t exist, can\'t verify user data.');
157
+                return $result;
158
+            }
159
+            $userData = $this->accountManager->getUser($user);
160
+
161
+            if ($publishedCodeSanitized === $argument['verificationCode']) {
162
+                $userData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFIED;
163
+            } else {
164
+                $userData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::NOT_VERIFIED;
165
+            }
166
+
167
+            $this->accountManager->updateUser($user, $userData);
168
+        }
169
+
170
+        return $result;
171
+    }
172
+
173
+    /**
174
+     * verify email address
175
+     *
176
+     * @param array $argument
177
+     * @param string $dataType
178
+     * @return bool true if we could check the verification code, otherwise false
179
+     */
180
+    protected function verifyViaLookupServer(array $argument, $dataType) {
181
+
182
+        $user = $this->userManager->get($argument['uid']);
183
+
184
+        // we don't check a valid user -> give up
185
+        if ($user === null) {
186
+            $this->logger->error($argument['uid'] . ' doesn\'t exist, can\'t verify user data.');
187
+            return true;
188
+        }
189
+
190
+        $localUserData = $this->accountManager->getUser($user);
191
+        $cloudId = $user->getCloudId();
192
+
193
+        // ask lookup-server for user data
194
+        $lookupServerData = $this->queryLookupServer($cloudId);
195
+
196
+        // for some reasons we couldn't read any data from the lookup server, try again later
197
+        if (empty($lookupServerData)) {
198
+            return false;
199
+        }
200
+
201
+        // lookup server has verification data for wrong user data (e.g. email address), try again later
202
+        if ($lookupServerData[$dataType]['value'] !== $argument['data']) {
203
+            return false;
204
+        }
205
+
206
+        // lookup server hasn't verified the email address so far, try again later
207
+        if ($lookupServerData[$dataType]['verified'] === AccountManager::NOT_VERIFIED) {
208
+            return false;
209
+        }
210
+
211
+        $localUserData[$dataType]['verified'] = AccountManager::VERIFIED;
212
+        $this->accountManager->updateUser($user, $localUserData);
213
+
214
+        return true;
215
+    }
216
+
217
+    /**
218
+     * @param string $cloudId
219
+     * @return array
220
+     */
221
+    protected function queryLookupServer($cloudId) {
222
+        try {
223
+            $client = $this->httpClientService->newClient();
224
+            $response = $client->get(
225
+                $this->lookupServerUrl . '/users?search=' . urlencode($cloudId) . '&exactCloudId=1',
226
+                [
227
+                    'timeout' => 10,
228
+                    'connect_timeout' => 3,
229
+                ]
230
+            );
231
+
232
+            $body = json_decode($response->getBody(), true);
233
+
234
+            if ($body['federationId'] === $cloudId) {
235
+                return $body;
236
+            }
237
+
238
+        } catch (\Exception $e) {
239
+            // do nothing, we will just re-try later
240
+        }
241
+
242
+        return [];
243
+    }
244
+
245
+    /**
246
+     * re-add background job with new arguments
247
+     *
248
+     * @param IJobList $jobList
249
+     * @param array $argument
250
+     */
251
+    protected function reAddJob(IJobList $jobList, array $argument) {
252
+        $jobList->add('OC\Settings\BackgroundJobs\VerifyUserData',
253
+            [
254
+                'verificationCode' => $argument['verificationCode'],
255
+                'data' => $argument['data'],
256
+                'type' => $argument['type'],
257
+                'uid' => $argument['uid'],
258
+                'try' => (int)$argument['try'] + 1,
259
+                'lastRun' => time()
260
+            ]
261
+        );
262
+    }
263
+
264
+    /**
265
+     * test if it is time for the next run
266
+     *
267
+     * @param array $argument
268
+     * @return bool
269
+     */
270
+    protected function shouldRun(array $argument) {
271
+        $lastRun = (int)$argument['lastRun'];
272
+        return ((time() - $lastRun) > $this->interval);
273
+    }
274
+
275
+
276
+    /**
277
+     * reset verification state after max tries are reached
278
+     */
279
+    protected function resetVerificationState() {
280
+        $user = $this->userManager->get($this->argument['uid']);
281
+        if ($user !== null) {
282
+            $accountData = $this->accountManager->getUser($user);
283
+            $accountData[$this->argument['type']]['verified'] = AccountManager::NOT_VERIFIED;
284
+            $this->accountManager->updateUser($user, $accountData);
285
+        }
286
+    }
287 287
 
288 288
 }
Please login to merge, or discard this patch.