Completed
Pull Request — master (#3965)
by Morris
12:24
created
apps/files/lib/Command/TransferOwnership.php 2 patches
Indentation   +245 added lines, -245 removed lines patch added patch discarded remove patch
@@ -42,249 +42,249 @@
 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
-		$inputPath = ltrim($input->getOption('path'), '/');
122
-		$this->sourcePath = rtrim($this->sourceUser . '/files/' . $inputPath, '/');
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
-			$inputPath = $this->sourcePath;
140
-			$output->writeln("<error>Unknown path provided: $inputPath</error>");
141
-			return 1;
142
-		}
143
-
144
-		// analyse source folder
145
-		$this->analyse($output);
146
-
147
-		// collect all the shares
148
-		$this->collectUsersShares($output);
149
-
150
-		// transfer the files
151
-		$this->transfer($output);
152
-
153
-		// restore the shares
154
-		$this->restoreShares($output);
155
-	}
156
-
157
-	private function walkFiles(View $view, $path, \Closure $callBack) {
158
-		foreach ($view->getDirectoryContent($path) as $fileInfo) {
159
-			if (!$callBack($fileInfo)) {
160
-				return;
161
-			}
162
-			if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
163
-				$this->walkFiles($view, $fileInfo->getPath(), $callBack);
164
-			}
165
-		}
166
-	}
167
-
168
-	/**
169
-	 * @param OutputInterface $output
170
-	 * @throws \Exception
171
-	 */
172
-	protected function analyse(OutputInterface $output) {
173
-		$view = new View();
174
-		$output->writeln("Analysing files of $this->sourceUser ...");
175
-		$progress = new ProgressBar($output);
176
-		$progress->start();
177
-		$self = $this;
178
-
179
-		$this->walkFiles($view, $this->sourcePath,
180
-				function (FileInfo $fileInfo) use ($progress, $self) {
181
-					if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
182
-						// only analyze into folders from main storage,
183
-						if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) {
184
-							return false;
185
-						}
186
-						return true;
187
-					}
188
-					$progress->advance();
189
-					$this->allFiles[] = $fileInfo;
190
-					if ($fileInfo->isEncrypted()) {
191
-						$this->encryptedFiles[] = $fileInfo;
192
-					}
193
-					return true;
194
-				});
195
-		$progress->finish();
196
-		$output->writeln('');
197
-
198
-		// no file is allowed to be encrypted
199
-		if (!empty($this->encryptedFiles)) {
200
-			$output->writeln("<error>Some files are encrypted - please decrypt them first</error>");
201
-			foreach($this->encryptedFiles as $encryptedFile) {
202
-				/** @var FileInfo $encryptedFile */
203
-				$output->writeln("  " . $encryptedFile->getPath());
204
-			}
205
-			throw new \Exception('Execution terminated.');
206
-		}
207
-
208
-	}
209
-
210
-	/**
211
-	 * @param OutputInterface $output
212
-	 */
213
-	private function collectUsersShares(OutputInterface $output) {
214
-		$output->writeln("Collecting all share information for files and folder of $this->sourceUser ...");
215
-
216
-		$progress = new ProgressBar($output, count($this->shares));
217
-		foreach([\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) {
218
-		$offset = 0;
219
-			while (true) {
220
-				$sharePage = $this->shareManager->getSharesBy($this->sourceUser, $shareType, null, true, 50, $offset);
221
-				$progress->advance(count($sharePage));
222
-				if (empty($sharePage)) {
223
-					break;
224
-				}
225
-				$this->shares = array_merge($this->shares, $sharePage);
226
-				$offset += 50;
227
-			}
228
-		}
229
-
230
-		$progress->finish();
231
-		$output->writeln('');
232
-	}
233
-
234
-	/**
235
-	 * @param OutputInterface $output
236
-	 */
237
-	protected function transfer(OutputInterface $output) {
238
-		$view = new View();
239
-		$output->writeln("Transferring files to $this->finalTarget ...");
240
-
241
-		// This change will help user to transfer the folder specified using --path option.
242
-		// Else only the content inside folder is transferred which is not correct.
243
-		if($this->sourcePath !== "$this->sourceUser/files") {
244
-			$view->mkdir($this->finalTarget);
245
-			$this->finalTarget = $this->finalTarget . '/' . basename($this->sourcePath);
246
-		}
247
-		$view->rename($this->sourcePath, $this->finalTarget);
248
-		if (!is_dir("$this->sourceUser/files")) {
249
-			// because the files folder is moved away we need to recreate it
250
-			$view->mkdir("$this->sourceUser/files");
251
-		}
252
-	}
253
-
254
-	/**
255
-	 * @param OutputInterface $output
256
-	 */
257
-	private function restoreShares(OutputInterface $output) {
258
-		$output->writeln("Restoring shares ...");
259
-		$progress = new ProgressBar($output, count($this->shares));
260
-
261
-		foreach($this->shares as $share) {
262
-			try {
263
-				if ($share->getSharedWith() === $this->destinationUser) {
264
-					// Unmount the shares before deleting, so we don't try to get the storage later on.
265
-					$shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget());
266
-					if ($shareMountPoint) {
267
-						$this->mountManager->removeMount($shareMountPoint->getMountPoint());
268
-					}
269
-					$this->shareManager->deleteShare($share);
270
-				} else {
271
-					if ($share->getShareOwner() === $this->sourceUser) {
272
-						$share->setShareOwner($this->destinationUser);
273
-					}
274
-					if ($share->getSharedBy() === $this->sourceUser) {
275
-						$share->setSharedBy($this->destinationUser);
276
-					}
277
-
278
-					$this->shareManager->updateShare($share);
279
-				}
280
-			} catch (\OCP\Files\NotFoundException $e) {
281
-				$output->writeln('<error>Share with id ' . $share->getId() . ' points at deleted file, skipping</error>');
282
-			} catch (\Exception $e) {
283
-				$output->writeln('<error>Could not restore share with id ' . $share->getId() . ':' . $e->getTraceAsString() . '</error>');
284
-			}
285
-			$progress->advance();
286
-		}
287
-		$progress->finish();
288
-		$output->writeln('');
289
-	}
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
+        $inputPath = ltrim($input->getOption('path'), '/');
122
+        $this->sourcePath = rtrim($this->sourceUser . '/files/' . $inputPath, '/');
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
+            $inputPath = $this->sourcePath;
140
+            $output->writeln("<error>Unknown path provided: $inputPath</error>");
141
+            return 1;
142
+        }
143
+
144
+        // analyse source folder
145
+        $this->analyse($output);
146
+
147
+        // collect all the shares
148
+        $this->collectUsersShares($output);
149
+
150
+        // transfer the files
151
+        $this->transfer($output);
152
+
153
+        // restore the shares
154
+        $this->restoreShares($output);
155
+    }
156
+
157
+    private function walkFiles(View $view, $path, \Closure $callBack) {
158
+        foreach ($view->getDirectoryContent($path) as $fileInfo) {
159
+            if (!$callBack($fileInfo)) {
160
+                return;
161
+            }
162
+            if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
163
+                $this->walkFiles($view, $fileInfo->getPath(), $callBack);
164
+            }
165
+        }
166
+    }
167
+
168
+    /**
169
+     * @param OutputInterface $output
170
+     * @throws \Exception
171
+     */
172
+    protected function analyse(OutputInterface $output) {
173
+        $view = new View();
174
+        $output->writeln("Analysing files of $this->sourceUser ...");
175
+        $progress = new ProgressBar($output);
176
+        $progress->start();
177
+        $self = $this;
178
+
179
+        $this->walkFiles($view, $this->sourcePath,
180
+                function (FileInfo $fileInfo) use ($progress, $self) {
181
+                    if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
182
+                        // only analyze into folders from main storage,
183
+                        if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) {
184
+                            return false;
185
+                        }
186
+                        return true;
187
+                    }
188
+                    $progress->advance();
189
+                    $this->allFiles[] = $fileInfo;
190
+                    if ($fileInfo->isEncrypted()) {
191
+                        $this->encryptedFiles[] = $fileInfo;
192
+                    }
193
+                    return true;
194
+                });
195
+        $progress->finish();
196
+        $output->writeln('');
197
+
198
+        // no file is allowed to be encrypted
199
+        if (!empty($this->encryptedFiles)) {
200
+            $output->writeln("<error>Some files are encrypted - please decrypt them first</error>");
201
+            foreach($this->encryptedFiles as $encryptedFile) {
202
+                /** @var FileInfo $encryptedFile */
203
+                $output->writeln("  " . $encryptedFile->getPath());
204
+            }
205
+            throw new \Exception('Execution terminated.');
206
+        }
207
+
208
+    }
209
+
210
+    /**
211
+     * @param OutputInterface $output
212
+     */
213
+    private function collectUsersShares(OutputInterface $output) {
214
+        $output->writeln("Collecting all share information for files and folder of $this->sourceUser ...");
215
+
216
+        $progress = new ProgressBar($output, count($this->shares));
217
+        foreach([\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) {
218
+        $offset = 0;
219
+            while (true) {
220
+                $sharePage = $this->shareManager->getSharesBy($this->sourceUser, $shareType, null, true, 50, $offset);
221
+                $progress->advance(count($sharePage));
222
+                if (empty($sharePage)) {
223
+                    break;
224
+                }
225
+                $this->shares = array_merge($this->shares, $sharePage);
226
+                $offset += 50;
227
+            }
228
+        }
229
+
230
+        $progress->finish();
231
+        $output->writeln('');
232
+    }
233
+
234
+    /**
235
+     * @param OutputInterface $output
236
+     */
237
+    protected function transfer(OutputInterface $output) {
238
+        $view = new View();
239
+        $output->writeln("Transferring files to $this->finalTarget ...");
240
+
241
+        // This change will help user to transfer the folder specified using --path option.
242
+        // Else only the content inside folder is transferred which is not correct.
243
+        if($this->sourcePath !== "$this->sourceUser/files") {
244
+            $view->mkdir($this->finalTarget);
245
+            $this->finalTarget = $this->finalTarget . '/' . basename($this->sourcePath);
246
+        }
247
+        $view->rename($this->sourcePath, $this->finalTarget);
248
+        if (!is_dir("$this->sourceUser/files")) {
249
+            // because the files folder is moved away we need to recreate it
250
+            $view->mkdir("$this->sourceUser/files");
251
+        }
252
+    }
253
+
254
+    /**
255
+     * @param OutputInterface $output
256
+     */
257
+    private function restoreShares(OutputInterface $output) {
258
+        $output->writeln("Restoring shares ...");
259
+        $progress = new ProgressBar($output, count($this->shares));
260
+
261
+        foreach($this->shares as $share) {
262
+            try {
263
+                if ($share->getSharedWith() === $this->destinationUser) {
264
+                    // Unmount the shares before deleting, so we don't try to get the storage later on.
265
+                    $shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget());
266
+                    if ($shareMountPoint) {
267
+                        $this->mountManager->removeMount($shareMountPoint->getMountPoint());
268
+                    }
269
+                    $this->shareManager->deleteShare($share);
270
+                } else {
271
+                    if ($share->getShareOwner() === $this->sourceUser) {
272
+                        $share->setShareOwner($this->destinationUser);
273
+                    }
274
+                    if ($share->getSharedBy() === $this->sourceUser) {
275
+                        $share->setSharedBy($this->destinationUser);
276
+                    }
277
+
278
+                    $this->shareManager->updateShare($share);
279
+                }
280
+            } catch (\OCP\Files\NotFoundException $e) {
281
+                $output->writeln('<error>Share with id ' . $share->getId() . ' points at deleted file, skipping</error>');
282
+            } catch (\Exception $e) {
283
+                $output->writeln('<error>Could not restore share with id ' . $share->getId() . ':' . $e->getTraceAsString() . '</error>');
284
+            }
285
+            $progress->advance();
286
+        }
287
+        $progress->finish();
288
+        $output->writeln('');
289
+    }
290 290
 }
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
 		$inputPath = ltrim($input->getOption('path'), '/');
