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