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