122
-		$this->sourcePath = rtrim($this->sourceUser . '/files/' . $inputPath, '/');
122
+		$this->sourcePath = rtrim($this->sourceUser.'/files/'.$inputPath, '/');
123 123
 
124 124
 		// target user has to be ready
125 125
 		if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) {
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
 		$self = $this;
178 178
 
179 179
 		$this->walkFiles($view, $this->sourcePath,
180
-				function (FileInfo $fileInfo) use ($progress, $self) {
180
+				function(FileInfo $fileInfo) use ($progress, $self) {
181 181
 					if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
182 182
 						// only analyze into folders from main storage,
183 183
 						if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) {
@@ -198,9 +198,9 @@  discard block
 block discarded – undo
198 198
 		// no file is allowed to be encrypted
199 199
 		if (!empty($this->encryptedFiles)) {
200 200
 			$output->writeln("<error>Some files are encrypted - please decrypt them first</error>");
201
-			foreach($this->encryptedFiles as $encryptedFile) {
201
+			foreach ($this->encryptedFiles as $encryptedFile) {
202 202
 				/** @var FileInfo $encryptedFile */
203
-				$output->writeln("  " . $encryptedFile->getPath());
203
+				$output->writeln("  ".$encryptedFile->getPath());
204 204
 			}
205 205
 			throw new \Exception('Execution terminated.');
206 206
 		}
@@ -214,7 +214,7 @@  discard block
 block discarded – undo
214 214
 		$output->writeln("Collecting all share information for files and folder of $this->sourceUser ...");
215 215
 
216 216
 		$progress = new ProgressBar($output, count($this->shares));
217
-		foreach([\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) {
217
+		foreach ([\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) {
218 218
 		$offset = 0;
219 219
 			while (true) {
220 220
 				$sharePage = $this->shareManager->getSharesBy($this->sourceUser, $shareType, null, true, 50, $offset);
@@ -240,9 +240,9 @@  discard block
 block discarded – undo
240 240
 
241 241
 		// This change will help user to transfer the folder specified using --path option.
242 242
 		// Else only the content inside folder is transferred which is not correct.
243
-		if($this->sourcePath !== "$this->sourceUser/files") {
243
+		if ($this->sourcePath !== "$this->sourceUser/files") {
244 244
 			$view->mkdir($this->finalTarget);
245
-			$this->finalTarget = $this->finalTarget . '/' . basename($this->sourcePath);
245
+			$this->finalTarget = $this->finalTarget.'/'.basename($this->sourcePath);
246 246
 		}
247 247
 		$view->rename($this->sourcePath, $this->finalTarget);
248 248
 		if (!is_dir("$this->sourceUser/files")) {
@@ -258,11 +258,11 @@  discard block
 block discarded – undo
258 258
 		$output->writeln("Restoring shares ...");
259 259
 		$progress = new ProgressBar($output, count($this->shares));
260 260
 
261
-		foreach($this->shares as $share) {
261
+		foreach ($this->shares as $share) {
262 262
 			try {
263 263
 				if ($share->getSharedWith() === $this->destinationUser) {
264 264
 					// Unmount the shares before deleting, so we don't try to get the storage later on.
265
-					$shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget());
265
+					$shareMountPoint = $this->mountManager->find('/'.$this->destinationUser.'/files'.$share->getTarget());
266 266
 					if ($shareMountPoint) {
267 267
 						$this->mountManager->removeMount($shareMountPoint->getMountPoint());
268 268
 					}
@@ -278,9 +278,9 @@  discard block
 block discarded – undo
278 278
 					$this->shareManager->updateShare($share);
279 279
 				}
280 280
 			} catch (\OCP\Files\NotFoundException $e) {
281
-				$output->writeln('<error>Share with id ' . $share->getId() . ' points at deleted file, skipping</error>');
281
+				$output->writeln('<error>Share with id '.$share->getId().' points at deleted file, skipping</error>');
282 282
 			} catch (\Exception $e) {
283
-				$output->writeln('<error>Could not restore share with id ' . $share->getId() . ':' . $e->getTraceAsString() . '</error>');
283
+				$output->writeln('<error>Could not restore share with id '.$share->getId().':'.$e->getTraceAsString().'</error>');
284 284
 			}
285 285
 			$progress->advance();
286 286
 		}
Please login to merge, or discard this patch.