Completed
Push — master ( 6e6cba...d2654c )
by Morris
11:18
created
apps/files/lib/Command/TransferOwnership.php 2 patches
Indentation   +244 added lines, -244 removed lines patch added patch discarded remove patch
@@ -42,248 +42,248 @@
 block discarded – undo
42 42
 
43 43
 class TransferOwnership extends Command {
44 44
 
45
-	/** @var IUserManager $userManager */
46
-	private $userManager;
47
-
48
-	/** @var IManager */
49
-	private $shareManager;
50
-
51
-	/** @var IMountManager */
52
-	private $mountManager;
53
-
54
-	/** @var FileInfo[] */
55
-	private $allFiles = [];
56
-
57
-	/** @var FileInfo[] */
58
-	private $encryptedFiles = [];
59
-
60
-	/** @var IShare[] */
61
-	private $shares = [];
62
-
63
-	/** @var string */
64
-	private $sourceUser;
65
-
66
-	/** @var string */
67
-	private $destinationUser;
68
-
69
-	/** @var string */
70
-	private $sourcePath;
71
-
72
-	/** @var string */
73
-	private $finalTarget;
74
-
75
-	public function __construct(IUserManager $userManager, IManager $shareManager, IMountManager $mountManager) {
76
-		$this->userManager = $userManager;
77
-		$this->shareManager = $shareManager;
78
-		$this->mountManager = $mountManager;
79
-		parent::__construct();
80
-	}
81
-
82
-	protected function configure() {
83
-		$this
84
-			->setName('files:transfer-ownership')
85
-			->setDescription('All files and folders are moved to another user - shares are moved as well.')
86
-			->addArgument(
87
-				'source-user',
88
-				InputArgument::REQUIRED,
89
-				'owner of files which shall be moved'
90
-			)
91
-			->addArgument(
92
-				'destination-user',
93
-				InputArgument::REQUIRED,
94
-				'user who will be the new owner of the files'
95
-			)
96
-			->addOption(
97
-				'path',
98
-				null,
99
-				InputOption::VALUE_REQUIRED,
100
-				'selectively provide the path to transfer. For example --path="folder_name"',
101
-				''
102
-			);
103
-	}
104
-
105
-	protected function execute(InputInterface $input, OutputInterface $output) {
106
-		$sourceUserObject = $this->userManager->get($input->getArgument('source-user'));
107
-		$destinationUserObject = $this->userManager->get($input->getArgument('destination-user'));
108
-
109
-		if (!$sourceUserObject instanceof IUser) {
110
-			$output->writeln("<error>Unknown source user $this->sourceUser</error>");
111
-			return 1;
112
-		}
113
-
114
-		if (!$destinationUserObject instanceof IUser) {
115
-			$output->writeln("<error>Unknown destination user $this->destinationUser</error>");
116
-			return 1;
117
-		}
118
-
119
-		$this->sourceUser = $sourceUserObject->getUID();
120
-		$this->destinationUser = $destinationUserObject->getUID();
121
-		$sourcePathOption = ltrim($input->getOption('path'), '/');
122
-		$this->sourcePath = rtrim($this->sourceUser . '/files/' . $sourcePathOption, '/');
123
-
124
-		// target user has to be ready
125
-		if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) {
126
-			$output->writeln("<error>The target user is not ready to accept files. The user has at least to be logged in once.</error>");
127
-			return 2;
128
-		}
129
-
130
-		$date = date('Y-m-d H-i-s');
131
-		$this->finalTarget = "$this->destinationUser/files/transferred from $this->sourceUser on $date";
132
-
133
-		// setup filesystem
134
-		Filesystem::initMountPoints($this->sourceUser);
135
-		Filesystem::initMountPoints($this->destinationUser);
136
-
137
-		$view = new View();
138
-		if (!$view->is_dir($this->sourcePath)) {
139
-			$output->writeln("<error>Unknown path provided: $sourcePathOption</error>");
140
-			return 1;
141
-		}
142
-
143
-		// analyse source folder
144
-		$this->analyse($output);
145
-
146
-		// collect all the shares
147
-		$this->collectUsersShares($output);
148
-
149
-		// transfer the files
150
-		$this->transfer($output);
151
-
152
-		// restore the shares
153
-		$this->restoreShares($output);
154
-	}
155
-
156
-	private function walkFiles(View $view, $path, \Closure $callBack) {
157
-		foreach ($view->getDirectoryContent($path) as $fileInfo) {
158
-			if (!$callBack($fileInfo)) {
159
-				return;
160
-			}
161
-			if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
162
-				$this->walkFiles($view, $fileInfo->getPath(), $callBack);
163
-			}
164
-		}
165
-	}
166
-
167
-	/**
168
-	 * @param OutputInterface $output
169
-	 * @throws \Exception
170
-	 */
171
-	protected function analyse(OutputInterface $output) {
172
-		$view = new View();
173
-		$output->writeln("Analysing files of $this->sourceUser ...");
174
-		$progress = new ProgressBar($output);
175
-		$progress->start();
176
-		$self = $this;
177
-
178
-		$this->walkFiles($view, $this->sourcePath,
179
-				function (FileInfo $fileInfo) use ($progress, $self) {
180
-					if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
181
-						// only analyze into folders from main storage,
182
-						if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) {
183
-							return false;
184
-						}
185
-						return true;
186
-					}
187
-					$progress->advance();
188
-					$this->allFiles[] = $fileInfo;
189
-					if ($fileInfo->isEncrypted()) {
190
-						$this->encryptedFiles[] = $fileInfo;
191
-					}
192
-					return true;
193
-				});
194
-		$progress->finish();
195
-		$output->writeln('');
196
-
197
-		// no file is allowed to be encrypted
198
-		if (!empty($this->encryptedFiles)) {
199
-			$output->writeln("<error>Some files are encrypted - please decrypt them first</error>");
200
-			foreach($this->encryptedFiles as $encryptedFile) {
201
-				/** @var FileInfo $encryptedFile */
202
-				$output->writeln("  " . $encryptedFile->getPath());
203
-			}
204
-			throw new \Exception('Execution terminated.');
205
-		}
206
-
207
-	}
208
-
209
-	/**
210
-	 * @param OutputInterface $output
211
-	 */
212
-	private function collectUsersShares(OutputInterface $output) {
213
-		$output->writeln("Collecting all share information for files and folder of $this->sourceUser ...");
214
-
215
-		$progress = new ProgressBar($output, count($this->shares));
216
-		foreach([\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) {
217
-		$offset = 0;
218
-			while (true) {
219
-				$sharePage = $this->shareManager->getSharesBy($this->sourceUser, $shareType, null, true, 50, $offset);
220
-				$progress->advance(count($sharePage));
221
-				if (empty($sharePage)) {
222
-					break;
223
-				}
224
-				$this->shares = array_merge($this->shares, $sharePage);
225
-				$offset += 50;
226
-			}
227
-		}
228
-
229
-		$progress->finish();
230
-		$output->writeln('');
231
-	}
232
-
233
-	/**
234
-	 * @param OutputInterface $output
235
-	 */
236
-	protected function transfer(OutputInterface $output) {
237
-		$view = new View();
238
-		$output->writeln("Transferring files to $this->finalTarget ...");
239
-
240
-		// This change will help user to transfer the folder specified using --path option.
241
-		// Else only the content inside folder is transferred which is not correct.
242
-		if($this->sourcePath !== "$this->sourceUser/files") {
243
-			$view->mkdir($this->finalTarget);
244
-			$this->finalTarget = $this->finalTarget . '/' . basename($this->sourcePath);
245
-		}
246
-		$view->rename($this->sourcePath, $this->finalTarget);
247
-		if (!is_dir("$this->sourceUser/files")) {
248
-			// because the files folder is moved away we need to recreate it
249
-			$view->mkdir("$this->sourceUser/files");
250
-		}
251
-	}
252
-
253
-	/**
254
-	 * @param OutputInterface $output
255
-	 */
256
-	private function restoreShares(OutputInterface $output) {
257
-		$output->writeln("Restoring shares ...");
258
-		$progress = new ProgressBar($output, count($this->shares));
259
-
260
-		foreach($this->shares as $share) {
261
-			try {
262
-				if ($share->getSharedWith() === $this->destinationUser) {
263
-					// Unmount the shares before deleting, so we don't try to get the storage later on.
264
-					$shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget());
265
-					if ($shareMountPoint) {
266
-						$this->mountManager->removeMount($shareMountPoint->getMountPoint());
267
-					}
268
-					$this->shareManager->deleteShare($share);
269
-				} else {
270
-					if ($share->getShareOwner() === $this->sourceUser) {
271
-						$share->setShareOwner($this->destinationUser);
272
-					}
273
-					if ($share->getSharedBy() === $this->sourceUser) {
274
-						$share->setSharedBy($this->destinationUser);
275
-					}
276
-
277
-					$this->shareManager->updateShare($share);
278
-				}
279
-			} catch (\OCP\Files\NotFoundException $e) {
280
-				$output->writeln('<error>Share with id ' . $share->getId() . ' points at deleted file, skipping</error>');
281
-			} catch (\Exception $e) {
282
-				$output->writeln('<error>Could not restore share with id ' . $share->getId() . ':' . $e->getTraceAsString() . '</error>');
283
-			}
284
-			$progress->advance();
285
-		}
286
-		$progress->finish();
287
-		$output->writeln('');
288
-	}
45
+    /** @var IUserManager $userManager */
46
+    private $userManager;
47
+
48
+    /** @var IManager */
49
+    private $shareManager;
50
+
51
+    /** @var IMountManager */
52
+    private $mountManager;
53
+
54
+    /** @var FileInfo[] */
55
+    private $allFiles = [];
56
+
57
+    /** @var FileInfo[] */
58
+    private $encryptedFiles = [];
59
+
60
+    /** @var IShare[] */
61
+    private $shares = [];
62
+
63
+    /** @var string */
64
+    private $sourceUser;
65
+
66
+    /** @var string */
67
+    private $destinationUser;
68
+
69
+    /** @var string */
70
+    private $sourcePath;
71
+
72
+    /** @var string */
73
+    private $finalTarget;
74
+
75
+    public function __construct(IUserManager $userManager, IManager $shareManager, IMountManager $mountManager) {
76
+        $this->userManager = $userManager;
77
+        $this->shareManager = $shareManager;
78
+        $this->mountManager = $mountManager;
79
+        parent::__construct();
80
+    }
81
+
82
+    protected function configure() {
83
+        $this
84
+            ->setName('files:transfer-ownership')
85
+            ->setDescription('All files and folders are moved to another user - shares are moved as well.')
86
+            ->addArgument(
87
+                'source-user',
88
+                InputArgument::REQUIRED,
89
+                'owner of files which shall be moved'
90
+            )
91
+            ->addArgument(
92
+                'destination-user',
93
+                InputArgument::REQUIRED,
94
+                'user who will be the new owner of the files'
95
+            )
96
+            ->addOption(
97
+                'path',
98
+                null,
99
+                InputOption::VALUE_REQUIRED,
100
+                'selectively provide the path to transfer. For example --path="folder_name"',
101
+                ''
102
+            );
103
+    }
104
+
105
+    protected function execute(InputInterface $input, OutputInterface $output) {
106
+        $sourceUserObject = $this->userManager->get($input->getArgument('source-user'));
107
+        $destinationUserObject = $this->userManager->get($input->getArgument('destination-user'));
108
+
109
+        if (!$sourceUserObject instanceof IUser) {
110
+            $output->writeln("<error>Unknown source user $this->sourceUser</error>");
111
+            return 1;
112
+        }
113
+
114
+        if (!$destinationUserObject instanceof IUser) {
115
+            $output->writeln("<error>Unknown destination user $this->destinationUser</error>");
116
+            return 1;
117
+        }
118
+
119
+        $this->sourceUser = $sourceUserObject->getUID();
120
+        $this->destinationUser = $destinationUserObject->getUID();
121
+        $sourcePathOption = ltrim($input->getOption('path'), '/');
122
+        $this->sourcePath = rtrim($this->sourceUser . '/files/' . $sourcePathOption, '/');
123
+
124
+        // target user has to be ready
125
+        if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) {
126
+            $output->writeln("<error>The target user is not ready to accept files. The user has at least to be logged in once.</error>");
127
+            return 2;
128
+        }
129
+
130
+        $date = date('Y-m-d H-i-s');
131
+        $this->finalTarget = "$this->destinationUser/files/transferred from $this->sourceUser on $date";
132
+
133
+        // setup filesystem
134
+        Filesystem::initMountPoints($this->sourceUser);
135
+        Filesystem::initMountPoints($this->destinationUser);
136
+
137
+        $view = new View();
138
+        if (!$view->is_dir($this->sourcePath)) {
139
+            $output->writeln("<error>Unknown path provided: $sourcePathOption</error>");
140
+            return 1;
141
+        }
142
+
143
+        // analyse source folder
144
+        $this->analyse($output);
145
+
146
+        // collect all the shares
147
+        $this->collectUsersShares($output);
148
+
149
+        // transfer the files
150
+        $this->transfer($output);
151
+
152
+        // restore the shares
153
+        $this->restoreShares($output);
154
+    }
155
+
156
+    private function walkFiles(View $view, $path, \Closure $callBack) {
157
+        foreach ($view->getDirectoryContent($path) as $fileInfo) {
158
+            if (!$callBack($fileInfo)) {
159
+                return;
160
+            }
161
+            if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
162
+                $this->walkFiles($view, $fileInfo->getPath(), $callBack);
163
+            }
164
+        }
165
+    }
166
+
167
+    /**
168
+     * @param OutputInterface $output
169
+     * @throws \Exception
170
+     */
171
+    protected function analyse(OutputInterface $output) {
172
+        $view = new View();
173
+        $output->writeln("Analysing files of $this->sourceUser ...");
174
+        $progress = new ProgressBar($output);
175
+        $progress->start();
176
+        $self = $this;
177
+
178
+        $this->walkFiles($view, $this->sourcePath,
179
+                function (FileInfo $fileInfo) use ($progress, $self) {
180
+                    if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
181
+                        // only analyze into folders from main storage,
182
+                        if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) {
183
+                            return false;
184
+                        }
185
+                        return true;
186
+                    }
187
+                    $progress->advance();
188
+                    $this->allFiles[] = $fileInfo;
189
+                    if ($fileInfo->isEncrypted()) {
190
+                        $this->encryptedFiles[] = $fileInfo;
191
+                    }
192
+                    return true;
193
+                });
194
+        $progress->finish();
195
+        $output->writeln('');
196
+
197
+        // no file is allowed to be encrypted
198
+        if (!empty($this->encryptedFiles)) {
199
+            $output->writeln("<error>Some files are encrypted - please decrypt them first</error>");
200
+            foreach($this->encryptedFiles as $encryptedFile) {
201
+                /** @var FileInfo $encryptedFile */
202
+                $output->writeln("  " . $encryptedFile->getPath());
203
+            }
204
+            throw new \Exception('Execution terminated.');
205
+        }
206
+
207
+    }
208
+
209
+    /**
210
+     * @param OutputInterface $output
211
+     */
212
+    private function collectUsersShares(OutputInterface $output) {
213
+        $output->writeln("Collecting all share information for files and folder of $this->sourceUser ...");
214
+
215
+        $progress = new ProgressBar($output, count($this->shares));
216
+        foreach([\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) {
217
+        $offset = 0;
218
+            while (true) {
219
+                $sharePage = $this->shareManager->getSharesBy($this->sourceUser, $shareType, null, true, 50, $offset);
220
+                $progress->advance(count($sharePage));
221
+                if (empty($sharePage)) {
222
+                    break;
223
+                }
224
+                $this->shares = array_merge($this->shares, $sharePage);
225
+                $offset += 50;
226
+            }
227
+        }
228
+
229
+        $progress->finish();
230
+        $output->writeln('');
231
+    }
232
+
233
+    /**
234
+     * @param OutputInterface $output
235
+     */
236
+    protected function transfer(OutputInterface $output) {
237
+        $view = new View();
238
+        $output->writeln("Transferring files to $this->finalTarget ...");
239
+
240
+        // This change will help user to transfer the folder specified using --path option.
241
+        // Else only the content inside folder is transferred which is not correct.
242
+        if($this->sourcePath !== "$this->sourceUser/files") {
243
+            $view->mkdir($this->finalTarget);
244
+            $this->finalTarget = $this->finalTarget . '/' . basename($this->sourcePath);
245
+        }
246
+        $view->rename($this->sourcePath, $this->finalTarget);
247
+        if (!is_dir("$this->sourceUser/files")) {
248
+            // because the files folder is moved away we need to recreate it
249
+            $view->mkdir("$this->sourceUser/files");
250
+        }
251
+    }
252
+
253
+    /**
254
+     * @param OutputInterface $output
255
+     */
256
+    private function restoreShares(OutputInterface $output) {
257
+        $output->writeln("Restoring shares ...");
258
+        $progress = new ProgressBar($output, count($this->shares));
259
+
260
+        foreach($this->shares as $share) {
261
+            try {
262
+                if ($share->getSharedWith() === $this->destinationUser) {
263
+                    // Unmount the shares before deleting, so we don't try to get the storage later on.
264
+                    $shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget());
265
+                    if ($shareMountPoint) {
266
+                        $this->mountManager->removeMount($shareMountPoint->getMountPoint());
267
+                    }
268
+                    $this->shareManager->deleteShare($share);
269
+                } else {
270
+                    if ($share->getShareOwner() === $this->sourceUser) {
271
+                        $share->setShareOwner($this->destinationUser);
272
+                    }
273
+                    if ($share->getSharedBy() === $this->sourceUser) {
274
+                        $share->setSharedBy($this->destinationUser);
275
+                    }
276
+
277
+                    $this->shareManager->updateShare($share);
278
+                }
279
+            } catch (\OCP\Files\NotFoundException $e) {
280
+                $output->writeln('<error>Share with id ' . $share->getId() . ' points at deleted file, skipping</error>');
281
+            } catch (\Exception $e) {
282
+                $output->writeln('<error>Could not restore share with id ' . $share->getId() . ':' . $e->getTraceAsString() . '</error>');
283
+            }
284
+            $progress->advance();
285
+        }
286
+        $progress->finish();
287
+        $output->writeln('');
288
+    }
289 289
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -119,7 +119,7 @@  discard block
 block discarded – undo
