Passed
Push — master ( 8a7963...0b88b5 )
by Joas
17:38 queued 13s
created
apps/encryption/lib/Crypto/EncryptAll.php 1 patch
Indentation   +422 added lines, -422 removed lines patch added patch discarded remove patch
@@ -49,426 +49,426 @@
 block discarded – undo
49 49
 
50 50
 class EncryptAll {
51 51
 
52
-	/** @var Setup */
53
-	protected $userSetup;
54
-
55
-	/** @var IUserManager */
56
-	protected $userManager;
57
-
58
-	/** @var View */
59
-	protected $rootView;
60
-
61
-	/** @var KeyManager */
62
-	protected $keyManager;
63
-
64
-	/** @var Util */
65
-	protected $util;
66
-
67
-	/** @var array  */
68
-	protected $userPasswords;
69
-
70
-	/** @var  IConfig */
71
-	protected $config;
72
-
73
-	/** @var IMailer */
74
-	protected $mailer;
75
-
76
-	/** @var  IL10N */
77
-	protected $l;
78
-
79
-	/** @var  IFactory */
80
-	protected $l10nFactory;
81
-
82
-	/** @var  QuestionHelper */
83
-	protected $questionHelper;
84
-
85
-	/** @var  OutputInterface */
86
-	protected $output;
87
-
88
-	/** @var  InputInterface */
89
-	protected $input;
90
-
91
-	/** @var ISecureRandom */
92
-	protected $secureRandom;
93
-
94
-	public function __construct(
95
-		Setup $userSetup,
96
-		IUserManager $userManager,
97
-		View $rootView,
98
-		KeyManager $keyManager,
99
-		Util $util,
100
-		IConfig $config,
101
-		IMailer $mailer,
102
-		IL10N $l,
103
-		IFactory $l10nFactory,
104
-		QuestionHelper $questionHelper,
105
-		ISecureRandom $secureRandom
106
-	) {
107
-		$this->userSetup = $userSetup;
108
-		$this->userManager = $userManager;
109
-		$this->rootView = $rootView;
110
-		$this->keyManager = $keyManager;
111
-		$this->util = $util;
112
-		$this->config = $config;
113
-		$this->mailer = $mailer;
114
-		$this->l = $l;
115
-		$this->l10nFactory = $l10nFactory;
116
-		$this->questionHelper = $questionHelper;
117
-		$this->secureRandom = $secureRandom;
118
-		// store one time passwords for the users
119
-		$this->userPasswords = [];
120
-	}
121
-
122
-	/**
123
-	 * start to encrypt all files
124
-	 *
125
-	 * @param InputInterface $input
126
-	 * @param OutputInterface $output
127
-	 */
128
-	public function encryptAll(InputInterface $input, OutputInterface $output) {
129
-		$this->input = $input;
130
-		$this->output = $output;
131
-
132
-		$headline = 'Encrypt all files with the ' . Encryption::DISPLAY_NAME;
133
-		$this->output->writeln("\n");
134
-		$this->output->writeln($headline);
135
-		$this->output->writeln(str_pad('', strlen($headline), '='));
136
-		$this->output->writeln("\n");
137
-
138
-		if ($this->util->isMasterKeyEnabled()) {
139
-			$this->output->writeln('Use master key to encrypt all files.');
140
-			$this->keyManager->validateMasterKey();
141
-		} else {
142
-			//create private/public keys for each user and store the private key password
143
-			$this->output->writeln('Create key-pair for every user');
144
-			$this->output->writeln('------------------------------');
145
-			$this->output->writeln('');
146
-			$this->output->writeln('This module will encrypt all files in the users files folder initially.');
147
-			$this->output->writeln('Already existing versions and files in the trash bin will not be encrypted.');
148
-			$this->output->writeln('');
149
-			$this->createKeyPairs();
150
-		}
151
-
152
-
153
-		// output generated encryption key passwords
154
-		if ($this->util->isMasterKeyEnabled() === false) {
155
-			//send-out or display password list and write it to a file
156
-			$this->output->writeln("\n");
157
-			$this->output->writeln('Generated encryption key passwords');
158
-			$this->output->writeln('----------------------------------');
159
-			$this->output->writeln('');
160
-			$this->outputPasswords();
161
-		}
162
-
163
-		//setup users file system and encrypt all files one by one (take should encrypt setting of storage into account)
164
-		$this->output->writeln("\n");
165
-		$this->output->writeln('Start to encrypt users files');
166
-		$this->output->writeln('----------------------------');
167
-		$this->output->writeln('');
168
-		$this->encryptAllUsersFiles();
169
-		$this->output->writeln("\n");
170
-	}
171
-
172
-	/**
173
-	 * create key-pair for every user
174
-	 */
175
-	protected function createKeyPairs() {
176
-		$this->output->writeln("\n");
177
-		$progress = new ProgressBar($this->output);
178
-		$progress->setFormat(" %message% \n [%bar%]");
179
-		$progress->start();
180
-
181
-		foreach ($this->userManager->getBackends() as $backend) {
182
-			$limit = 500;
183
-			$offset = 0;
184
-			do {
185
-				$users = $backend->getUsers('', $limit, $offset);
186
-				foreach ($users as $user) {
187
-					if ($this->keyManager->userHasKeys($user) === false) {
188
-						$progress->setMessage('Create key-pair for ' . $user);
189
-						$progress->advance();
190
-						$this->setupUserFS($user);
191
-						$password = $this->generateOneTimePassword($user);
192
-						$this->userSetup->setupUser($user, $password);
193
-					} else {
194
-						// users which already have a key-pair will be stored with a
195
-						// empty password and filtered out later
196
-						$this->userPasswords[$user] = '';
197
-					}
198
-				}
199
-				$offset += $limit;
200
-			} while (count($users) >= $limit);
201
-		}
202
-
203
-		$progress->setMessage('Key-pair created for all users');
204
-		$progress->finish();
205
-	}
206
-
207
-	/**
208
-	 * iterate over all user and encrypt their files
209
-	 */
210
-	protected function encryptAllUsersFiles() {
211
-		$this->output->writeln("\n");
212
-		$progress = new ProgressBar($this->output);
213
-		$progress->setFormat(" %message% \n [%bar%]");
214
-		$progress->start();
215
-		$numberOfUsers = count($this->userPasswords);
216
-		$userNo = 1;
217
-		if ($this->util->isMasterKeyEnabled()) {
218
-			$this->encryptAllUserFilesWithMasterKey($progress);
219
-		} else {
220
-			foreach ($this->userPasswords as $uid => $password) {
221
-				$userCount = "$uid ($userNo of $numberOfUsers)";
222
-				$this->encryptUsersFiles($uid, $progress, $userCount);
223
-				$userNo++;
224
-			}
225
-		}
226
-		$progress->setMessage("all files encrypted");
227
-		$progress->finish();
228
-	}
229
-
230
-	/**
231
-	 * encrypt all user files with the master key
232
-	 *
233
-	 * @param ProgressBar $progress
234
-	 */
235
-	protected function encryptAllUserFilesWithMasterKey(ProgressBar $progress) {
236
-		$userNo = 1;
237
-		foreach ($this->userManager->getBackends() as $backend) {
238
-			$limit = 500;
239
-			$offset = 0;
240
-			do {
241
-				$users = $backend->getUsers('', $limit, $offset);
242
-				foreach ($users as $user) {
243
-					$userCount = "$user ($userNo)";
244
-					$this->encryptUsersFiles($user, $progress, $userCount);
245
-					$userNo++;
246
-				}
247
-				$offset += $limit;
248
-			} while (count($users) >= $limit);
249
-		}
250
-	}
251
-
252
-	/**
253
-	 * encrypt files from the given user
254
-	 *
255
-	 * @param string $uid
256
-	 * @param ProgressBar $progress
257
-	 * @param string $userCount
258
-	 */
259
-	protected function encryptUsersFiles($uid, ProgressBar $progress, $userCount) {
260
-		$this->setupUserFS($uid);
261
-		$directories = [];
262
-		$directories[] = '/' . $uid . '/files';
263
-
264
-		while ($root = array_pop($directories)) {
265
-			$content = $this->rootView->getDirectoryContent($root);
266
-			foreach ($content as $file) {
267
-				$path = $root . '/' . $file['name'];
268
-				if ($this->rootView->is_dir($path)) {
269
-					$directories[] = $path;
270
-					continue;
271
-				} else {
272
-					$progress->setMessage("encrypt files for user $userCount: $path");
273
-					$progress->advance();
274
-					if ($this->encryptFile($path) === false) {
275
-						$progress->setMessage("encrypt files for user $userCount: $path (already encrypted)");
276
-						$progress->advance();
277
-					}
278
-				}
279
-			}
280
-		}
281
-	}
282
-
283
-	/**
284
-	 * encrypt file
285
-	 *
286
-	 * @param string $path
287
-	 * @return bool
288
-	 */
289
-	protected function encryptFile($path) {
290
-
291
-		// skip already encrypted files
292
-		$fileInfo = $this->rootView->getFileInfo($path);
293
-		if ($fileInfo !== false && $fileInfo->isEncrypted()) {
294
-			return true;
295
-		}
296
-
297
-		$source = $path;
298
-		$target = $path . '.encrypted.' . time();
299
-
300
-		try {
301
-			$this->rootView->copy($source, $target);
302
-			$this->rootView->rename($target, $source);
303
-		} catch (DecryptionFailedException $e) {
304
-			if ($this->rootView->file_exists($target)) {
305
-				$this->rootView->unlink($target);
306
-			}
307
-			return false;
308
-		}
309
-
310
-		return true;
311
-	}
312
-
313
-	/**
314
-	 * output one-time encryption passwords
315
-	 */
316
-	protected function outputPasswords() {
317
-		$table = new Table($this->output);
318
-		$table->setHeaders(['Username', 'Private key password']);
319
-
320
-		//create rows
321
-		$newPasswords = [];
322
-		$unchangedPasswords = [];
323
-		foreach ($this->userPasswords as $uid => $password) {
324
-			if (empty($password)) {
325
-				$unchangedPasswords[] = $uid;
326
-			} else {
327
-				$newPasswords[] = [$uid, $password];
328
-			}
329
-		}
330
-
331
-		if (empty($newPasswords)) {
332
-			$this->output->writeln("\nAll users already had a key-pair, no further action needed.\n");
333
-			return;
334
-		}
335
-
336
-		$table->setRows($newPasswords);
337
-		$table->render();
338
-
339
-		if (!empty($unchangedPasswords)) {
340
-			$this->output->writeln("\nThe following users already had a key-pair which was reused without setting a new password:\n");
341
-			foreach ($unchangedPasswords as $uid) {
342
-				$this->output->writeln("    $uid");
343
-			}
344
-		}
345
-
346
-		$this->writePasswordsToFile($newPasswords);
347
-
348
-		$this->output->writeln('');
349
-		$question = new ConfirmationQuestion('Do you want to send the passwords directly to the users by mail? (y/n) ', false);
350
-		if ($this->questionHelper->ask($this->input, $this->output, $question)) {
351
-			$this->sendPasswordsByMail();
352
-		}
353
-	}
354
-
355
-	/**
356
-	 * write one-time encryption passwords to a csv file
357
-	 *
358
-	 * @param array $passwords
359
-	 */
360
-	protected function writePasswordsToFile(array $passwords) {
361
-		$fp = $this->rootView->fopen('oneTimeEncryptionPasswords.csv', 'w');
362
-		foreach ($passwords as $pwd) {
363
-			fputcsv($fp, $pwd);
364
-		}
365
-		fclose($fp);
366
-		$this->output->writeln("\n");
367
-		$this->output->writeln('A list of all newly created passwords was written to data/oneTimeEncryptionPasswords.csv');
368
-		$this->output->writeln('');
369
-		$this->output->writeln('Each of these users need to login to the web interface, go to the');
370
-		$this->output->writeln('personal settings section "basic encryption module" and');
371
-		$this->output->writeln('update the private key password to match the login password again by');
372
-		$this->output->writeln('entering the one-time password into the "old log-in password" field');
373
-		$this->output->writeln('and their current login password');
374
-	}
375
-
376
-	/**
377
-	 * setup user file system
378
-	 *
379
-	 * @param string $uid
380
-	 */
381
-	protected function setupUserFS($uid) {
382
-		\OC_Util::tearDownFS();
383
-		\OC_Util::setupFS($uid);
384
-	}
385
-
386
-	/**
387
-	 * generate one time password for the user and store it in a array
388
-	 *
389
-	 * @param string $uid
390
-	 * @return string password
391
-	 */
392
-	protected function generateOneTimePassword($uid) {
393
-		$password = $this->secureRandom->generate(16, ISecureRandom::CHAR_HUMAN_READABLE);
394
-		$this->userPasswords[$uid] = $password;
395
-		return $password;
396
-	}
397
-
398
-	/**
399
-	 * send encryption key passwords to the users by mail
400
-	 */
401
-	protected function sendPasswordsByMail() {
402
-		$noMail = [];
403
-
404
-		$this->output->writeln('');
405
-		$progress = new ProgressBar($this->output, count($this->userPasswords));
406
-		$progress->start();
407
-
408
-		foreach ($this->userPasswords as $uid => $password) {
409
-			$progress->advance();
410
-			if (!empty($password)) {
411
-				$recipient = $this->userManager->get($uid);
412
-				if (!$recipient instanceof IUser) {
413
-					continue;
414
-				}
415
-
416
-				$recipientDisplayName = $recipient->getDisplayName();
417
-				$to = $recipient->getEMailAddress();
418
-
419
-				if ($to === '' || $to === null) {
420
-					$noMail[] = $uid;
421
-					continue;
422
-				}
423
-
424
-				$l = $this->l10nFactory->get('encryption', $this->l10nFactory->getUserLanguage($recipient));
425
-
426
-				$template = $this->mailer->createEMailTemplate('encryption.encryptAllPassword', [
427
-					'user' => $recipient->getUID(),
428
-					'password' => $password,
429
-				]);
430
-
431
-				$template->setSubject($l->t('one-time password for server-side-encryption'));
432
-				// 'Hey there,<br><br>The administration enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.<br><br>
433
-				// Please login to the web interface, go to the section "Basic encryption module" of your personal settings and update your encryption password by entering this password into the "Old log-in password" field and your current login-password.<br><br>'
434
-				$template->addHeader();
435
-				$template->addHeading($l->t('Encryption password'));
436
-				$template->addBodyText(
437
-					$l->t('The administration enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.', [htmlspecialchars($password)]),
438
-					$l->t('The administration enabled server-side-encryption. Your files were encrypted using the password "%s".', $password)
439
-				);
440
-				$template->addBodyText(
441
-					$l->t('Please login to the web interface, go to the "Security" section of your personal settings and update your encryption password by entering this password into the "Old log-in password" field and your current login-password.')
442
-				);
443
-				$template->addFooter();
444
-
445
-				// send it out now
446
-				try {
447
-					$message = $this->mailer->createMessage();
448
-					$message->setTo([$to => $recipientDisplayName]);
449
-					$message->useTemplate($template);
450
-					$message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
451
-					$this->mailer->send($message);
452
-				} catch (\Exception $e) {
453
-					$noMail[] = $uid;
454
-				}
455
-			}
456
-		}
457
-
458
-		$progress->finish();
459
-
460
-		if (empty($noMail)) {
461
-			$this->output->writeln("\n\nPassword successfully send to all users");
462
-		} else {
463
-			$table = new Table($this->output);
464
-			$table->setHeaders(['Username', 'Private key password']);
465
-			$this->output->writeln("\n\nCould not send password to following users:\n");
466
-			$rows = [];
467
-			foreach ($noMail as $uid) {
468
-				$rows[] = [$uid, $this->userPasswords[$uid]];
469
-			}
470
-			$table->setRows($rows);
471
-			$table->render();
472
-		}
473
-	}
52
+    /** @var Setup */
53
+    protected $userSetup;
54
+
55
+    /** @var IUserManager */
56
+    protected $userManager;
57
+
58
+    /** @var View */
59
+    protected $rootView;
60
+
61
+    /** @var KeyManager */
62
+    protected $keyManager;
63
+
64
+    /** @var Util */
65
+    protected $util;
66
+
67
+    /** @var array  */
68
+    protected $userPasswords;
69
+
70
+    /** @var  IConfig */
71
+    protected $config;
72
+
73
+    /** @var IMailer */
74
+    protected $mailer;
75
+
76
+    /** @var  IL10N */
77
+    protected $l;
78
+
79
+    /** @var  IFactory */
80
+    protected $l10nFactory;
81
+
82
+    /** @var  QuestionHelper */
83
+    protected $questionHelper;
84
+
85
+    /** @var  OutputInterface */
86
+    protected $output;
87
+
88
+    /** @var  InputInterface */
89
+    protected $input;
90
+
91
+    /** @var ISecureRandom */
92
+    protected $secureRandom;
93
+
94
+    public function __construct(
95
+        Setup $userSetup,
96
+        IUserManager $userManager,
97
+        View $rootView,
98
+        KeyManager $keyManager,
99
+        Util $util,
100
+        IConfig $config,
101
+        IMailer $mailer,
102
+        IL10N $l,
103
+        IFactory $l10nFactory,
104
+        QuestionHelper $questionHelper,
105
+        ISecureRandom $secureRandom
106
+    ) {
107
+        $this->userSetup = $userSetup;
108
+        $this->userManager = $userManager;
109
+        $this->rootView = $rootView;
110
+        $this->keyManager = $keyManager;
111
+        $this->util = $util;
112
+        $this->config = $config;
113
+        $this->mailer = $mailer;
114
+        $this->l = $l;
115
+        $this->l10nFactory = $l10nFactory;
116
+        $this->questionHelper = $questionHelper;
117
+        $this->secureRandom = $secureRandom;
118
+        // store one time passwords for the users
119
+        $this->userPasswords = [];
120
+    }
121
+
122
+    /**
123
+     * start to encrypt all files
124
+     *
125
+     * @param InputInterface $input
126
+     * @param OutputInterface $output
127
+     */
128
+    public function encryptAll(InputInterface $input, OutputInterface $output) {
129
+        $this->input = $input;
130
+        $this->output = $output;
131
+
132
+        $headline = 'Encrypt all files with the ' . Encryption::DISPLAY_NAME;
133
+        $this->output->writeln("\n");
134
+        $this->output->writeln($headline);
135
+        $this->output->writeln(str_pad('', strlen($headline), '='));
136
+        $this->output->writeln("\n");
137
+
138
+        if ($this->util->isMasterKeyEnabled()) {
139
+            $this->output->writeln('Use master key to encrypt all files.');
140
+            $this->keyManager->validateMasterKey();
141
+        } else {
142
+            //create private/public keys for each user and store the private key password
143
+            $this->output->writeln('Create key-pair for every user');
144
+            $this->output->writeln('------------------------------');
145
+            $this->output->writeln('');
146
+            $this->output->writeln('This module will encrypt all files in the users files folder initially.');
147
+            $this->output->writeln('Already existing versions and files in the trash bin will not be encrypted.');
148
+            $this->output->writeln('');
149
+            $this->createKeyPairs();
150
+        }
151
+
152
+
153
+        // output generated encryption key passwords
154
+        if ($this->util->isMasterKeyEnabled() === false) {
155
+            //send-out or display password list and write it to a file
156
+            $this->output->writeln("\n");
157
+            $this->output->writeln('Generated encryption key passwords');
158
+            $this->output->writeln('----------------------------------');
159
+            $this->output->writeln('');
160
+            $this->outputPasswords();
161
+        }
162
+
163
+        //setup users file system and encrypt all files one by one (take should encrypt setting of storage into account)
164
+        $this->output->writeln("\n");
165
+        $this->output->writeln('Start to encrypt users files');
166
+        $this->output->writeln('----------------------------');
167
+        $this->output->writeln('');
168
+        $this->encryptAllUsersFiles();
169
+        $this->output->writeln("\n");
170
+    }
171
+
172
+    /**
173
+     * create key-pair for every user
174
+     */
175
+    protected function createKeyPairs() {
176
+        $this->output->writeln("\n");
177
+        $progress = new ProgressBar($this->output);
178
+        $progress->setFormat(" %message% \n [%bar%]");
179
+        $progress->start();
180
+
181
+        foreach ($this->userManager->getBackends() as $backend) {
182
+            $limit = 500;
183
+            $offset = 0;
184
+            do {
185
+                $users = $backend->getUsers('', $limit, $offset);
186
+                foreach ($users as $user) {
187
+                    if ($this->keyManager->userHasKeys($user) === false) {
188
+                        $progress->setMessage('Create key-pair for ' . $user);
189
+                        $progress->advance();
190
+                        $this->setupUserFS($user);
191
+                        $password = $this->generateOneTimePassword($user);
192
+                        $this->userSetup->setupUser($user, $password);
193
+                    } else {
194
+                        // users which already have a key-pair will be stored with a
195
+                        // empty password and filtered out later
196
+                        $this->userPasswords[$user] = '';
197
+                    }
198
+                }
199
+                $offset += $limit;
200
+            } while (count($users) >= $limit);
201
+        }
202
+
203
+        $progress->setMessage('Key-pair created for all users');
204
+        $progress->finish();
205
+    }
206
+
207
+    /**
208
+     * iterate over all user and encrypt their files
209
+     */
210
+    protected function encryptAllUsersFiles() {
211
+        $this->output->writeln("\n");
212
+        $progress = new ProgressBar($this->output);
213
+        $progress->setFormat(" %message% \n [%bar%]");
214
+        $progress->start();
215
+        $numberOfUsers = count($this->userPasswords);
216
+        $userNo = 1;
217
+        if ($this->util->isMasterKeyEnabled()) {
218
+            $this->encryptAllUserFilesWithMasterKey($progress);
219
+        } else {
220
+            foreach ($this->userPasswords as $uid => $password) {
221
+                $userCount = "$uid ($userNo of $numberOfUsers)";
222
+                $this->encryptUsersFiles($uid, $progress, $userCount);
223
+                $userNo++;
224
+            }
225
+        }
226
+        $progress->setMessage("all files encrypted");
227
+        $progress->finish();
228
+    }
229
+
230
+    /**
231
+     * encrypt all user files with the master key
232
+     *
233
+     * @param ProgressBar $progress
234
+     */
235
+    protected function encryptAllUserFilesWithMasterKey(ProgressBar $progress) {
236
+        $userNo = 1;
237
+        foreach ($this->userManager->getBackends() as $backend) {
238
+            $limit = 500;
239
+            $offset = 0;
240
+            do {
241
+                $users = $backend->getUsers('', $limit, $offset);
242
+                foreach ($users as $user) {
243
+                    $userCount = "$user ($userNo)";
244
+                    $this->encryptUsersFiles($user, $progress, $userCount);
245
+                    $userNo++;
246
+                }
247
+                $offset += $limit;
248
+            } while (count($users) >= $limit);
249
+        }
250
+    }
251
+
252
+    /**
253
+     * encrypt files from the given user
254
+     *
255
+     * @param string $uid
256
+     * @param ProgressBar $progress
257
+     * @param string $userCount
258
+     */
259
+    protected function encryptUsersFiles($uid, ProgressBar $progress, $userCount) {
260
+        $this->setupUserFS($uid);
261
+        $directories = [];
262
+        $directories[] = '/' . $uid . '/files';
263
+
264
+        while ($root = array_pop($directories)) {
265
+            $content = $this->rootView->getDirectoryContent($root);
266
+            foreach ($content as $file) {
267
+                $path = $root . '/' . $file['name'];
268
+                if ($this->rootView->is_dir($path)) {
269
+                    $directories[] = $path;
270
+                    continue;
271
+                } else {
272
+                    $progress->setMessage("encrypt files for user $userCount: $path");
273
+                    $progress->advance();
274
+                    if ($this->encryptFile($path) === false) {
275
+                        $progress->setMessage("encrypt files for user $userCount: $path (already encrypted)");
276
+                        $progress->advance();
277
+                    }
278
+                }
279
+            }
280
+        }
281
+    }
282
+
283
+    /**
284
+     * encrypt file
285
+     *
286
+     * @param string $path
287
+     * @return bool
288
+     */
289
+    protected function encryptFile($path) {
290
+
291
+        // skip already encrypted files
292
+        $fileInfo = $this->rootView->getFileInfo($path);
293
+        if ($fileInfo !== false && $fileInfo->isEncrypted()) {
294
+            return true;
295
+        }
296
+
297
+        $source = $path;
298
+        $target = $path . '.encrypted.' . time();
299
+
300
+        try {
301
+            $this->rootView->copy($source, $target);
302
+            $this->rootView->rename($target, $source);
303
+        } catch (DecryptionFailedException $e) {
304
+            if ($this->rootView->file_exists($target)) {
305
+                $this->rootView->unlink($target);
306
+            }
307
+            return false;
308
+        }
309
+
310
+        return true;
311
+    }
312
+
313
+    /**
314
+     * output one-time encryption passwords
315
+     */
316
+    protected function outputPasswords() {
317
+        $table = new Table($this->output);
318
+        $table->setHeaders(['Username', 'Private key password']);
319
+
320
+        //create rows
321
+        $newPasswords = [];
322
+        $unchangedPasswords = [];
323
+        foreach ($this->userPasswords as $uid => $password) {
324
+            if (empty($password)) {
325
+                $unchangedPasswords[] = $uid;
326
+            } else {
327
+                $newPasswords[] = [$uid, $password];
328
+            }
329
+        }
330
+
331
+        if (empty($newPasswords)) {
332
+            $this->output->writeln("\nAll users already had a key-pair, no further action needed.\n");
333
+            return;
334
+        }
335
+
336
+        $table->setRows($newPasswords);
337
+        $table->render();
338
+
339
+        if (!empty($unchangedPasswords)) {
340
+            $this->output->writeln("\nThe following users already had a key-pair which was reused without setting a new password:\n");
341
+            foreach ($unchangedPasswords as $uid) {
342
+                $this->output->writeln("    $uid");
343
+            }
344
+        }
345
+
346
+        $this->writePasswordsToFile($newPasswords);
347
+
348
+        $this->output->writeln('');
349
+        $question = new ConfirmationQuestion('Do you want to send the passwords directly to the users by mail? (y/n) ', false);
350
+        if ($this->questionHelper->ask($this->input, $this->output, $question)) {
351
+            $this->sendPasswordsByMail();
352
+        }
353
+    }
354
+
355
+    /**
356
+     * write one-time encryption passwords to a csv file
357
+     *
358
+     * @param array $passwords
359
+     */
360
+    protected function writePasswordsToFile(array $passwords) {
361
+        $fp = $this->rootView->fopen('oneTimeEncryptionPasswords.csv', 'w');
362
+        foreach ($passwords as $pwd) {
363
+            fputcsv($fp, $pwd);
364
+        }
365
+        fclose($fp);
366
+        $this->output->writeln("\n");
367
+        $this->output->writeln('A list of all newly created passwords was written to data/oneTimeEncryptionPasswords.csv');
368
+        $this->output->writeln('');
369
+        $this->output->writeln('Each of these users need to login to the web interface, go to the');
370
+        $this->output->writeln('personal settings section "basic encryption module" and');
371
+        $this->output->writeln('update the private key password to match the login password again by');
372
+        $this->output->writeln('entering the one-time password into the "old log-in password" field');
373
+        $this->output->writeln('and their current login password');
374
+    }
375
+
376
+    /**
377
+     * setup user file system
378
+     *
379
+     * @param string $uid
380
+     */
381
+    protected function setupUserFS($uid) {
382
+        \OC_Util::tearDownFS();
383
+        \OC_Util::setupFS($uid);
384
+    }
385
+
386
+    /**
387
+     * generate one time password for the user and store it in a array
388
+     *
389
+     * @param string $uid
390
+     * @return string password
391
+     */
392
+    protected function generateOneTimePassword($uid) {
393
+        $password = $this->secureRandom->generate(16, ISecureRandom::CHAR_HUMAN_READABLE);
394
+        $this->userPasswords[$uid] = $password;
395
+        return $password;
396
+    }
397
+
398
+    /**
399
+     * send encryption key passwords to the users by mail
400
+     */
401
+    protected function sendPasswordsByMail() {
402
+        $noMail = [];
403
+
404
+        $this->output->writeln('');
405
+        $progress = new ProgressBar($this->output, count($this->userPasswords));
406
+        $progress->start();
407
+
408
+        foreach ($this->userPasswords as $uid => $password) {
409
+            $progress->advance();
410
+            if (!empty($password)) {
411
+                $recipient = $this->userManager->get($uid);
412
+                if (!$recipient instanceof IUser) {
413
+                    continue;
414
+                }
415
+
416
+                $recipientDisplayName = $recipient->getDisplayName();
417
+                $to = $recipient->getEMailAddress();
418
+
419
+                if ($to === '' || $to === null) {
420
+                    $noMail[] = $uid;
421
+                    continue;
422
+                }
423
+
424
+                $l = $this->l10nFactory->get('encryption', $this->l10nFactory->getUserLanguage($recipient));
425
+
426
+                $template = $this->mailer->createEMailTemplate('encryption.encryptAllPassword', [
427
+                    'user' => $recipient->getUID(),
428
+                    'password' => $password,
429
+                ]);
430
+
431
+                $template->setSubject($l->t('one-time password for server-side-encryption'));
432
+                // 'Hey there,<br><br>The administration enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.<br><br>
433
+                // Please login to the web interface, go to the section "Basic encryption module" of your personal settings and update your encryption password by entering this password into the "Old log-in password" field and your current login-password.<br><br>'
434
+                $template->addHeader();
435
+                $template->addHeading($l->t('Encryption password'));
436
+                $template->addBodyText(
437
+                    $l->t('The administration enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.', [htmlspecialchars($password)]),
438
+                    $l->t('The administration enabled server-side-encryption. Your files were encrypted using the password "%s".', $password)
439
+                );
440
+                $template->addBodyText(
441
+                    $l->t('Please login to the web interface, go to the "Security" section of your personal settings and update your encryption password by entering this password into the "Old log-in password" field and your current login-password.')
442
+                );
443
+                $template->addFooter();
444
+
445
+                // send it out now
446
+                try {
447
+                    $message = $this->mailer->createMessage();
448
+                    $message->setTo([$to => $recipientDisplayName]);
449
+                    $message->useTemplate($template);
450
+                    $message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
451
+                    $this->mailer->send($message);
452
+                } catch (\Exception $e) {
453
+                    $noMail[] = $uid;
454
+                }
455
+            }
456
+        }
457
+
458
+        $progress->finish();
459
+
460
+        if (empty($noMail)) {
461
+            $this->output->writeln("\n\nPassword successfully send to all users");
462
+        } else {
463
+            $table = new Table($this->output);
464
+            $table->setHeaders(['Username', 'Private key password']);
465
+            $this->output->writeln("\n\nCould not send password to following users:\n");
466
+            $rows = [];
467
+            foreach ($noMail as $uid) {
468
+                $rows[] = [$uid, $this->userPasswords[$uid]];
469
+            }
470
+            $table->setRows($rows);
471
+            $table->render();
472
+        }
473
+    }
474 474
 }
Please login to merge, or discard this patch.