119 119
 		$this->sourceUser = $sourceUserObject->getUID();
120 120
 		$this->destinationUser = $destinationUserObject->getUID();
121 121
 		$sourcePathOption = ltrim($input->getOption('path'), '/');
122
-		$this->sourcePath = rtrim($this->sourceUser . '/files/' . $sourcePathOption, '/');
122
+		$this->sourcePath = rtrim($this->sourceUser.'/files/'.$sourcePathOption, '/');
123 123
 
124 124
 		// target user has to be ready
125 125
 		if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) {
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
 		$self = $this;
177 177
 
178 178
 		$this->walkFiles($view, $this->sourcePath,
179
-				function (FileInfo $fileInfo) use ($progress, $self) {
179
+				function(FileInfo $fileInfo) use ($progress, $self) {
180 180
 					if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
181 181
 						// only analyze into folders from main storage,
182 182
 						if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) {
@@ -197,9 +197,9 @@  discard block
 block discarded – undo
197 197
 		// no file is allowed to be encrypted
198 198
 		if (!empty($this->encryptedFiles)) {
199 199
 			$output->writeln("<error>Some files are encrypted - please decrypt them first</error>");
200
-			foreach($this->encryptedFiles as $encryptedFile) {
200
+			foreach ($this->encryptedFiles as $encryptedFile) {
201 201
 				/** @var FileInfo $encryptedFile */
202
-				$output->writeln("  " . $encryptedFile->getPath());
202
+				$output->writeln("  ".$encryptedFile->getPath());
203 203
 			}
204 204
 			throw new \Exception('Execution terminated.');
205 205
 		}
@@ -213,7 +213,7 @@  discard block
 block discarded – undo
213 213
 		$output->writeln("Collecting all share information for files and folder of $this->sourceUser ...");
214 214
 
215 215
 		$progress = new ProgressBar($output, count($this->shares));
216
-		foreach([\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) {
216
+		foreach ([\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) {
217 217
 		$offset = 0;
218 218
 			while (true) {
219 219
 				$sharePage = $this->shareManager->getSharesBy($this->sourceUser, $shareType, null, true, 50, $offset);
@@ -239,9 +239,9 @@  discard block
 block discarded – undo
239 239
 
240 240
 		// This change will help user to transfer the folder specified using --path option.
241 241
 		// Else only the content inside folder is transferred which is not correct.
242
-		if($this->sourcePath !== "$this->sourceUser/files") {
242
+		if ($this->sourcePath !== "$this->sourceUser/files") {
243 243
 			$view->mkdir($this->finalTarget);
244
-			$this->finalTarget = $this->finalTarget . '/' . basename($this->sourcePath);
244
+			$this->finalTarget = $this->finalTarget.'/'.basename($this->sourcePath);
245 245
 		}
246 246
 		$view->rename($this->sourcePath, $this->finalTarget);
247 247
 		if (!is_dir("$this->sourceUser/files")) {
@@ -257,11 +257,11 @@  discard block
 block discarded – undo
257 257
 		$output->writeln("Restoring shares ...");
258 258
 		$progress = new ProgressBar($output, count($this->shares));
259 259
 
260
-		foreach($this->shares as $share) {
260
+		foreach ($this->shares as $share) {
261 261
 			try {
262 262
 				if ($share->getSharedWith() === $this->destinationUser) {
263 263
 					// Unmount the shares before deleting, so we don't try to get the storage later on.
264
-					$shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget());
264
+					$shareMountPoint = $this->mountManager->find('/'.$this->destinationUser.'/files'.$share->getTarget());
265 265
 					if ($shareMountPoint) {
266 266
 						$this->mountManager->removeMount($shareMountPoint->getMountPoint());
267 267
 					}
@@ -277,9 +277,9 @@  discard block
 block discarded – undo
277 277
 					$this->shareManager->updateShare($share);
278 278
 				}
279 279
 			} catch (\OCP\Files\NotFoundException $e) {
280
-				$output->writeln('<error>Share with id ' . $share->getId() . ' points at deleted file, skipping</error>');
280
+				$output->writeln('<error>Share with id '.$share->getId().' points at deleted file, skipping</error>');
281 281
 			} catch (\Exception $e) {
282
-				$output->writeln('<error>Could not restore share with id ' . $share->getId() . ':' . $e->getTraceAsString() . '</error>');
282
+				$output->writeln('<error>Could not restore share with id '.$share->getId().':'.$e->getTraceAsString().'</error>');
283 283
 			}
284 284
 			$progress->advance();
285 285
 		}
Please login to merge, or discard this patch.