@@ -303,6 +303,7 @@ |
||
303 | 303 | * get default share folder |
304 | 304 | * |
305 | 305 | * @param \OC\Files\View |
306 | + * @param View $view |
|
306 | 307 | * @return string |
307 | 308 | */ |
308 | 309 | public static function getShareFolder($view = null) { |
@@ -87,7 +87,7 @@ discard block |
||
87 | 87 | |
88 | 88 | $basePath = $path; |
89 | 89 | |
90 | - if ($relativePath !== null && Filesystem::isReadable($basePath . $relativePath)) { |
|
90 | + if ($relativePath !== null && Filesystem::isReadable($basePath.$relativePath)) { |
|
91 | 91 | $path .= Filesystem::normalizePath($relativePath); |
92 | 92 | } |
93 | 93 | |
@@ -112,14 +112,14 @@ discard block |
||
112 | 112 | if ($password !== null) { |
113 | 113 | if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { |
114 | 114 | if ($shareManager->checkPassword($share, $password)) { |
115 | - \OC::$server->getSession()->set('public_link_authenticated', (string)$share->getId()); |
|
115 | + \OC::$server->getSession()->set('public_link_authenticated', (string) $share->getId()); |
|
116 | 116 | return true; |
117 | 117 | } |
118 | 118 | } |
119 | 119 | } else { |
120 | 120 | // not authenticated ? |
121 | 121 | if (\OC::$server->getSession()->exists('public_link_authenticated') |
122 | - && \OC::$server->getSession()->get('public_link_authenticated') !== (string)$share->getId()) { |
|
122 | + && \OC::$server->getSession()->get('public_link_authenticated') !== (string) $share->getId()) { |
|
123 | 123 | return true; |
124 | 124 | } |
125 | 125 | } |
@@ -132,7 +132,7 @@ discard block |
||
132 | 132 | Filesystem::initMountPoints($owner); |
133 | 133 | $info = Filesystem::getFileInfo($target); |
134 | 134 | $ownerView = new View('/'.$owner.'/files'); |
135 | - if ( $owner != User::getUser() ) { |
|
135 | + if ($owner != User::getUser()) { |
|
136 | 136 | $path = $ownerView->getPath($info['fileid']); |
137 | 137 | } else { |
138 | 138 | $path = $target; |
@@ -145,7 +145,7 @@ discard block |
||
145 | 145 | if ($info instanceof \OC\Files\FileInfo) { |
146 | 146 | $ids[] = $info['fileid']; |
147 | 147 | } else { |
148 | - \OCP\Util::writeLog('sharing', 'No fileinfo available for: ' . $path, \OCP\Util::WARN); |
|
148 | + \OCP\Util::writeLog('sharing', 'No fileinfo available for: '.$path, \OCP\Util::WARN); |
|
149 | 149 | } |
150 | 150 | $path = dirname($path); |
151 | 151 | } |
@@ -155,7 +155,7 @@ discard block |
||
155 | 155 | $idList = array_chunk($ids, 99, true); |
156 | 156 | |
157 | 157 | foreach ($idList as $subList) { |
158 | - $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (" . implode(',', $subList) . ") AND `share_type` IN (0, 1, 2)"; |
|
158 | + $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (".implode(',', $subList).") AND `share_type` IN (0, 1, 2)"; |
|
159 | 159 | $query = \OCP\DB::prepare($statement); |
160 | 160 | $r = $query->execute(); |
161 | 161 | $result = array_merge($result, $r->fetchAll()); |
@@ -183,7 +183,7 @@ discard block |
||
183 | 183 | $uid = User::getUser(); |
184 | 184 | } |
185 | 185 | Filesystem::initMountPoints($uid); |
186 | - if ( $uid != User::getUser() ) { |
|
186 | + if ($uid != User::getUser()) { |
|
187 | 187 | $info = Filesystem::getFileInfo($filename); |
188 | 188 | $ownerView = new View('/'.$uid.'/files'); |
189 | 189 | try { |
@@ -230,7 +230,7 @@ discard block |
||
230 | 230 | $dir = $pathinfo['dirname']; |
231 | 231 | $i = 2; |
232 | 232 | while ($view->file_exists($path) || in_array($path, $excludeList)) { |
233 | - $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); |
|
233 | + $path = Filesystem::normalizePath($dir.'/'.$name.' ('.$i.')'.$ext); |
|
234 | 234 | $i++; |
235 | 235 | } |
236 | 236 | |
@@ -254,7 +254,7 @@ discard block |
||
254 | 254 | $dir = ''; |
255 | 255 | $subdirs = explode('/', $shareFolder); |
256 | 256 | foreach ($subdirs as $subdir) { |
257 | - $dir = $dir . '/' . $subdir; |
|
257 | + $dir = $dir.'/'.$subdir; |
|
258 | 258 | if (!$view->is_dir($dir)) { |
259 | 259 | $view->mkdir($dir); |
260 | 260 | } |
@@ -36,243 +36,243 @@ |
||
36 | 36 | |
37 | 37 | class Helper { |
38 | 38 | |
39 | - public static function registerHooks() { |
|
40 | - \OCP\Util::connectHook('OC_Filesystem', 'post_rename', '\OCA\Files_Sharing\Updater', 'renameHook'); |
|
41 | - \OCP\Util::connectHook('OC_Filesystem', 'post_delete', '\OCA\Files_Sharing\Hooks', 'unshareChildren'); |
|
42 | - \OCP\Util::connectHook('OC_Appconfig', 'post_set_value', '\OCA\Files_Sharing\Maintainer', 'configChangeHook'); |
|
43 | - |
|
44 | - \OCP\Util::connectHook('OC_User', 'post_deleteUser', '\OCA\Files_Sharing\Hooks', 'deleteUser'); |
|
45 | - } |
|
46 | - |
|
47 | - /** |
|
48 | - * Sets up the filesystem and user for public sharing |
|
49 | - * @param string $token string share token |
|
50 | - * @param string $relativePath optional path relative to the share |
|
51 | - * @param string $password optional password |
|
52 | - * @return array |
|
53 | - */ |
|
54 | - public static function setupFromToken($token, $relativePath = null, $password = null) { |
|
55 | - \OC_User::setIncognitoMode(true); |
|
56 | - |
|
57 | - $shareManager = \OC::$server->getShareManager(); |
|
58 | - |
|
59 | - try { |
|
60 | - $share = $shareManager->getShareByToken($token); |
|
61 | - } catch (ShareNotFound $e) { |
|
62 | - \OC_Response::setStatus(404); |
|
63 | - \OCP\Util::writeLog('core-preview', 'Passed token parameter is not valid', \OCP\Util::DEBUG); |
|
64 | - exit; |
|
65 | - } |
|
66 | - |
|
67 | - \OCP\JSON::checkUserExists($share->getShareOwner()); |
|
68 | - \OC_Util::tearDownFS(); |
|
69 | - \OC_Util::setupFS($share->getShareOwner()); |
|
70 | - |
|
71 | - |
|
72 | - try { |
|
73 | - $path = Filesystem::getPath($share->getNodeId()); |
|
74 | - } catch (NotFoundException $e) { |
|
75 | - \OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); |
|
76 | - \OC_Response::setStatus(404); |
|
77 | - \OCP\JSON::error(array('success' => false)); |
|
78 | - exit(); |
|
79 | - } |
|
80 | - |
|
81 | - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK && $share->getPassword() !== null) { |
|
82 | - if (!self::authenticate($share, $password)) { |
|
83 | - \OC_Response::setStatus(403); |
|
84 | - \OCP\JSON::error(array('success' => false)); |
|
85 | - exit(); |
|
86 | - } |
|
87 | - } |
|
88 | - |
|
89 | - $basePath = $path; |
|
90 | - |
|
91 | - if ($relativePath !== null && Filesystem::isReadable($basePath . $relativePath)) { |
|
92 | - $path .= Filesystem::normalizePath($relativePath); |
|
93 | - } |
|
94 | - |
|
95 | - return array( |
|
96 | - 'share' => $share, |
|
97 | - 'basePath' => $basePath, |
|
98 | - 'realPath' => $path |
|
99 | - ); |
|
100 | - } |
|
101 | - |
|
102 | - /** |
|
103 | - * Authenticate link item with the given password |
|
104 | - * or with the session if no password was given. |
|
105 | - * @param \OCP\Share\IShare $share |
|
106 | - * @param string $password optional password |
|
107 | - * |
|
108 | - * @return boolean true if authorized, false otherwise |
|
109 | - */ |
|
110 | - public static function authenticate($share, $password = null) { |
|
111 | - $shareManager = \OC::$server->getShareManager(); |
|
112 | - |
|
113 | - if ($password !== null) { |
|
114 | - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { |
|
115 | - if ($shareManager->checkPassword($share, $password)) { |
|
116 | - \OC::$server->getSession()->set('public_link_authenticated', (string)$share->getId()); |
|
117 | - return true; |
|
118 | - } |
|
119 | - } |
|
120 | - } else { |
|
121 | - // not authenticated ? |
|
122 | - if (\OC::$server->getSession()->exists('public_link_authenticated') |
|
123 | - && \OC::$server->getSession()->get('public_link_authenticated') !== (string)$share->getId()) { |
|
124 | - return true; |
|
125 | - } |
|
126 | - } |
|
127 | - return false; |
|
128 | - } |
|
129 | - |
|
130 | - public static function getSharesFromItem($target) { |
|
131 | - $result = array(); |
|
132 | - $owner = Filesystem::getOwner($target); |
|
133 | - Filesystem::initMountPoints($owner); |
|
134 | - $info = Filesystem::getFileInfo($target); |
|
135 | - $ownerView = new View('/'.$owner.'/files'); |
|
136 | - if ( $owner != User::getUser() ) { |
|
137 | - $path = $ownerView->getPath($info['fileid']); |
|
138 | - } else { |
|
139 | - $path = $target; |
|
140 | - } |
|
141 | - |
|
142 | - |
|
143 | - $ids = array(); |
|
144 | - while ($path !== dirname($path)) { |
|
145 | - $info = $ownerView->getFileInfo($path); |
|
146 | - if ($info instanceof \OC\Files\FileInfo) { |
|
147 | - $ids[] = $info['fileid']; |
|
148 | - } else { |
|
149 | - \OCP\Util::writeLog('sharing', 'No fileinfo available for: ' . $path, \OCP\Util::WARN); |
|
150 | - } |
|
151 | - $path = dirname($path); |
|
152 | - } |
|
153 | - |
|
154 | - if (!empty($ids)) { |
|
155 | - |
|
156 | - $idList = array_chunk($ids, 99, true); |
|
157 | - |
|
158 | - foreach ($idList as $subList) { |
|
159 | - $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (" . implode(',', $subList) . ") AND `share_type` IN (0, 1, 2)"; |
|
160 | - $query = \OCP\DB::prepare($statement); |
|
161 | - $r = $query->execute(); |
|
162 | - $result = array_merge($result, $r->fetchAll()); |
|
163 | - } |
|
164 | - } |
|
165 | - |
|
166 | - return $result; |
|
167 | - } |
|
168 | - |
|
169 | - /** |
|
170 | - * get the UID of the owner of the file and the path to the file relative to |
|
171 | - * owners files folder |
|
172 | - * |
|
173 | - * @param $filename |
|
174 | - * @return array |
|
175 | - * @throws \OC\User\NoUserException |
|
176 | - */ |
|
177 | - public static function getUidAndFilename($filename) { |
|
178 | - $uid = Filesystem::getOwner($filename); |
|
179 | - $userManager = \OC::$server->getUserManager(); |
|
180 | - // if the user with the UID doesn't exists, e.g. because the UID points |
|
181 | - // to a remote user with a federated cloud ID we use the current logged-in |
|
182 | - // user. We need a valid local user to create the share |
|
183 | - if (!$userManager->userExists($uid)) { |
|
184 | - $uid = User::getUser(); |
|
185 | - } |
|
186 | - Filesystem::initMountPoints($uid); |
|
187 | - if ( $uid != User::getUser() ) { |
|
188 | - $info = Filesystem::getFileInfo($filename); |
|
189 | - $ownerView = new View('/'.$uid.'/files'); |
|
190 | - try { |
|
191 | - $filename = $ownerView->getPath($info['fileid']); |
|
192 | - } catch (NotFoundException $e) { |
|
193 | - $filename = null; |
|
194 | - } |
|
195 | - } |
|
196 | - return [$uid, $filename]; |
|
197 | - } |
|
198 | - |
|
199 | - /** |
|
200 | - * Format a path to be relative to the /user/files/ directory |
|
201 | - * @param string $path the absolute path |
|
202 | - * @return string e.g. turns '/admin/files/test.txt' into 'test.txt' |
|
203 | - */ |
|
204 | - public static function stripUserFilesPath($path) { |
|
205 | - $trimmed = ltrim($path, '/'); |
|
206 | - $split = explode('/', $trimmed); |
|
207 | - |
|
208 | - // it is not a file relative to data/user/files |
|
209 | - if (count($split) < 3 || $split[1] !== 'files') { |
|
210 | - return false; |
|
211 | - } |
|
212 | - |
|
213 | - $sliced = array_slice($split, 2); |
|
214 | - $relPath = implode('/', $sliced); |
|
215 | - |
|
216 | - return $relPath; |
|
217 | - } |
|
218 | - |
|
219 | - /** |
|
220 | - * check if file name already exists and generate unique target |
|
221 | - * |
|
222 | - * @param string $path |
|
223 | - * @param array $excludeList |
|
224 | - * @param View $view |
|
225 | - * @return string $path |
|
226 | - */ |
|
227 | - public static function generateUniqueTarget($path, $excludeList, $view) { |
|
228 | - $pathinfo = pathinfo($path); |
|
229 | - $ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : ''; |
|
230 | - $name = $pathinfo['filename']; |
|
231 | - $dir = $pathinfo['dirname']; |
|
232 | - $i = 2; |
|
233 | - while ($view->file_exists($path) || in_array($path, $excludeList)) { |
|
234 | - $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); |
|
235 | - $i++; |
|
236 | - } |
|
237 | - |
|
238 | - return $path; |
|
239 | - } |
|
240 | - |
|
241 | - /** |
|
242 | - * get default share folder |
|
243 | - * |
|
244 | - * @param \OC\Files\View |
|
245 | - * @return string |
|
246 | - */ |
|
247 | - public static function getShareFolder($view = null) { |
|
248 | - if ($view === null) { |
|
249 | - $view = Filesystem::getView(); |
|
250 | - } |
|
251 | - $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/'); |
|
252 | - $shareFolder = Filesystem::normalizePath($shareFolder); |
|
253 | - |
|
254 | - if (!$view->file_exists($shareFolder)) { |
|
255 | - $dir = ''; |
|
256 | - $subdirs = explode('/', $shareFolder); |
|
257 | - foreach ($subdirs as $subdir) { |
|
258 | - $dir = $dir . '/' . $subdir; |
|
259 | - if (!$view->is_dir($dir)) { |
|
260 | - $view->mkdir($dir); |
|
261 | - } |
|
262 | - } |
|
263 | - } |
|
264 | - |
|
265 | - return $shareFolder; |
|
266 | - |
|
267 | - } |
|
268 | - |
|
269 | - /** |
|
270 | - * set default share folder |
|
271 | - * |
|
272 | - * @param string $shareFolder |
|
273 | - */ |
|
274 | - public static function setShareFolder($shareFolder) { |
|
275 | - \OC::$server->getConfig()->setSystemValue('share_folder', $shareFolder); |
|
276 | - } |
|
39 | + public static function registerHooks() { |
|
40 | + \OCP\Util::connectHook('OC_Filesystem', 'post_rename', '\OCA\Files_Sharing\Updater', 'renameHook'); |
|
41 | + \OCP\Util::connectHook('OC_Filesystem', 'post_delete', '\OCA\Files_Sharing\Hooks', 'unshareChildren'); |
|
42 | + \OCP\Util::connectHook('OC_Appconfig', 'post_set_value', '\OCA\Files_Sharing\Maintainer', 'configChangeHook'); |
|
43 | + |
|
44 | + \OCP\Util::connectHook('OC_User', 'post_deleteUser', '\OCA\Files_Sharing\Hooks', 'deleteUser'); |
|
45 | + } |
|
46 | + |
|
47 | + /** |
|
48 | + * Sets up the filesystem and user for public sharing |
|
49 | + * @param string $token string share token |
|
50 | + * @param string $relativePath optional path relative to the share |
|
51 | + * @param string $password optional password |
|
52 | + * @return array |
|
53 | + */ |
|
54 | + public static function setupFromToken($token, $relativePath = null, $password = null) { |
|
55 | + \OC_User::setIncognitoMode(true); |
|
56 | + |
|
57 | + $shareManager = \OC::$server->getShareManager(); |
|
58 | + |
|
59 | + try { |
|
60 | + $share = $shareManager->getShareByToken($token); |
|
61 | + } catch (ShareNotFound $e) { |
|
62 | + \OC_Response::setStatus(404); |
|
63 | + \OCP\Util::writeLog('core-preview', 'Passed token parameter is not valid', \OCP\Util::DEBUG); |
|
64 | + exit; |
|
65 | + } |
|
66 | + |
|
67 | + \OCP\JSON::checkUserExists($share->getShareOwner()); |
|
68 | + \OC_Util::tearDownFS(); |
|
69 | + \OC_Util::setupFS($share->getShareOwner()); |
|
70 | + |
|
71 | + |
|
72 | + try { |
|
73 | + $path = Filesystem::getPath($share->getNodeId()); |
|
74 | + } catch (NotFoundException $e) { |
|
75 | + \OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); |
|
76 | + \OC_Response::setStatus(404); |
|
77 | + \OCP\JSON::error(array('success' => false)); |
|
78 | + exit(); |
|
79 | + } |
|
80 | + |
|
81 | + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK && $share->getPassword() !== null) { |
|
82 | + if (!self::authenticate($share, $password)) { |
|
83 | + \OC_Response::setStatus(403); |
|
84 | + \OCP\JSON::error(array('success' => false)); |
|
85 | + exit(); |
|
86 | + } |
|
87 | + } |
|
88 | + |
|
89 | + $basePath = $path; |
|
90 | + |
|
91 | + if ($relativePath !== null && Filesystem::isReadable($basePath . $relativePath)) { |
|
92 | + $path .= Filesystem::normalizePath($relativePath); |
|
93 | + } |
|
94 | + |
|
95 | + return array( |
|
96 | + 'share' => $share, |
|
97 | + 'basePath' => $basePath, |
|
98 | + 'realPath' => $path |
|
99 | + ); |
|
100 | + } |
|
101 | + |
|
102 | + /** |
|
103 | + * Authenticate link item with the given password |
|
104 | + * or with the session if no password was given. |
|
105 | + * @param \OCP\Share\IShare $share |
|
106 | + * @param string $password optional password |
|
107 | + * |
|
108 | + * @return boolean true if authorized, false otherwise |
|
109 | + */ |
|
110 | + public static function authenticate($share, $password = null) { |
|
111 | + $shareManager = \OC::$server->getShareManager(); |
|
112 | + |
|
113 | + if ($password !== null) { |
|
114 | + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { |
|
115 | + if ($shareManager->checkPassword($share, $password)) { |
|
116 | + \OC::$server->getSession()->set('public_link_authenticated', (string)$share->getId()); |
|
117 | + return true; |
|
118 | + } |
|
119 | + } |
|
120 | + } else { |
|
121 | + // not authenticated ? |
|
122 | + if (\OC::$server->getSession()->exists('public_link_authenticated') |
|
123 | + && \OC::$server->getSession()->get('public_link_authenticated') !== (string)$share->getId()) { |
|
124 | + return true; |
|
125 | + } |
|
126 | + } |
|
127 | + return false; |
|
128 | + } |
|
129 | + |
|
130 | + public static function getSharesFromItem($target) { |
|
131 | + $result = array(); |
|
132 | + $owner = Filesystem::getOwner($target); |
|
133 | + Filesystem::initMountPoints($owner); |
|
134 | + $info = Filesystem::getFileInfo($target); |
|
135 | + $ownerView = new View('/'.$owner.'/files'); |
|
136 | + if ( $owner != User::getUser() ) { |
|
137 | + $path = $ownerView->getPath($info['fileid']); |
|
138 | + } else { |
|
139 | + $path = $target; |
|
140 | + } |
|
141 | + |
|
142 | + |
|
143 | + $ids = array(); |
|
144 | + while ($path !== dirname($path)) { |
|
145 | + $info = $ownerView->getFileInfo($path); |
|
146 | + if ($info instanceof \OC\Files\FileInfo) { |
|
147 | + $ids[] = $info['fileid']; |
|
148 | + } else { |
|
149 | + \OCP\Util::writeLog('sharing', 'No fileinfo available for: ' . $path, \OCP\Util::WARN); |
|
150 | + } |
|
151 | + $path = dirname($path); |
|
152 | + } |
|
153 | + |
|
154 | + if (!empty($ids)) { |
|
155 | + |
|
156 | + $idList = array_chunk($ids, 99, true); |
|
157 | + |
|
158 | + foreach ($idList as $subList) { |
|
159 | + $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (" . implode(',', $subList) . ") AND `share_type` IN (0, 1, 2)"; |
|
160 | + $query = \OCP\DB::prepare($statement); |
|
161 | + $r = $query->execute(); |
|
162 | + $result = array_merge($result, $r->fetchAll()); |
|
163 | + } |
|
164 | + } |
|
165 | + |
|
166 | + return $result; |
|
167 | + } |
|
168 | + |
|
169 | + /** |
|
170 | + * get the UID of the owner of the file and the path to the file relative to |
|
171 | + * owners files folder |
|
172 | + * |
|
173 | + * @param $filename |
|
174 | + * @return array |
|
175 | + * @throws \OC\User\NoUserException |
|
176 | + */ |
|
177 | + public static function getUidAndFilename($filename) { |
|
178 | + $uid = Filesystem::getOwner($filename); |
|
179 | + $userManager = \OC::$server->getUserManager(); |
|
180 | + // if the user with the UID doesn't exists, e.g. because the UID points |
|
181 | + // to a remote user with a federated cloud ID we use the current logged-in |
|
182 | + // user. We need a valid local user to create the share |
|
183 | + if (!$userManager->userExists($uid)) { |
|
184 | + $uid = User::getUser(); |
|
185 | + } |
|
186 | + Filesystem::initMountPoints($uid); |
|
187 | + if ( $uid != User::getUser() ) { |
|
188 | + $info = Filesystem::getFileInfo($filename); |
|
189 | + $ownerView = new View('/'.$uid.'/files'); |
|
190 | + try { |
|
191 | + $filename = $ownerView->getPath($info['fileid']); |
|
192 | + } catch (NotFoundException $e) { |
|
193 | + $filename = null; |
|
194 | + } |
|
195 | + } |
|
196 | + return [$uid, $filename]; |
|
197 | + } |
|
198 | + |
|
199 | + /** |
|
200 | + * Format a path to be relative to the /user/files/ directory |
|
201 | + * @param string $path the absolute path |
|
202 | + * @return string e.g. turns '/admin/files/test.txt' into 'test.txt' |
|
203 | + */ |
|
204 | + public static function stripUserFilesPath($path) { |
|
205 | + $trimmed = ltrim($path, '/'); |
|
206 | + $split = explode('/', $trimmed); |
|
207 | + |
|
208 | + // it is not a file relative to data/user/files |
|
209 | + if (count($split) < 3 || $split[1] !== 'files') { |
|
210 | + return false; |
|
211 | + } |
|
212 | + |
|
213 | + $sliced = array_slice($split, 2); |
|
214 | + $relPath = implode('/', $sliced); |
|
215 | + |
|
216 | + return $relPath; |
|
217 | + } |
|
218 | + |
|
219 | + /** |
|
220 | + * check if file name already exists and generate unique target |
|
221 | + * |
|
222 | + * @param string $path |
|
223 | + * @param array $excludeList |
|
224 | + * @param View $view |
|
225 | + * @return string $path |
|
226 | + */ |
|
227 | + public static function generateUniqueTarget($path, $excludeList, $view) { |
|
228 | + $pathinfo = pathinfo($path); |
|
229 | + $ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : ''; |
|
230 | + $name = $pathinfo['filename']; |
|
231 | + $dir = $pathinfo['dirname']; |
|
232 | + $i = 2; |
|
233 | + while ($view->file_exists($path) || in_array($path, $excludeList)) { |
|
234 | + $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); |
|
235 | + $i++; |
|
236 | + } |
|
237 | + |
|
238 | + return $path; |
|
239 | + } |
|
240 | + |
|
241 | + /** |
|
242 | + * get default share folder |
|
243 | + * |
|
244 | + * @param \OC\Files\View |
|
245 | + * @return string |
|
246 | + */ |
|
247 | + public static function getShareFolder($view = null) { |
|
248 | + if ($view === null) { |
|
249 | + $view = Filesystem::getView(); |
|
250 | + } |
|
251 | + $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/'); |
|
252 | + $shareFolder = Filesystem::normalizePath($shareFolder); |
|
253 | + |
|
254 | + if (!$view->file_exists($shareFolder)) { |
|
255 | + $dir = ''; |
|
256 | + $subdirs = explode('/', $shareFolder); |
|
257 | + foreach ($subdirs as $subdir) { |
|
258 | + $dir = $dir . '/' . $subdir; |
|
259 | + if (!$view->is_dir($dir)) { |
|
260 | + $view->mkdir($dir); |
|
261 | + } |
|
262 | + } |
|
263 | + } |
|
264 | + |
|
265 | + return $shareFolder; |
|
266 | + |
|
267 | + } |
|
268 | + |
|
269 | + /** |
|
270 | + * set default share folder |
|
271 | + * |
|
272 | + * @param string $shareFolder |
|
273 | + */ |
|
274 | + public static function setShareFolder($shareFolder) { |
|
275 | + \OC::$server->getConfig()->setSystemValue('share_folder', $shareFolder); |
|
276 | + } |
|
277 | 277 | |
278 | 278 | } |
@@ -273,6 +273,10 @@ discard block |
||
273 | 273 | return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; |
274 | 274 | } |
275 | 275 | |
276 | + /** |
|
277 | + * @param integer $step |
|
278 | + * @param integer $max |
|
279 | + */ |
|
276 | 280 | protected function emit($sql, $step, $max) { |
277 | 281 | if ($this->noEmit) { |
278 | 282 | return; |
@@ -283,6 +287,10 @@ discard block |
||
283 | 287 | $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max])); |
284 | 288 | } |
285 | 289 | |
290 | + /** |
|
291 | + * @param integer $step |
|
292 | + * @param integer $max |
|
293 | + */ |
|
286 | 294 | private function emitCheckStep($tableName, $step, $max) { |
287 | 295 | if(is_null($this->dispatcher)) { |
288 | 296 | return; |
@@ -43,271 +43,271 @@ |
||
43 | 43 | |
44 | 44 | class Migrator { |
45 | 45 | |
46 | - /** |
|
47 | - * @var \Doctrine\DBAL\Connection $connection |
|
48 | - */ |
|
49 | - protected $connection; |
|
50 | - |
|
51 | - /** |
|
52 | - * @var ISecureRandom |
|
53 | - */ |
|
54 | - private $random; |
|
55 | - |
|
56 | - /** @var IConfig */ |
|
57 | - protected $config; |
|
58 | - |
|
59 | - /** @var EventDispatcher */ |
|
60 | - private $dispatcher; |
|
61 | - |
|
62 | - /** @var bool */ |
|
63 | - private $noEmit = false; |
|
64 | - |
|
65 | - /** |
|
66 | - * @param \Doctrine\DBAL\Connection|Connection $connection |
|
67 | - * @param ISecureRandom $random |
|
68 | - * @param IConfig $config |
|
69 | - * @param EventDispatcher $dispatcher |
|
70 | - */ |
|
71 | - public function __construct(\Doctrine\DBAL\Connection $connection, |
|
72 | - ISecureRandom $random, |
|
73 | - IConfig $config, |
|
74 | - EventDispatcher $dispatcher = null) { |
|
75 | - $this->connection = $connection; |
|
76 | - $this->random = $random; |
|
77 | - $this->config = $config; |
|
78 | - $this->dispatcher = $dispatcher; |
|
79 | - } |
|
80 | - |
|
81 | - /** |
|
82 | - * @param \Doctrine\DBAL\Schema\Schema $targetSchema |
|
83 | - */ |
|
84 | - public function migrate(Schema $targetSchema) { |
|
85 | - $this->noEmit = true; |
|
86 | - $this->applySchema($targetSchema); |
|
87 | - } |
|
88 | - |
|
89 | - /** |
|
90 | - * @param \Doctrine\DBAL\Schema\Schema $targetSchema |
|
91 | - * @return string |
|
92 | - */ |
|
93 | - public function generateChangeScript(Schema $targetSchema) { |
|
94 | - $schemaDiff = $this->getDiff($targetSchema, $this->connection); |
|
95 | - |
|
96 | - $script = ''; |
|
97 | - $sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform()); |
|
98 | - foreach ($sqls as $sql) { |
|
99 | - $script .= $this->convertStatementToScript($sql); |
|
100 | - } |
|
101 | - |
|
102 | - return $script; |
|
103 | - } |
|
104 | - |
|
105 | - /** |
|
106 | - * @param Schema $targetSchema |
|
107 | - * @throws \OC\DB\MigrationException |
|
108 | - */ |
|
109 | - public function checkMigrate(Schema $targetSchema) { |
|
110 | - $this->noEmit = true; |
|
111 | - /**@var \Doctrine\DBAL\Schema\Table[] $tables */ |
|
112 | - $tables = $targetSchema->getTables(); |
|
113 | - $filterExpression = $this->getFilterExpression(); |
|
114 | - $this->connection->getConfiguration()-> |
|
115 | - setFilterSchemaAssetsExpression($filterExpression); |
|
116 | - $existingTables = $this->connection->getSchemaManager()->listTableNames(); |
|
117 | - |
|
118 | - $step = 0; |
|
119 | - foreach ($tables as $table) { |
|
120 | - if (strpos($table->getName(), '.')) { |
|
121 | - list(, $tableName) = explode('.', $table->getName()); |
|
122 | - } else { |
|
123 | - $tableName = $table->getName(); |
|
124 | - } |
|
125 | - $this->emitCheckStep($tableName, $step++, count($tables)); |
|
126 | - // don't need to check for new tables |
|
127 | - if (array_search($tableName, $existingTables) !== false) { |
|
128 | - $this->checkTableMigrate($table); |
|
129 | - } |
|
130 | - } |
|
131 | - } |
|
132 | - |
|
133 | - /** |
|
134 | - * Create a unique name for the temporary table |
|
135 | - * |
|
136 | - * @param string $name |
|
137 | - * @return string |
|
138 | - */ |
|
139 | - protected function generateTemporaryTableName($name) { |
|
140 | - return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS); |
|
141 | - } |
|
142 | - |
|
143 | - /** |
|
144 | - * Check the migration of a table on a copy so we can detect errors before messing with the real table |
|
145 | - * |
|
146 | - * @param \Doctrine\DBAL\Schema\Table $table |
|
147 | - * @throws \OC\DB\MigrationException |
|
148 | - */ |
|
149 | - protected function checkTableMigrate(Table $table) { |
|
150 | - $name = $table->getName(); |
|
151 | - $tmpName = $this->generateTemporaryTableName($name); |
|
152 | - |
|
153 | - $this->copyTable($name, $tmpName); |
|
154 | - |
|
155 | - //create the migration schema for the temporary table |
|
156 | - $tmpTable = $this->renameTableSchema($table, $tmpName); |
|
157 | - $schemaConfig = new SchemaConfig(); |
|
158 | - $schemaConfig->setName($this->connection->getDatabase()); |
|
159 | - $schema = new Schema(array($tmpTable), array(), $schemaConfig); |
|
160 | - |
|
161 | - try { |
|
162 | - $this->applySchema($schema); |
|
163 | - $this->dropTable($tmpName); |
|
164 | - } catch (DBALException $e) { |
|
165 | - // pgsql needs to commit it's failed transaction before doing anything else |
|
166 | - if ($this->connection->isTransactionActive()) { |
|
167 | - $this->connection->commit(); |
|
168 | - } |
|
169 | - $this->dropTable($tmpName); |
|
170 | - throw new MigrationException($table->getName(), $e->getMessage()); |
|
171 | - } |
|
172 | - } |
|
173 | - |
|
174 | - /** |
|
175 | - * @param \Doctrine\DBAL\Schema\Table $table |
|
176 | - * @param string $newName |
|
177 | - * @return \Doctrine\DBAL\Schema\Table |
|
178 | - */ |
|
179 | - protected function renameTableSchema(Table $table, $newName) { |
|
180 | - /** |
|
181 | - * @var \Doctrine\DBAL\Schema\Index[] $indexes |
|
182 | - */ |
|
183 | - $indexes = $table->getIndexes(); |
|
184 | - $newIndexes = array(); |
|
185 | - foreach ($indexes as $index) { |
|
186 | - if ($index->isPrimary()) { |
|
187 | - // do not rename primary key |
|
188 | - $indexName = $index->getName(); |
|
189 | - } else { |
|
190 | - // avoid conflicts in index names |
|
191 | - $indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER); |
|
192 | - } |
|
193 | - $newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary()); |
|
194 | - } |
|
195 | - |
|
196 | - // foreign keys are not supported so we just set it to an empty array |
|
197 | - return new Table($newName, $table->getColumns(), $newIndexes, array(), 0, $table->getOptions()); |
|
198 | - } |
|
199 | - |
|
200 | - /** |
|
201 | - * @param Schema $targetSchema |
|
202 | - * @param \Doctrine\DBAL\Connection $connection |
|
203 | - * @return \Doctrine\DBAL\Schema\SchemaDiff |
|
204 | - * @throws DBALException |
|
205 | - */ |
|
206 | - protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { |
|
207 | - // adjust varchar columns with a length higher then getVarcharMaxLength to clob |
|
208 | - foreach ($targetSchema->getTables() as $table) { |
|
209 | - foreach ($table->getColumns() as $column) { |
|
210 | - if ($column->getType() instanceof StringType) { |
|
211 | - if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) { |
|
212 | - $column->setType(Type::getType('text')); |
|
213 | - $column->setLength(null); |
|
214 | - } |
|
215 | - } |
|
216 | - } |
|
217 | - } |
|
218 | - |
|
219 | - $filterExpression = $this->getFilterExpression(); |
|
220 | - $this->connection->getConfiguration()-> |
|
221 | - setFilterSchemaAssetsExpression($filterExpression); |
|
222 | - $sourceSchema = $connection->getSchemaManager()->createSchema(); |
|
223 | - |
|
224 | - // remove tables we don't know about |
|
225 | - /** @var $table \Doctrine\DBAL\Schema\Table */ |
|
226 | - foreach ($sourceSchema->getTables() as $table) { |
|
227 | - if (!$targetSchema->hasTable($table->getName())) { |
|
228 | - $sourceSchema->dropTable($table->getName()); |
|
229 | - } |
|
230 | - } |
|
231 | - // remove sequences we don't know about |
|
232 | - foreach ($sourceSchema->getSequences() as $table) { |
|
233 | - if (!$targetSchema->hasSequence($table->getName())) { |
|
234 | - $sourceSchema->dropSequence($table->getName()); |
|
235 | - } |
|
236 | - } |
|
237 | - |
|
238 | - $comparator = new Comparator(); |
|
239 | - return $comparator->compare($sourceSchema, $targetSchema); |
|
240 | - } |
|
241 | - |
|
242 | - /** |
|
243 | - * @param \Doctrine\DBAL\Schema\Schema $targetSchema |
|
244 | - * @param \Doctrine\DBAL\Connection $connection |
|
245 | - */ |
|
246 | - protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) { |
|
247 | - if (is_null($connection)) { |
|
248 | - $connection = $this->connection; |
|
249 | - } |
|
250 | - |
|
251 | - $schemaDiff = $this->getDiff($targetSchema, $connection); |
|
252 | - |
|
253 | - $connection->beginTransaction(); |
|
254 | - $sqls = $schemaDiff->toSql($connection->getDatabasePlatform()); |
|
255 | - $step = 0; |
|
256 | - foreach ($sqls as $sql) { |
|
257 | - $this->emit($sql, $step++, count($sqls)); |
|
258 | - $connection->query($sql); |
|
259 | - } |
|
260 | - $connection->commit(); |
|
261 | - } |
|
262 | - |
|
263 | - /** |
|
264 | - * @param string $sourceName |
|
265 | - * @param string $targetName |
|
266 | - */ |
|
267 | - protected function copyTable($sourceName, $targetName) { |
|
268 | - $quotedSource = $this->connection->quoteIdentifier($sourceName); |
|
269 | - $quotedTarget = $this->connection->quoteIdentifier($targetName); |
|
270 | - |
|
271 | - $this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')'); |
|
272 | - $this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource); |
|
273 | - } |
|
274 | - |
|
275 | - /** |
|
276 | - * @param string $name |
|
277 | - */ |
|
278 | - protected function dropTable($name) { |
|
279 | - $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name)); |
|
280 | - } |
|
281 | - |
|
282 | - /** |
|
283 | - * @param $statement |
|
284 | - * @return string |
|
285 | - */ |
|
286 | - protected function convertStatementToScript($statement) { |
|
287 | - $script = $statement . ';'; |
|
288 | - $script .= PHP_EOL; |
|
289 | - $script .= PHP_EOL; |
|
290 | - return $script; |
|
291 | - } |
|
292 | - |
|
293 | - protected function getFilterExpression() { |
|
294 | - return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; |
|
295 | - } |
|
296 | - |
|
297 | - protected function emit($sql, $step, $max) { |
|
298 | - if ($this->noEmit) { |
|
299 | - return; |
|
300 | - } |
|
301 | - if(is_null($this->dispatcher)) { |
|
302 | - return; |
|
303 | - } |
|
304 | - $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max])); |
|
305 | - } |
|
306 | - |
|
307 | - private function emitCheckStep($tableName, $step, $max) { |
|
308 | - if(is_null($this->dispatcher)) { |
|
309 | - return; |
|
310 | - } |
|
311 | - $this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step+1, $max])); |
|
312 | - } |
|
46 | + /** |
|
47 | + * @var \Doctrine\DBAL\Connection $connection |
|
48 | + */ |
|
49 | + protected $connection; |
|
50 | + |
|
51 | + /** |
|
52 | + * @var ISecureRandom |
|
53 | + */ |
|
54 | + private $random; |
|
55 | + |
|
56 | + /** @var IConfig */ |
|
57 | + protected $config; |
|
58 | + |
|
59 | + /** @var EventDispatcher */ |
|
60 | + private $dispatcher; |
|
61 | + |
|
62 | + /** @var bool */ |
|
63 | + private $noEmit = false; |
|
64 | + |
|
65 | + /** |
|
66 | + * @param \Doctrine\DBAL\Connection|Connection $connection |
|
67 | + * @param ISecureRandom $random |
|
68 | + * @param IConfig $config |
|
69 | + * @param EventDispatcher $dispatcher |
|
70 | + */ |
|
71 | + public function __construct(\Doctrine\DBAL\Connection $connection, |
|
72 | + ISecureRandom $random, |
|
73 | + IConfig $config, |
|
74 | + EventDispatcher $dispatcher = null) { |
|
75 | + $this->connection = $connection; |
|
76 | + $this->random = $random; |
|
77 | + $this->config = $config; |
|
78 | + $this->dispatcher = $dispatcher; |
|
79 | + } |
|
80 | + |
|
81 | + /** |
|
82 | + * @param \Doctrine\DBAL\Schema\Schema $targetSchema |
|
83 | + */ |
|
84 | + public function migrate(Schema $targetSchema) { |
|
85 | + $this->noEmit = true; |
|
86 | + $this->applySchema($targetSchema); |
|
87 | + } |
|
88 | + |
|
89 | + /** |
|
90 | + * @param \Doctrine\DBAL\Schema\Schema $targetSchema |
|
91 | + * @return string |
|
92 | + */ |
|
93 | + public function generateChangeScript(Schema $targetSchema) { |
|
94 | + $schemaDiff = $this->getDiff($targetSchema, $this->connection); |
|
95 | + |
|
96 | + $script = ''; |
|
97 | + $sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform()); |
|
98 | + foreach ($sqls as $sql) { |
|
99 | + $script .= $this->convertStatementToScript($sql); |
|
100 | + } |
|
101 | + |
|
102 | + return $script; |
|
103 | + } |
|
104 | + |
|
105 | + /** |
|
106 | + * @param Schema $targetSchema |
|
107 | + * @throws \OC\DB\MigrationException |
|
108 | + */ |
|
109 | + public function checkMigrate(Schema $targetSchema) { |
|
110 | + $this->noEmit = true; |
|
111 | + /**@var \Doctrine\DBAL\Schema\Table[] $tables */ |
|
112 | + $tables = $targetSchema->getTables(); |
|
113 | + $filterExpression = $this->getFilterExpression(); |
|
114 | + $this->connection->getConfiguration()-> |
|
115 | + setFilterSchemaAssetsExpression($filterExpression); |
|
116 | + $existingTables = $this->connection->getSchemaManager()->listTableNames(); |
|
117 | + |
|
118 | + $step = 0; |
|
119 | + foreach ($tables as $table) { |
|
120 | + if (strpos($table->getName(), '.')) { |
|
121 | + list(, $tableName) = explode('.', $table->getName()); |
|
122 | + } else { |
|
123 | + $tableName = $table->getName(); |
|
124 | + } |
|
125 | + $this->emitCheckStep($tableName, $step++, count($tables)); |
|
126 | + // don't need to check for new tables |
|
127 | + if (array_search($tableName, $existingTables) !== false) { |
|
128 | + $this->checkTableMigrate($table); |
|
129 | + } |
|
130 | + } |
|
131 | + } |
|
132 | + |
|
133 | + /** |
|
134 | + * Create a unique name for the temporary table |
|
135 | + * |
|
136 | + * @param string $name |
|
137 | + * @return string |
|
138 | + */ |
|
139 | + protected function generateTemporaryTableName($name) { |
|
140 | + return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS); |
|
141 | + } |
|
142 | + |
|
143 | + /** |
|
144 | + * Check the migration of a table on a copy so we can detect errors before messing with the real table |
|
145 | + * |
|
146 | + * @param \Doctrine\DBAL\Schema\Table $table |
|
147 | + * @throws \OC\DB\MigrationException |
|
148 | + */ |
|
149 | + protected function checkTableMigrate(Table $table) { |
|
150 | + $name = $table->getName(); |
|
151 | + $tmpName = $this->generateTemporaryTableName($name); |
|
152 | + |
|
153 | + $this->copyTable($name, $tmpName); |
|
154 | + |
|
155 | + //create the migration schema for the temporary table |
|
156 | + $tmpTable = $this->renameTableSchema($table, $tmpName); |
|
157 | + $schemaConfig = new SchemaConfig(); |
|
158 | + $schemaConfig->setName($this->connection->getDatabase()); |
|
159 | + $schema = new Schema(array($tmpTable), array(), $schemaConfig); |
|
160 | + |
|
161 | + try { |
|
162 | + $this->applySchema($schema); |
|
163 | + $this->dropTable($tmpName); |
|
164 | + } catch (DBALException $e) { |
|
165 | + // pgsql needs to commit it's failed transaction before doing anything else |
|
166 | + if ($this->connection->isTransactionActive()) { |
|
167 | + $this->connection->commit(); |
|
168 | + } |
|
169 | + $this->dropTable($tmpName); |
|
170 | + throw new MigrationException($table->getName(), $e->getMessage()); |
|
171 | + } |
|
172 | + } |
|
173 | + |
|
174 | + /** |
|
175 | + * @param \Doctrine\DBAL\Schema\Table $table |
|
176 | + * @param string $newName |
|
177 | + * @return \Doctrine\DBAL\Schema\Table |
|
178 | + */ |
|
179 | + protected function renameTableSchema(Table $table, $newName) { |
|
180 | + /** |
|
181 | + * @var \Doctrine\DBAL\Schema\Index[] $indexes |
|
182 | + */ |
|
183 | + $indexes = $table->getIndexes(); |
|
184 | + $newIndexes = array(); |
|
185 | + foreach ($indexes as $index) { |
|
186 | + if ($index->isPrimary()) { |
|
187 | + // do not rename primary key |
|
188 | + $indexName = $index->getName(); |
|
189 | + } else { |
|
190 | + // avoid conflicts in index names |
|
191 | + $indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER); |
|
192 | + } |
|
193 | + $newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary()); |
|
194 | + } |
|
195 | + |
|
196 | + // foreign keys are not supported so we just set it to an empty array |
|
197 | + return new Table($newName, $table->getColumns(), $newIndexes, array(), 0, $table->getOptions()); |
|
198 | + } |
|
199 | + |
|
200 | + /** |
|
201 | + * @param Schema $targetSchema |
|
202 | + * @param \Doctrine\DBAL\Connection $connection |
|
203 | + * @return \Doctrine\DBAL\Schema\SchemaDiff |
|
204 | + * @throws DBALException |
|
205 | + */ |
|
206 | + protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { |
|
207 | + // adjust varchar columns with a length higher then getVarcharMaxLength to clob |
|
208 | + foreach ($targetSchema->getTables() as $table) { |
|
209 | + foreach ($table->getColumns() as $column) { |
|
210 | + if ($column->getType() instanceof StringType) { |
|
211 | + if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) { |
|
212 | + $column->setType(Type::getType('text')); |
|
213 | + $column->setLength(null); |
|
214 | + } |
|
215 | + } |
|
216 | + } |
|
217 | + } |
|
218 | + |
|
219 | + $filterExpression = $this->getFilterExpression(); |
|
220 | + $this->connection->getConfiguration()-> |
|
221 | + setFilterSchemaAssetsExpression($filterExpression); |
|
222 | + $sourceSchema = $connection->getSchemaManager()->createSchema(); |
|
223 | + |
|
224 | + // remove tables we don't know about |
|
225 | + /** @var $table \Doctrine\DBAL\Schema\Table */ |
|
226 | + foreach ($sourceSchema->getTables() as $table) { |
|
227 | + if (!$targetSchema->hasTable($table->getName())) { |
|
228 | + $sourceSchema->dropTable($table->getName()); |
|
229 | + } |
|
230 | + } |
|
231 | + // remove sequences we don't know about |
|
232 | + foreach ($sourceSchema->getSequences() as $table) { |
|
233 | + if (!$targetSchema->hasSequence($table->getName())) { |
|
234 | + $sourceSchema->dropSequence($table->getName()); |
|
235 | + } |
|
236 | + } |
|
237 | + |
|
238 | + $comparator = new Comparator(); |
|
239 | + return $comparator->compare($sourceSchema, $targetSchema); |
|
240 | + } |
|
241 | + |
|
242 | + /** |
|
243 | + * @param \Doctrine\DBAL\Schema\Schema $targetSchema |
|
244 | + * @param \Doctrine\DBAL\Connection $connection |
|
245 | + */ |
|
246 | + protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) { |
|
247 | + if (is_null($connection)) { |
|
248 | + $connection = $this->connection; |
|
249 | + } |
|
250 | + |
|
251 | + $schemaDiff = $this->getDiff($targetSchema, $connection); |
|
252 | + |
|
253 | + $connection->beginTransaction(); |
|
254 | + $sqls = $schemaDiff->toSql($connection->getDatabasePlatform()); |
|
255 | + $step = 0; |
|
256 | + foreach ($sqls as $sql) { |
|
257 | + $this->emit($sql, $step++, count($sqls)); |
|
258 | + $connection->query($sql); |
|
259 | + } |
|
260 | + $connection->commit(); |
|
261 | + } |
|
262 | + |
|
263 | + /** |
|
264 | + * @param string $sourceName |
|
265 | + * @param string $targetName |
|
266 | + */ |
|
267 | + protected function copyTable($sourceName, $targetName) { |
|
268 | + $quotedSource = $this->connection->quoteIdentifier($sourceName); |
|
269 | + $quotedTarget = $this->connection->quoteIdentifier($targetName); |
|
270 | + |
|
271 | + $this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')'); |
|
272 | + $this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource); |
|
273 | + } |
|
274 | + |
|
275 | + /** |
|
276 | + * @param string $name |
|
277 | + */ |
|
278 | + protected function dropTable($name) { |
|
279 | + $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name)); |
|
280 | + } |
|
281 | + |
|
282 | + /** |
|
283 | + * @param $statement |
|
284 | + * @return string |
|
285 | + */ |
|
286 | + protected function convertStatementToScript($statement) { |
|
287 | + $script = $statement . ';'; |
|
288 | + $script .= PHP_EOL; |
|
289 | + $script .= PHP_EOL; |
|
290 | + return $script; |
|
291 | + } |
|
292 | + |
|
293 | + protected function getFilterExpression() { |
|
294 | + return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; |
|
295 | + } |
|
296 | + |
|
297 | + protected function emit($sql, $step, $max) { |
|
298 | + if ($this->noEmit) { |
|
299 | + return; |
|
300 | + } |
|
301 | + if(is_null($this->dispatcher)) { |
|
302 | + return; |
|
303 | + } |
|
304 | + $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max])); |
|
305 | + } |
|
306 | + |
|
307 | + private function emitCheckStep($tableName, $step, $max) { |
|
308 | + if(is_null($this->dispatcher)) { |
|
309 | + return; |
|
310 | + } |
|
311 | + $this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step+1, $max])); |
|
312 | + } |
|
313 | 313 | } |
@@ -137,7 +137,7 @@ discard block |
||
137 | 137 | * @return string |
138 | 138 | */ |
139 | 139 | protected function generateTemporaryTableName($name) { |
140 | - return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS); |
|
140 | + return $this->config->getSystemValue('dbtableprefix', 'oc_').$name.'_'.$this->random->generate(13, ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS); |
|
141 | 141 | } |
142 | 142 | |
143 | 143 | /** |
@@ -188,7 +188,7 @@ discard block |
||
188 | 188 | $indexName = $index->getName(); |
189 | 189 | } else { |
190 | 190 | // avoid conflicts in index names |
191 | - $indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER); |
|
191 | + $indexName = $this->config->getSystemValue('dbtableprefix', 'oc_').$this->random->generate(13, ISecureRandom::CHAR_LOWER); |
|
192 | 192 | } |
193 | 193 | $newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary()); |
194 | 194 | } |
@@ -268,15 +268,15 @@ discard block |
||
268 | 268 | $quotedSource = $this->connection->quoteIdentifier($sourceName); |
269 | 269 | $quotedTarget = $this->connection->quoteIdentifier($targetName); |
270 | 270 | |
271 | - $this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')'); |
|
272 | - $this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource); |
|
271 | + $this->connection->exec('CREATE TABLE '.$quotedTarget.' (LIKE '.$quotedSource.')'); |
|
272 | + $this->connection->exec('INSERT INTO '.$quotedTarget.' SELECT * FROM '.$quotedSource); |
|
273 | 273 | } |
274 | 274 | |
275 | 275 | /** |
276 | 276 | * @param string $name |
277 | 277 | */ |
278 | 278 | protected function dropTable($name) { |
279 | - $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name)); |
|
279 | + $this->connection->exec('DROP TABLE '.$this->connection->quoteIdentifier($name)); |
|
280 | 280 | } |
281 | 281 | |
282 | 282 | /** |
@@ -284,30 +284,30 @@ discard block |
||
284 | 284 | * @return string |
285 | 285 | */ |
286 | 286 | protected function convertStatementToScript($statement) { |
287 | - $script = $statement . ';'; |
|
287 | + $script = $statement.';'; |
|
288 | 288 | $script .= PHP_EOL; |
289 | 289 | $script .= PHP_EOL; |
290 | 290 | return $script; |
291 | 291 | } |
292 | 292 | |
293 | 293 | protected function getFilterExpression() { |
294 | - return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; |
|
294 | + return '/^'.preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')).'/'; |
|
295 | 295 | } |
296 | 296 | |
297 | 297 | protected function emit($sql, $step, $max) { |
298 | 298 | if ($this->noEmit) { |
299 | 299 | return; |
300 | 300 | } |
301 | - if(is_null($this->dispatcher)) { |
|
301 | + if (is_null($this->dispatcher)) { |
|
302 | 302 | return; |
303 | 303 | } |
304 | - $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max])); |
|
304 | + $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step + 1, $max])); |
|
305 | 305 | } |
306 | 306 | |
307 | 307 | private function emitCheckStep($tableName, $step, $max) { |
308 | - if(is_null($this->dispatcher)) { |
|
308 | + if (is_null($this->dispatcher)) { |
|
309 | 309 | return; |
310 | 310 | } |
311 | - $this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step+1, $max])); |
|
311 | + $this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step + 1, $max])); |
|
312 | 312 | } |
313 | 313 | } |
@@ -27,13 +27,8 @@ |
||
27 | 27 | use OCA\Files_External\Lib\DefinitionParameter; |
28 | 28 | use OCA\Files_External\Service\BackendService; |
29 | 29 | use Symfony\Component\Console\Command\Command; |
30 | -use Symfony\Component\Console\Helper\Table; |
|
31 | -use Symfony\Component\Console\Helper\TableHelper; |
|
32 | -use Symfony\Component\Console\Input\ArrayInput; |
|
33 | 30 | use Symfony\Component\Console\Input\InputArgument; |
34 | 31 | use Symfony\Component\Console\Input\InputInterface; |
35 | -use Symfony\Component\Console\Input\InputOption; |
|
36 | -use Symfony\Component\Console\Input\Input; |
|
37 | 32 | use Symfony\Component\Console\Output\OutputInterface; |
38 | 33 | |
39 | 34 | class Backends extends Base { |
@@ -32,91 +32,91 @@ |
||
32 | 32 | use Symfony\Component\Console\Output\OutputInterface; |
33 | 33 | |
34 | 34 | class Backends extends Base { |
35 | - /** @var BackendService */ |
|
36 | - private $backendService; |
|
35 | + /** @var BackendService */ |
|
36 | + private $backendService; |
|
37 | 37 | |
38 | - function __construct(BackendService $backendService |
|
39 | - ) { |
|
40 | - parent::__construct(); |
|
38 | + function __construct(BackendService $backendService |
|
39 | + ) { |
|
40 | + parent::__construct(); |
|
41 | 41 | |
42 | - $this->backendService = $backendService; |
|
43 | - } |
|
42 | + $this->backendService = $backendService; |
|
43 | + } |
|
44 | 44 | |
45 | - protected function configure() { |
|
46 | - $this |
|
47 | - ->setName('files_external:backends') |
|
48 | - ->setDescription('Show available authentication and storage backends') |
|
49 | - ->addArgument( |
|
50 | - 'type', |
|
51 | - InputArgument::OPTIONAL, |
|
52 | - 'only show backends of a certain type. Possible values are "authentication" or "storage"' |
|
53 | - )->addArgument( |
|
54 | - 'backend', |
|
55 | - InputArgument::OPTIONAL, |
|
56 | - 'only show information of a specific backend' |
|
57 | - ); |
|
58 | - parent::configure(); |
|
59 | - } |
|
45 | + protected function configure() { |
|
46 | + $this |
|
47 | + ->setName('files_external:backends') |
|
48 | + ->setDescription('Show available authentication and storage backends') |
|
49 | + ->addArgument( |
|
50 | + 'type', |
|
51 | + InputArgument::OPTIONAL, |
|
52 | + 'only show backends of a certain type. Possible values are "authentication" or "storage"' |
|
53 | + )->addArgument( |
|
54 | + 'backend', |
|
55 | + InputArgument::OPTIONAL, |
|
56 | + 'only show information of a specific backend' |
|
57 | + ); |
|
58 | + parent::configure(); |
|
59 | + } |
|
60 | 60 | |
61 | - protected function execute(InputInterface $input, OutputInterface $output) { |
|
62 | - $authBackends = $this->backendService->getAuthMechanisms(); |
|
63 | - $storageBackends = $this->backendService->getBackends(); |
|
61 | + protected function execute(InputInterface $input, OutputInterface $output) { |
|
62 | + $authBackends = $this->backendService->getAuthMechanisms(); |
|
63 | + $storageBackends = $this->backendService->getBackends(); |
|
64 | 64 | |
65 | - $data = [ |
|
66 | - 'authentication' => array_map([$this, 'serializeAuthBackend'], $authBackends), |
|
67 | - 'storage' => array_map([$this, 'serializeAuthBackend'], $storageBackends) |
|
68 | - ]; |
|
65 | + $data = [ |
|
66 | + 'authentication' => array_map([$this, 'serializeAuthBackend'], $authBackends), |
|
67 | + 'storage' => array_map([$this, 'serializeAuthBackend'], $storageBackends) |
|
68 | + ]; |
|
69 | 69 | |
70 | - $type = $input->getArgument('type'); |
|
71 | - $backend = $input->getArgument('backend'); |
|
72 | - if ($type) { |
|
73 | - if (!isset($data[$type])) { |
|
74 | - $output->writeln('<error>Invalid type "' . $type . '". Possible values are "authentication" or "storage"</error>'); |
|
75 | - return 1; |
|
76 | - } |
|
77 | - $data = $data[$type]; |
|
70 | + $type = $input->getArgument('type'); |
|
71 | + $backend = $input->getArgument('backend'); |
|
72 | + if ($type) { |
|
73 | + if (!isset($data[$type])) { |
|
74 | + $output->writeln('<error>Invalid type "' . $type . '". Possible values are "authentication" or "storage"</error>'); |
|
75 | + return 1; |
|
76 | + } |
|
77 | + $data = $data[$type]; |
|
78 | 78 | |
79 | - if ($backend) { |
|
80 | - if (!isset($data[$backend])) { |
|
81 | - $output->writeln('<error>Unknown backend "' . $backend . '" of type "' . $type . '"</error>'); |
|
82 | - return 1; |
|
83 | - } |
|
84 | - $data = $data[$backend]; |
|
85 | - } |
|
86 | - } |
|
79 | + if ($backend) { |
|
80 | + if (!isset($data[$backend])) { |
|
81 | + $output->writeln('<error>Unknown backend "' . $backend . '" of type "' . $type . '"</error>'); |
|
82 | + return 1; |
|
83 | + } |
|
84 | + $data = $data[$backend]; |
|
85 | + } |
|
86 | + } |
|
87 | 87 | |
88 | - $this->writeArrayInOutputFormat($input, $output, $data); |
|
89 | - } |
|
88 | + $this->writeArrayInOutputFormat($input, $output, $data); |
|
89 | + } |
|
90 | 90 | |
91 | - private function serializeAuthBackend(\JsonSerializable $backend) { |
|
92 | - $data = $backend->jsonSerialize(); |
|
93 | - $result = [ |
|
94 | - 'name' => $data['name'], |
|
95 | - 'identifier' => $data['identifier'], |
|
96 | - 'configuration' => $this->formatConfiguration($data['configuration']) |
|
97 | - ]; |
|
98 | - if ($backend instanceof Backend) { |
|
99 | - $result['storage_class'] = $backend->getStorageClass(); |
|
100 | - $authBackends = $this->backendService->getAuthMechanismsByScheme(array_keys($backend->getAuthSchemes())); |
|
101 | - $result['supported_authentication_backends'] = array_keys($authBackends); |
|
102 | - $authConfig = array_map(function (AuthMechanism $auth) { |
|
103 | - return $this->serializeAuthBackend($auth)['configuration']; |
|
104 | - }, $authBackends); |
|
105 | - $result['authentication_configuration'] = array_combine(array_keys($authBackends), $authConfig); |
|
106 | - } |
|
107 | - return $result; |
|
108 | - } |
|
91 | + private function serializeAuthBackend(\JsonSerializable $backend) { |
|
92 | + $data = $backend->jsonSerialize(); |
|
93 | + $result = [ |
|
94 | + 'name' => $data['name'], |
|
95 | + 'identifier' => $data['identifier'], |
|
96 | + 'configuration' => $this->formatConfiguration($data['configuration']) |
|
97 | + ]; |
|
98 | + if ($backend instanceof Backend) { |
|
99 | + $result['storage_class'] = $backend->getStorageClass(); |
|
100 | + $authBackends = $this->backendService->getAuthMechanismsByScheme(array_keys($backend->getAuthSchemes())); |
|
101 | + $result['supported_authentication_backends'] = array_keys($authBackends); |
|
102 | + $authConfig = array_map(function (AuthMechanism $auth) { |
|
103 | + return $this->serializeAuthBackend($auth)['configuration']; |
|
104 | + }, $authBackends); |
|
105 | + $result['authentication_configuration'] = array_combine(array_keys($authBackends), $authConfig); |
|
106 | + } |
|
107 | + return $result; |
|
108 | + } |
|
109 | 109 | |
110 | - /** |
|
111 | - * @param DefinitionParameter[] $parameters |
|
112 | - * @return string[] |
|
113 | - */ |
|
114 | - private function formatConfiguration(array $parameters) { |
|
115 | - $configuration = array_filter($parameters, function (DefinitionParameter $parameter) { |
|
116 | - return $parameter->getType() !== DefinitionParameter::VALUE_HIDDEN; |
|
117 | - }); |
|
118 | - return array_map(function (DefinitionParameter $parameter) { |
|
119 | - return $parameter->getTypeName(); |
|
120 | - }, $configuration); |
|
121 | - } |
|
110 | + /** |
|
111 | + * @param DefinitionParameter[] $parameters |
|
112 | + * @return string[] |
|
113 | + */ |
|
114 | + private function formatConfiguration(array $parameters) { |
|
115 | + $configuration = array_filter($parameters, function (DefinitionParameter $parameter) { |
|
116 | + return $parameter->getType() !== DefinitionParameter::VALUE_HIDDEN; |
|
117 | + }); |
|
118 | + return array_map(function (DefinitionParameter $parameter) { |
|
119 | + return $parameter->getTypeName(); |
|
120 | + }, $configuration); |
|
121 | + } |
|
122 | 122 | } |
@@ -71,14 +71,14 @@ discard block |
||
71 | 71 | $backend = $input->getArgument('backend'); |
72 | 72 | if ($type) { |
73 | 73 | if (!isset($data[$type])) { |
74 | - $output->writeln('<error>Invalid type "' . $type . '". Possible values are "authentication" or "storage"</error>'); |
|
74 | + $output->writeln('<error>Invalid type "'.$type.'". Possible values are "authentication" or "storage"</error>'); |
|
75 | 75 | return 1; |
76 | 76 | } |
77 | 77 | $data = $data[$type]; |
78 | 78 | |
79 | 79 | if ($backend) { |
80 | 80 | if (!isset($data[$backend])) { |
81 | - $output->writeln('<error>Unknown backend "' . $backend . '" of type "' . $type . '"</error>'); |
|
81 | + $output->writeln('<error>Unknown backend "'.$backend.'" of type "'.$type.'"</error>'); |
|
82 | 82 | return 1; |
83 | 83 | } |
84 | 84 | $data = $data[$backend]; |
@@ -99,7 +99,7 @@ discard block |
||
99 | 99 | $result['storage_class'] = $backend->getStorageClass(); |
100 | 100 | $authBackends = $this->backendService->getAuthMechanismsByScheme(array_keys($backend->getAuthSchemes())); |
101 | 101 | $result['supported_authentication_backends'] = array_keys($authBackends); |
102 | - $authConfig = array_map(function (AuthMechanism $auth) { |
|
102 | + $authConfig = array_map(function(AuthMechanism $auth) { |
|
103 | 103 | return $this->serializeAuthBackend($auth)['configuration']; |
104 | 104 | }, $authBackends); |
105 | 105 | $result['authentication_configuration'] = array_combine(array_keys($authBackends), $authConfig); |
@@ -112,10 +112,10 @@ discard block |
||
112 | 112 | * @return string[] |
113 | 113 | */ |
114 | 114 | private function formatConfiguration(array $parameters) { |
115 | - $configuration = array_filter($parameters, function (DefinitionParameter $parameter) { |
|
115 | + $configuration = array_filter($parameters, function(DefinitionParameter $parameter) { |
|
116 | 116 | return $parameter->getType() !== DefinitionParameter::VALUE_HIDDEN; |
117 | 117 | }); |
118 | - return array_map(function (DefinitionParameter $parameter) { |
|
118 | + return array_map(function(DefinitionParameter $parameter) { |
|
119 | 119 | return $parameter->getTypeName(); |
120 | 120 | }, $configuration); |
121 | 121 | } |
@@ -27,7 +27,6 @@ |
||
27 | 27 | |
28 | 28 | use OC_App; |
29 | 29 | use OCP\Console\ConsoleEvent; |
30 | -use OCP\Defaults; |
|
31 | 30 | use OCP\IConfig; |
32 | 31 | use OCP\IRequest; |
33 | 32 | use Symfony\Component\Console\Application as SymfonyApplication; |
@@ -39,110 +39,110 @@ |
||
39 | 39 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
40 | 40 | |
41 | 41 | class Application { |
42 | - /** @var IConfig */ |
|
43 | - private $config; |
|
44 | - /** @var EventDispatcherInterface */ |
|
45 | - private $dispatcher; |
|
46 | - /** @var IRequest */ |
|
47 | - private $request; |
|
42 | + /** @var IConfig */ |
|
43 | + private $config; |
|
44 | + /** @var EventDispatcherInterface */ |
|
45 | + private $dispatcher; |
|
46 | + /** @var IRequest */ |
|
47 | + private $request; |
|
48 | 48 | |
49 | - /** |
|
50 | - * @param IConfig $config |
|
51 | - * @param EventDispatcherInterface $dispatcher |
|
52 | - * @param IRequest $request |
|
53 | - */ |
|
54 | - public function __construct(IConfig $config, EventDispatcherInterface $dispatcher, IRequest $request) { |
|
55 | - $defaults = \OC::$server->getThemingDefaults(); |
|
56 | - $this->config = $config; |
|
57 | - $this->application = new SymfonyApplication($defaults->getName(), \OC_Util::getVersionString()); |
|
58 | - $this->dispatcher = $dispatcher; |
|
59 | - $this->request = $request; |
|
60 | - } |
|
49 | + /** |
|
50 | + * @param IConfig $config |
|
51 | + * @param EventDispatcherInterface $dispatcher |
|
52 | + * @param IRequest $request |
|
53 | + */ |
|
54 | + public function __construct(IConfig $config, EventDispatcherInterface $dispatcher, IRequest $request) { |
|
55 | + $defaults = \OC::$server->getThemingDefaults(); |
|
56 | + $this->config = $config; |
|
57 | + $this->application = new SymfonyApplication($defaults->getName(), \OC_Util::getVersionString()); |
|
58 | + $this->dispatcher = $dispatcher; |
|
59 | + $this->request = $request; |
|
60 | + } |
|
61 | 61 | |
62 | - /** |
|
63 | - * @param InputInterface $input |
|
64 | - * @param OutputInterface $output |
|
65 | - * @throws \Exception |
|
66 | - */ |
|
67 | - public function loadCommands(InputInterface $input, OutputInterface $output) { |
|
68 | - // $application is required to be defined in the register_command scripts |
|
69 | - $application = $this->application; |
|
70 | - $inputDefinition = $application->getDefinition(); |
|
71 | - $inputDefinition->addOption( |
|
72 | - new InputOption( |
|
73 | - 'no-warnings', |
|
74 | - null, |
|
75 | - InputOption::VALUE_NONE, |
|
76 | - 'Skip global warnings, show command output only', |
|
77 | - null |
|
78 | - ) |
|
79 | - ); |
|
80 | - try { |
|
81 | - $input->bind($inputDefinition); |
|
82 | - } catch (\RuntimeException $e) { |
|
83 | - //expected if there are extra options |
|
84 | - } |
|
85 | - if ($input->getOption('no-warnings')) { |
|
86 | - $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); |
|
87 | - } |
|
88 | - require_once __DIR__ . '/../../../core/register_command.php'; |
|
89 | - if ($this->config->getSystemValue('installed', false)) { |
|
90 | - if (\OCP\Util::needUpgrade()) { |
|
91 | - $output->writeln("Nextcloud or one of the apps require upgrade - only a limited number of commands are available"); |
|
92 | - $output->writeln("You may use your browser or the occ upgrade command to do the upgrade"); |
|
93 | - } elseif ($this->config->getSystemValue('maintenance', false)) { |
|
94 | - $output->writeln("Nextcloud is in maintenance mode - no app have been loaded"); |
|
95 | - } else { |
|
96 | - OC_App::loadApps(); |
|
97 | - foreach (\OC::$server->getAppManager()->getInstalledApps() as $app) { |
|
98 | - $appPath = \OC_App::getAppPath($app); |
|
99 | - if($appPath === false) { |
|
100 | - continue; |
|
101 | - } |
|
102 | - \OC_App::registerAutoloading($app, $appPath); |
|
103 | - $file = $appPath . '/appinfo/register_command.php'; |
|
104 | - if (file_exists($file)) { |
|
105 | - require $file; |
|
106 | - } |
|
107 | - } |
|
108 | - } |
|
109 | - } else { |
|
110 | - $output->writeln("Nextcloud is not installed - only a limited number of commands are available"); |
|
111 | - } |
|
112 | - $input = new ArgvInput(); |
|
113 | - if ($input->getFirstArgument() !== 'check') { |
|
114 | - $errors = \OC_Util::checkServer(\OC::$server->getConfig()); |
|
115 | - if (!empty($errors)) { |
|
116 | - foreach ($errors as $error) { |
|
117 | - $output->writeln((string)$error['error']); |
|
118 | - $output->writeln((string)$error['hint']); |
|
119 | - $output->writeln(''); |
|
120 | - } |
|
121 | - throw new \Exception("Environment not properly prepared."); |
|
122 | - } |
|
123 | - } |
|
124 | - } |
|
62 | + /** |
|
63 | + * @param InputInterface $input |
|
64 | + * @param OutputInterface $output |
|
65 | + * @throws \Exception |
|
66 | + */ |
|
67 | + public function loadCommands(InputInterface $input, OutputInterface $output) { |
|
68 | + // $application is required to be defined in the register_command scripts |
|
69 | + $application = $this->application; |
|
70 | + $inputDefinition = $application->getDefinition(); |
|
71 | + $inputDefinition->addOption( |
|
72 | + new InputOption( |
|
73 | + 'no-warnings', |
|
74 | + null, |
|
75 | + InputOption::VALUE_NONE, |
|
76 | + 'Skip global warnings, show command output only', |
|
77 | + null |
|
78 | + ) |
|
79 | + ); |
|
80 | + try { |
|
81 | + $input->bind($inputDefinition); |
|
82 | + } catch (\RuntimeException $e) { |
|
83 | + //expected if there are extra options |
|
84 | + } |
|
85 | + if ($input->getOption('no-warnings')) { |
|
86 | + $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); |
|
87 | + } |
|
88 | + require_once __DIR__ . '/../../../core/register_command.php'; |
|
89 | + if ($this->config->getSystemValue('installed', false)) { |
|
90 | + if (\OCP\Util::needUpgrade()) { |
|
91 | + $output->writeln("Nextcloud or one of the apps require upgrade - only a limited number of commands are available"); |
|
92 | + $output->writeln("You may use your browser or the occ upgrade command to do the upgrade"); |
|
93 | + } elseif ($this->config->getSystemValue('maintenance', false)) { |
|
94 | + $output->writeln("Nextcloud is in maintenance mode - no app have been loaded"); |
|
95 | + } else { |
|
96 | + OC_App::loadApps(); |
|
97 | + foreach (\OC::$server->getAppManager()->getInstalledApps() as $app) { |
|
98 | + $appPath = \OC_App::getAppPath($app); |
|
99 | + if($appPath === false) { |
|
100 | + continue; |
|
101 | + } |
|
102 | + \OC_App::registerAutoloading($app, $appPath); |
|
103 | + $file = $appPath . '/appinfo/register_command.php'; |
|
104 | + if (file_exists($file)) { |
|
105 | + require $file; |
|
106 | + } |
|
107 | + } |
|
108 | + } |
|
109 | + } else { |
|
110 | + $output->writeln("Nextcloud is not installed - only a limited number of commands are available"); |
|
111 | + } |
|
112 | + $input = new ArgvInput(); |
|
113 | + if ($input->getFirstArgument() !== 'check') { |
|
114 | + $errors = \OC_Util::checkServer(\OC::$server->getConfig()); |
|
115 | + if (!empty($errors)) { |
|
116 | + foreach ($errors as $error) { |
|
117 | + $output->writeln((string)$error['error']); |
|
118 | + $output->writeln((string)$error['hint']); |
|
119 | + $output->writeln(''); |
|
120 | + } |
|
121 | + throw new \Exception("Environment not properly prepared."); |
|
122 | + } |
|
123 | + } |
|
124 | + } |
|
125 | 125 | |
126 | - /** |
|
127 | - * Sets whether to automatically exit after a command execution or not. |
|
128 | - * |
|
129 | - * @param bool $boolean Whether to automatically exit after a command execution or not |
|
130 | - */ |
|
131 | - public function setAutoExit($boolean) { |
|
132 | - $this->application->setAutoExit($boolean); |
|
133 | - } |
|
126 | + /** |
|
127 | + * Sets whether to automatically exit after a command execution or not. |
|
128 | + * |
|
129 | + * @param bool $boolean Whether to automatically exit after a command execution or not |
|
130 | + */ |
|
131 | + public function setAutoExit($boolean) { |
|
132 | + $this->application->setAutoExit($boolean); |
|
133 | + } |
|
134 | 134 | |
135 | - /** |
|
136 | - * @param InputInterface $input |
|
137 | - * @param OutputInterface $output |
|
138 | - * @return int |
|
139 | - * @throws \Exception |
|
140 | - */ |
|
141 | - public function run(InputInterface $input = null, OutputInterface $output = null) { |
|
142 | - $this->dispatcher->dispatch(ConsoleEvent::EVENT_RUN, new ConsoleEvent( |
|
143 | - ConsoleEvent::EVENT_RUN, |
|
144 | - $this->request->server['argv'] |
|
145 | - )); |
|
146 | - return $this->application->run($input, $output); |
|
147 | - } |
|
135 | + /** |
|
136 | + * @param InputInterface $input |
|
137 | + * @param OutputInterface $output |
|
138 | + * @return int |
|
139 | + * @throws \Exception |
|
140 | + */ |
|
141 | + public function run(InputInterface $input = null, OutputInterface $output = null) { |
|
142 | + $this->dispatcher->dispatch(ConsoleEvent::EVENT_RUN, new ConsoleEvent( |
|
143 | + ConsoleEvent::EVENT_RUN, |
|
144 | + $this->request->server['argv'] |
|
145 | + )); |
|
146 | + return $this->application->run($input, $output); |
|
147 | + } |
|
148 | 148 | } |
@@ -85,7 +85,7 @@ discard block |
||
85 | 85 | if ($input->getOption('no-warnings')) { |
86 | 86 | $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); |
87 | 87 | } |
88 | - require_once __DIR__ . '/../../../core/register_command.php'; |
|
88 | + require_once __DIR__.'/../../../core/register_command.php'; |
|
89 | 89 | if ($this->config->getSystemValue('installed', false)) { |
90 | 90 | if (\OCP\Util::needUpgrade()) { |
91 | 91 | $output->writeln("Nextcloud or one of the apps require upgrade - only a limited number of commands are available"); |
@@ -96,11 +96,11 @@ discard block |
||
96 | 96 | OC_App::loadApps(); |
97 | 97 | foreach (\OC::$server->getAppManager()->getInstalledApps() as $app) { |
98 | 98 | $appPath = \OC_App::getAppPath($app); |
99 | - if($appPath === false) { |
|
99 | + if ($appPath === false) { |
|
100 | 100 | continue; |
101 | 101 | } |
102 | 102 | \OC_App::registerAutoloading($app, $appPath); |
103 | - $file = $appPath . '/appinfo/register_command.php'; |
|
103 | + $file = $appPath.'/appinfo/register_command.php'; |
|
104 | 104 | if (file_exists($file)) { |
105 | 105 | require $file; |
106 | 106 | } |
@@ -114,8 +114,8 @@ discard block |
||
114 | 114 | $errors = \OC_Util::checkServer(\OC::$server->getConfig()); |
115 | 115 | if (!empty($errors)) { |
116 | 116 | foreach ($errors as $error) { |
117 | - $output->writeln((string)$error['error']); |
|
118 | - $output->writeln((string)$error['hint']); |
|
117 | + $output->writeln((string) $error['error']); |
|
118 | + $output->writeln((string) $error['hint']); |
|
119 | 119 | $output->writeln(''); |
120 | 120 | } |
121 | 121 | throw new \Exception("Environment not properly prepared."); |
@@ -35,15 +35,6 @@ |
||
35 | 35 | */ |
36 | 36 | namespace OC; |
37 | 37 | |
38 | -use Assetic\Asset\AssetCollection; |
|
39 | -use Assetic\Asset\FileAsset; |
|
40 | -use Assetic\AssetWriter; |
|
41 | -use Assetic\Filter\CssImportFilter; |
|
42 | -use Assetic\Filter\CssMinFilter; |
|
43 | -use Assetic\Filter\CssRewriteFilter; |
|
44 | -use Assetic\Filter\JSqueezeFilter; |
|
45 | -use Assetic\Filter\SeparatorFilter; |
|
46 | - |
|
47 | 38 | class TemplateLayout extends \OC_Template { |
48 | 39 | |
49 | 40 | private static $versionHash = ''; |
@@ -61,7 +61,7 @@ |
||
61 | 61 | parent::__construct( 'core', 'layout.user' ); |
62 | 62 | if(in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) { |
63 | 63 | $this->assign('bodyid', 'body-settings'); |
64 | - }else{ |
|
64 | + } else{ |
|
65 | 65 | $this->assign('bodyid', 'body-user'); |
66 | 66 | } |
67 | 67 |
@@ -46,172 +46,172 @@ |
||
46 | 46 | |
47 | 47 | class TemplateLayout extends \OC_Template { |
48 | 48 | |
49 | - private static $versionHash = ''; |
|
50 | - |
|
51 | - /** |
|
52 | - * @var \OCP\IConfig |
|
53 | - */ |
|
54 | - private $config; |
|
55 | - |
|
56 | - /** |
|
57 | - * @param string $renderAs |
|
58 | - * @param string $appId application id |
|
59 | - */ |
|
60 | - public function __construct( $renderAs, $appId = '' ) { |
|
61 | - |
|
62 | - // yes - should be injected .... |
|
63 | - $this->config = \OC::$server->getConfig(); |
|
64 | - |
|
65 | - // Decide which page we show |
|
66 | - if($renderAs == 'user') { |
|
67 | - parent::__construct( 'core', 'layout.user' ); |
|
68 | - if(in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) { |
|
69 | - $this->assign('bodyid', 'body-settings'); |
|
70 | - }else{ |
|
71 | - $this->assign('bodyid', 'body-user'); |
|
72 | - } |
|
73 | - |
|
74 | - // Code integrity notification |
|
75 | - $integrityChecker = \OC::$server->getIntegrityCodeChecker(); |
|
76 | - if(\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) { |
|
77 | - \OCP\Util::addScript('core', 'integritycheck-failed-notification'); |
|
78 | - } |
|
79 | - |
|
80 | - // Add navigation entry |
|
81 | - $this->assign( 'application', ''); |
|
82 | - $this->assign( 'appid', $appId ); |
|
83 | - $navigation = \OC_App::getNavigation(); |
|
84 | - $this->assign( 'navigation', $navigation); |
|
85 | - $settingsNavigation = \OC_App::getSettingsNavigation(); |
|
86 | - $this->assign( 'settingsnavigation', $settingsNavigation); |
|
87 | - foreach($navigation as $entry) { |
|
88 | - if ($entry['active']) { |
|
89 | - $this->assign( 'application', $entry['name'] ); |
|
90 | - break; |
|
91 | - } |
|
92 | - } |
|
49 | + private static $versionHash = ''; |
|
50 | + |
|
51 | + /** |
|
52 | + * @var \OCP\IConfig |
|
53 | + */ |
|
54 | + private $config; |
|
55 | + |
|
56 | + /** |
|
57 | + * @param string $renderAs |
|
58 | + * @param string $appId application id |
|
59 | + */ |
|
60 | + public function __construct( $renderAs, $appId = '' ) { |
|
61 | + |
|
62 | + // yes - should be injected .... |
|
63 | + $this->config = \OC::$server->getConfig(); |
|
64 | + |
|
65 | + // Decide which page we show |
|
66 | + if($renderAs == 'user') { |
|
67 | + parent::__construct( 'core', 'layout.user' ); |
|
68 | + if(in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) { |
|
69 | + $this->assign('bodyid', 'body-settings'); |
|
70 | + }else{ |
|
71 | + $this->assign('bodyid', 'body-user'); |
|
72 | + } |
|
73 | + |
|
74 | + // Code integrity notification |
|
75 | + $integrityChecker = \OC::$server->getIntegrityCodeChecker(); |
|
76 | + if(\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) { |
|
77 | + \OCP\Util::addScript('core', 'integritycheck-failed-notification'); |
|
78 | + } |
|
79 | + |
|
80 | + // Add navigation entry |
|
81 | + $this->assign( 'application', ''); |
|
82 | + $this->assign( 'appid', $appId ); |
|
83 | + $navigation = \OC_App::getNavigation(); |
|
84 | + $this->assign( 'navigation', $navigation); |
|
85 | + $settingsNavigation = \OC_App::getSettingsNavigation(); |
|
86 | + $this->assign( 'settingsnavigation', $settingsNavigation); |
|
87 | + foreach($navigation as $entry) { |
|
88 | + if ($entry['active']) { |
|
89 | + $this->assign( 'application', $entry['name'] ); |
|
90 | + break; |
|
91 | + } |
|
92 | + } |
|
93 | 93 | |
94 | - foreach($settingsNavigation as $entry) { |
|
95 | - if ($entry['active']) { |
|
96 | - $this->assign( 'application', $entry['name'] ); |
|
97 | - break; |
|
98 | - } |
|
99 | - } |
|
100 | - $userDisplayName = \OC_User::getDisplayName(); |
|
101 | - $appsMgmtActive = strpos(\OC::$server->getRequest()->getRequestUri(), \OC::$server->getURLGenerator()->linkToRoute('settings.AppSettings.viewApps')) === 0; |
|
102 | - if ($appsMgmtActive) { |
|
103 | - $l = \OC::$server->getL10N('lib'); |
|
104 | - $this->assign('application', $l->t('Apps')); |
|
105 | - } |
|
106 | - $this->assign('user_displayname', $userDisplayName); |
|
107 | - $this->assign('user_uid', \OC_User::getUser()); |
|
108 | - $this->assign('appsmanagement_active', $appsMgmtActive); |
|
109 | - $this->assign('enableAvatars', $this->config->getSystemValue('enable_avatars', true) === true); |
|
110 | - |
|
111 | - if (\OC_User::getUser() === false) { |
|
112 | - $this->assign('userAvatarSet', false); |
|
113 | - } else { |
|
114 | - $this->assign('userAvatarSet', \OC::$server->getAvatarManager()->getAvatar(\OC_User::getUser())->exists()); |
|
115 | - } |
|
116 | - |
|
117 | - } else if ($renderAs == 'error') { |
|
118 | - parent::__construct('core', 'layout.guest', '', false); |
|
119 | - $this->assign('bodyid', 'body-login'); |
|
120 | - } else if ($renderAs == 'guest') { |
|
121 | - parent::__construct('core', 'layout.guest'); |
|
122 | - $this->assign('bodyid', 'body-login'); |
|
123 | - } else { |
|
124 | - parent::__construct('core', 'layout.base'); |
|
125 | - |
|
126 | - } |
|
127 | - // Send the language to our layouts |
|
128 | - $this->assign('language', \OC_L10N::findLanguage()); |
|
129 | - |
|
130 | - if(\OC::$server->getSystemConfig()->getValue('installed', false)) { |
|
131 | - if (empty(self::$versionHash)) { |
|
132 | - $v = \OC_App::getAppVersions(); |
|
133 | - $v['core'] = implode('.', \OCP\Util::getVersion()); |
|
134 | - self::$versionHash = md5(implode(',', $v)); |
|
135 | - } |
|
136 | - } else { |
|
137 | - self::$versionHash = md5('not installed'); |
|
138 | - } |
|
139 | - |
|
140 | - // Add the js files |
|
141 | - $jsFiles = self::findJavascriptFiles(\OC_Util::$scripts); |
|
142 | - $this->assign('jsfiles', array()); |
|
143 | - if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') { |
|
144 | - $this->append( 'jsfiles', \OC::$server->getURLGenerator()->linkToRoute('js_config', ['v' => self::$versionHash])); |
|
145 | - } |
|
146 | - foreach($jsFiles as $info) { |
|
147 | - $web = $info[1]; |
|
148 | - $file = $info[2]; |
|
149 | - $this->append( 'jsfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
150 | - } |
|
151 | - |
|
152 | - // Add the css files |
|
153 | - $cssFiles = self::findStylesheetFiles(\OC_Util::$styles); |
|
154 | - $this->assign('cssfiles', array()); |
|
155 | - $this->assign('printcssfiles', []); |
|
156 | - $this->assign('versionHash', self::$versionHash); |
|
157 | - foreach($cssFiles as $info) { |
|
158 | - $web = $info[1]; |
|
159 | - $file = $info[2]; |
|
160 | - |
|
161 | - if (substr($file, -strlen('print.css')) === 'print.css') { |
|
162 | - $this->append( 'printcssfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
163 | - } else { |
|
164 | - $this->append( 'cssfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
165 | - } |
|
166 | - } |
|
167 | - } |
|
168 | - |
|
169 | - /** |
|
170 | - * @param array $styles |
|
171 | - * @return array |
|
172 | - */ |
|
173 | - static public function findStylesheetFiles($styles) { |
|
174 | - // Read the selected theme from the config file |
|
175 | - $theme = \OC_Util::getTheme(); |
|
176 | - |
|
177 | - $locator = new \OC\Template\CSSResourceLocator( |
|
178 | - \OC::$server->getLogger(), |
|
179 | - $theme, |
|
180 | - array( \OC::$SERVERROOT => \OC::$WEBROOT ), |
|
181 | - array( \OC::$SERVERROOT => \OC::$WEBROOT )); |
|
182 | - $locator->find($styles); |
|
183 | - return $locator->getResources(); |
|
184 | - } |
|
185 | - |
|
186 | - /** |
|
187 | - * @param array $scripts |
|
188 | - * @return array |
|
189 | - */ |
|
190 | - static public function findJavascriptFiles($scripts) { |
|
191 | - // Read the selected theme from the config file |
|
192 | - $theme = \OC_Util::getTheme(); |
|
193 | - |
|
194 | - $locator = new \OC\Template\JSResourceLocator( |
|
195 | - \OC::$server->getLogger(), |
|
196 | - $theme, |
|
197 | - array( \OC::$SERVERROOT => \OC::$WEBROOT ), |
|
198 | - array( \OC::$SERVERROOT => \OC::$WEBROOT )); |
|
199 | - $locator->find($scripts); |
|
200 | - return $locator->getResources(); |
|
201 | - } |
|
202 | - |
|
203 | - /** |
|
204 | - * Converts the absolute file path to a relative path from \OC::$SERVERROOT |
|
205 | - * @param string $filePath Absolute path |
|
206 | - * @return string Relative path |
|
207 | - * @throws \Exception If $filePath is not under \OC::$SERVERROOT |
|
208 | - */ |
|
209 | - public static function convertToRelativePath($filePath) { |
|
210 | - $relativePath = explode(\OC::$SERVERROOT, $filePath); |
|
211 | - if(count($relativePath) !== 2) { |
|
212 | - throw new \Exception('$filePath is not under the \OC::$SERVERROOT'); |
|
213 | - } |
|
214 | - |
|
215 | - return $relativePath[1]; |
|
216 | - } |
|
94 | + foreach($settingsNavigation as $entry) { |
|
95 | + if ($entry['active']) { |
|
96 | + $this->assign( 'application', $entry['name'] ); |
|
97 | + break; |
|
98 | + } |
|
99 | + } |
|
100 | + $userDisplayName = \OC_User::getDisplayName(); |
|
101 | + $appsMgmtActive = strpos(\OC::$server->getRequest()->getRequestUri(), \OC::$server->getURLGenerator()->linkToRoute('settings.AppSettings.viewApps')) === 0; |
|
102 | + if ($appsMgmtActive) { |
|
103 | + $l = \OC::$server->getL10N('lib'); |
|
104 | + $this->assign('application', $l->t('Apps')); |
|
105 | + } |
|
106 | + $this->assign('user_displayname', $userDisplayName); |
|
107 | + $this->assign('user_uid', \OC_User::getUser()); |
|
108 | + $this->assign('appsmanagement_active', $appsMgmtActive); |
|
109 | + $this->assign('enableAvatars', $this->config->getSystemValue('enable_avatars', true) === true); |
|
110 | + |
|
111 | + if (\OC_User::getUser() === false) { |
|
112 | + $this->assign('userAvatarSet', false); |
|
113 | + } else { |
|
114 | + $this->assign('userAvatarSet', \OC::$server->getAvatarManager()->getAvatar(\OC_User::getUser())->exists()); |
|
115 | + } |
|
116 | + |
|
117 | + } else if ($renderAs == 'error') { |
|
118 | + parent::__construct('core', 'layout.guest', '', false); |
|
119 | + $this->assign('bodyid', 'body-login'); |
|
120 | + } else if ($renderAs == 'guest') { |
|
121 | + parent::__construct('core', 'layout.guest'); |
|
122 | + $this->assign('bodyid', 'body-login'); |
|
123 | + } else { |
|
124 | + parent::__construct('core', 'layout.base'); |
|
125 | + |
|
126 | + } |
|
127 | + // Send the language to our layouts |
|
128 | + $this->assign('language', \OC_L10N::findLanguage()); |
|
129 | + |
|
130 | + if(\OC::$server->getSystemConfig()->getValue('installed', false)) { |
|
131 | + if (empty(self::$versionHash)) { |
|
132 | + $v = \OC_App::getAppVersions(); |
|
133 | + $v['core'] = implode('.', \OCP\Util::getVersion()); |
|
134 | + self::$versionHash = md5(implode(',', $v)); |
|
135 | + } |
|
136 | + } else { |
|
137 | + self::$versionHash = md5('not installed'); |
|
138 | + } |
|
139 | + |
|
140 | + // Add the js files |
|
141 | + $jsFiles = self::findJavascriptFiles(\OC_Util::$scripts); |
|
142 | + $this->assign('jsfiles', array()); |
|
143 | + if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') { |
|
144 | + $this->append( 'jsfiles', \OC::$server->getURLGenerator()->linkToRoute('js_config', ['v' => self::$versionHash])); |
|
145 | + } |
|
146 | + foreach($jsFiles as $info) { |
|
147 | + $web = $info[1]; |
|
148 | + $file = $info[2]; |
|
149 | + $this->append( 'jsfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
150 | + } |
|
151 | + |
|
152 | + // Add the css files |
|
153 | + $cssFiles = self::findStylesheetFiles(\OC_Util::$styles); |
|
154 | + $this->assign('cssfiles', array()); |
|
155 | + $this->assign('printcssfiles', []); |
|
156 | + $this->assign('versionHash', self::$versionHash); |
|
157 | + foreach($cssFiles as $info) { |
|
158 | + $web = $info[1]; |
|
159 | + $file = $info[2]; |
|
160 | + |
|
161 | + if (substr($file, -strlen('print.css')) === 'print.css') { |
|
162 | + $this->append( 'printcssfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
163 | + } else { |
|
164 | + $this->append( 'cssfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
165 | + } |
|
166 | + } |
|
167 | + } |
|
168 | + |
|
169 | + /** |
|
170 | + * @param array $styles |
|
171 | + * @return array |
|
172 | + */ |
|
173 | + static public function findStylesheetFiles($styles) { |
|
174 | + // Read the selected theme from the config file |
|
175 | + $theme = \OC_Util::getTheme(); |
|
176 | + |
|
177 | + $locator = new \OC\Template\CSSResourceLocator( |
|
178 | + \OC::$server->getLogger(), |
|
179 | + $theme, |
|
180 | + array( \OC::$SERVERROOT => \OC::$WEBROOT ), |
|
181 | + array( \OC::$SERVERROOT => \OC::$WEBROOT )); |
|
182 | + $locator->find($styles); |
|
183 | + return $locator->getResources(); |
|
184 | + } |
|
185 | + |
|
186 | + /** |
|
187 | + * @param array $scripts |
|
188 | + * @return array |
|
189 | + */ |
|
190 | + static public function findJavascriptFiles($scripts) { |
|
191 | + // Read the selected theme from the config file |
|
192 | + $theme = \OC_Util::getTheme(); |
|
193 | + |
|
194 | + $locator = new \OC\Template\JSResourceLocator( |
|
195 | + \OC::$server->getLogger(), |
|
196 | + $theme, |
|
197 | + array( \OC::$SERVERROOT => \OC::$WEBROOT ), |
|
198 | + array( \OC::$SERVERROOT => \OC::$WEBROOT )); |
|
199 | + $locator->find($scripts); |
|
200 | + return $locator->getResources(); |
|
201 | + } |
|
202 | + |
|
203 | + /** |
|
204 | + * Converts the absolute file path to a relative path from \OC::$SERVERROOT |
|
205 | + * @param string $filePath Absolute path |
|
206 | + * @return string Relative path |
|
207 | + * @throws \Exception If $filePath is not under \OC::$SERVERROOT |
|
208 | + */ |
|
209 | + public static function convertToRelativePath($filePath) { |
|
210 | + $relativePath = explode(\OC::$SERVERROOT, $filePath); |
|
211 | + if(count($relativePath) !== 2) { |
|
212 | + throw new \Exception('$filePath is not under the \OC::$SERVERROOT'); |
|
213 | + } |
|
214 | + |
|
215 | + return $relativePath[1]; |
|
216 | + } |
|
217 | 217 | } |
@@ -57,43 +57,43 @@ discard block |
||
57 | 57 | * @param string $renderAs |
58 | 58 | * @param string $appId application id |
59 | 59 | */ |
60 | - public function __construct( $renderAs, $appId = '' ) { |
|
60 | + public function __construct($renderAs, $appId = '') { |
|
61 | 61 | |
62 | 62 | // yes - should be injected .... |
63 | 63 | $this->config = \OC::$server->getConfig(); |
64 | 64 | |
65 | 65 | // Decide which page we show |
66 | - if($renderAs == 'user') { |
|
67 | - parent::__construct( 'core', 'layout.user' ); |
|
68 | - if(in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) { |
|
66 | + if ($renderAs == 'user') { |
|
67 | + parent::__construct('core', 'layout.user'); |
|
68 | + if (in_array(\OC_App::getCurrentApp(), ['settings', 'admin', 'help']) !== false) { |
|
69 | 69 | $this->assign('bodyid', 'body-settings'); |
70 | - }else{ |
|
70 | + } else { |
|
71 | 71 | $this->assign('bodyid', 'body-user'); |
72 | 72 | } |
73 | 73 | |
74 | 74 | // Code integrity notification |
75 | 75 | $integrityChecker = \OC::$server->getIntegrityCodeChecker(); |
76 | - if(\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) { |
|
76 | + if (\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) { |
|
77 | 77 | \OCP\Util::addScript('core', 'integritycheck-failed-notification'); |
78 | 78 | } |
79 | 79 | |
80 | 80 | // Add navigation entry |
81 | - $this->assign( 'application', ''); |
|
82 | - $this->assign( 'appid', $appId ); |
|
81 | + $this->assign('application', ''); |
|
82 | + $this->assign('appid', $appId); |
|
83 | 83 | $navigation = \OC_App::getNavigation(); |
84 | - $this->assign( 'navigation', $navigation); |
|
84 | + $this->assign('navigation', $navigation); |
|
85 | 85 | $settingsNavigation = \OC_App::getSettingsNavigation(); |
86 | - $this->assign( 'settingsnavigation', $settingsNavigation); |
|
87 | - foreach($navigation as $entry) { |
|
86 | + $this->assign('settingsnavigation', $settingsNavigation); |
|
87 | + foreach ($navigation as $entry) { |
|
88 | 88 | if ($entry['active']) { |
89 | - $this->assign( 'application', $entry['name'] ); |
|
89 | + $this->assign('application', $entry['name']); |
|
90 | 90 | break; |
91 | 91 | } |
92 | 92 | } |
93 | 93 | |
94 | - foreach($settingsNavigation as $entry) { |
|
94 | + foreach ($settingsNavigation as $entry) { |
|
95 | 95 | if ($entry['active']) { |
96 | - $this->assign( 'application', $entry['name'] ); |
|
96 | + $this->assign('application', $entry['name']); |
|
97 | 97 | break; |
98 | 98 | } |
99 | 99 | } |
@@ -127,7 +127,7 @@ discard block |
||
127 | 127 | // Send the language to our layouts |
128 | 128 | $this->assign('language', \OC_L10N::findLanguage()); |
129 | 129 | |
130 | - if(\OC::$server->getSystemConfig()->getValue('installed', false)) { |
|
130 | + if (\OC::$server->getSystemConfig()->getValue('installed', false)) { |
|
131 | 131 | if (empty(self::$versionHash)) { |
132 | 132 | $v = \OC_App::getAppVersions(); |
133 | 133 | $v['core'] = implode('.', \OCP\Util::getVersion()); |
@@ -141,12 +141,12 @@ discard block |
||
141 | 141 | $jsFiles = self::findJavascriptFiles(\OC_Util::$scripts); |
142 | 142 | $this->assign('jsfiles', array()); |
143 | 143 | if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') { |
144 | - $this->append( 'jsfiles', \OC::$server->getURLGenerator()->linkToRoute('js_config', ['v' => self::$versionHash])); |
|
144 | + $this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('js_config', ['v' => self::$versionHash])); |
|
145 | 145 | } |
146 | - foreach($jsFiles as $info) { |
|
146 | + foreach ($jsFiles as $info) { |
|
147 | 147 | $web = $info[1]; |
148 | 148 | $file = $info[2]; |
149 | - $this->append( 'jsfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
149 | + $this->append('jsfiles', $web.'/'.$file.'?v='.self::$versionHash); |
|
150 | 150 | } |
151 | 151 | |
152 | 152 | // Add the css files |
@@ -154,14 +154,14 @@ discard block |
||
154 | 154 | $this->assign('cssfiles', array()); |
155 | 155 | $this->assign('printcssfiles', []); |
156 | 156 | $this->assign('versionHash', self::$versionHash); |
157 | - foreach($cssFiles as $info) { |
|
157 | + foreach ($cssFiles as $info) { |
|
158 | 158 | $web = $info[1]; |
159 | 159 | $file = $info[2]; |
160 | 160 | |
161 | 161 | if (substr($file, -strlen('print.css')) === 'print.css') { |
162 | - $this->append( 'printcssfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
162 | + $this->append('printcssfiles', $web.'/'.$file.'?v='.self::$versionHash); |
|
163 | 163 | } else { |
164 | - $this->append( 'cssfiles', $web.'/'.$file . '?v=' . self::$versionHash); |
|
164 | + $this->append('cssfiles', $web.'/'.$file.'?v='.self::$versionHash); |
|
165 | 165 | } |
166 | 166 | } |
167 | 167 | } |
@@ -177,8 +177,8 @@ discard block |
||
177 | 177 | $locator = new \OC\Template\CSSResourceLocator( |
178 | 178 | \OC::$server->getLogger(), |
179 | 179 | $theme, |
180 | - array( \OC::$SERVERROOT => \OC::$WEBROOT ), |
|
181 | - array( \OC::$SERVERROOT => \OC::$WEBROOT )); |
|
180 | + array(\OC::$SERVERROOT => \OC::$WEBROOT), |
|
181 | + array(\OC::$SERVERROOT => \OC::$WEBROOT)); |
|
182 | 182 | $locator->find($styles); |
183 | 183 | return $locator->getResources(); |
184 | 184 | } |
@@ -194,8 +194,8 @@ discard block |
||
194 | 194 | $locator = new \OC\Template\JSResourceLocator( |
195 | 195 | \OC::$server->getLogger(), |
196 | 196 | $theme, |
197 | - array( \OC::$SERVERROOT => \OC::$WEBROOT ), |
|
198 | - array( \OC::$SERVERROOT => \OC::$WEBROOT )); |
|
197 | + array(\OC::$SERVERROOT => \OC::$WEBROOT), |
|
198 | + array(\OC::$SERVERROOT => \OC::$WEBROOT)); |
|
199 | 199 | $locator->find($scripts); |
200 | 200 | return $locator->getResources(); |
201 | 201 | } |
@@ -208,7 +208,7 @@ discard block |
||
208 | 208 | */ |
209 | 209 | public static function convertToRelativePath($filePath) { |
210 | 210 | $relativePath = explode(\OC::$SERVERROOT, $filePath); |
211 | - if(count($relativePath) !== 2) { |
|
211 | + if (count($relativePath) !== 2) { |
|
212 | 212 | throw new \Exception('$filePath is not under the \OC::$SERVERROOT'); |
213 | 213 | } |
214 | 214 |
@@ -22,7 +22,6 @@ |
||
22 | 22 | |
23 | 23 | namespace OC\Core\Controller; |
24 | 24 | |
25 | -use OC\AppFramework\Utility\TimeFactory; |
|
26 | 25 | use OC\Authentication\TwoFactorAuth\Manager; |
27 | 26 | use OC\Security\Bruteforce\Throttler; |
28 | 27 | use OC\User\Session; |
@@ -42,219 +42,219 @@ |
||
42 | 42 | use OCP\IUserManager; |
43 | 43 | |
44 | 44 | class LoginController extends Controller { |
45 | - /** @var IUserManager */ |
|
46 | - private $userManager; |
|
47 | - /** @var IConfig */ |
|
48 | - private $config; |
|
49 | - /** @var ISession */ |
|
50 | - private $session; |
|
51 | - /** @var Session */ |
|
52 | - private $userSession; |
|
53 | - /** @var IURLGenerator */ |
|
54 | - private $urlGenerator; |
|
55 | - /** @var Manager */ |
|
56 | - private $twoFactorManager; |
|
57 | - /** @var Throttler */ |
|
58 | - private $throttler; |
|
45 | + /** @var IUserManager */ |
|
46 | + private $userManager; |
|
47 | + /** @var IConfig */ |
|
48 | + private $config; |
|
49 | + /** @var ISession */ |
|
50 | + private $session; |
|
51 | + /** @var Session */ |
|
52 | + private $userSession; |
|
53 | + /** @var IURLGenerator */ |
|
54 | + private $urlGenerator; |
|
55 | + /** @var Manager */ |
|
56 | + private $twoFactorManager; |
|
57 | + /** @var Throttler */ |
|
58 | + private $throttler; |
|
59 | 59 | |
60 | - /** |
|
61 | - * @param string $appName |
|
62 | - * @param IRequest $request |
|
63 | - * @param IUserManager $userManager |
|
64 | - * @param IConfig $config |
|
65 | - * @param ISession $session |
|
66 | - * @param Session $userSession |
|
67 | - * @param IURLGenerator $urlGenerator |
|
68 | - * @param Manager $twoFactorManager |
|
69 | - * @param Throttler $throttler |
|
70 | - */ |
|
71 | - function __construct($appName, |
|
72 | - IRequest $request, |
|
73 | - IUserManager $userManager, |
|
74 | - IConfig $config, |
|
75 | - ISession $session, |
|
76 | - Session $userSession, |
|
77 | - IURLGenerator $urlGenerator, |
|
78 | - Manager $twoFactorManager, |
|
79 | - Throttler $throttler) { |
|
80 | - parent::__construct($appName, $request); |
|
81 | - $this->userManager = $userManager; |
|
82 | - $this->config = $config; |
|
83 | - $this->session = $session; |
|
84 | - $this->userSession = $userSession; |
|
85 | - $this->urlGenerator = $urlGenerator; |
|
86 | - $this->twoFactorManager = $twoFactorManager; |
|
87 | - $this->throttler = $throttler; |
|
88 | - } |
|
60 | + /** |
|
61 | + * @param string $appName |
|
62 | + * @param IRequest $request |
|
63 | + * @param IUserManager $userManager |
|
64 | + * @param IConfig $config |
|
65 | + * @param ISession $session |
|
66 | + * @param Session $userSession |
|
67 | + * @param IURLGenerator $urlGenerator |
|
68 | + * @param Manager $twoFactorManager |
|
69 | + * @param Throttler $throttler |
|
70 | + */ |
|
71 | + function __construct($appName, |
|
72 | + IRequest $request, |
|
73 | + IUserManager $userManager, |
|
74 | + IConfig $config, |
|
75 | + ISession $session, |
|
76 | + Session $userSession, |
|
77 | + IURLGenerator $urlGenerator, |
|
78 | + Manager $twoFactorManager, |
|
79 | + Throttler $throttler) { |
|
80 | + parent::__construct($appName, $request); |
|
81 | + $this->userManager = $userManager; |
|
82 | + $this->config = $config; |
|
83 | + $this->session = $session; |
|
84 | + $this->userSession = $userSession; |
|
85 | + $this->urlGenerator = $urlGenerator; |
|
86 | + $this->twoFactorManager = $twoFactorManager; |
|
87 | + $this->throttler = $throttler; |
|
88 | + } |
|
89 | 89 | |
90 | - /** |
|
91 | - * @NoAdminRequired |
|
92 | - * @UseSession |
|
93 | - * |
|
94 | - * @return RedirectResponse |
|
95 | - */ |
|
96 | - public function logout() { |
|
97 | - $loginToken = $this->request->getCookie('oc_token'); |
|
98 | - if (!is_null($loginToken)) { |
|
99 | - $this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken); |
|
100 | - } |
|
101 | - $this->userSession->logout(); |
|
90 | + /** |
|
91 | + * @NoAdminRequired |
|
92 | + * @UseSession |
|
93 | + * |
|
94 | + * @return RedirectResponse |
|
95 | + */ |
|
96 | + public function logout() { |
|
97 | + $loginToken = $this->request->getCookie('oc_token'); |
|
98 | + if (!is_null($loginToken)) { |
|
99 | + $this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken); |
|
100 | + } |
|
101 | + $this->userSession->logout(); |
|
102 | 102 | |
103 | - return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); |
|
104 | - } |
|
103 | + return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); |
|
104 | + } |
|
105 | 105 | |
106 | - /** |
|
107 | - * @PublicPage |
|
108 | - * @NoCSRFRequired |
|
109 | - * @UseSession |
|
110 | - * |
|
111 | - * @param string $user |
|
112 | - * @param string $redirect_url |
|
113 | - * @param string $remember_login |
|
114 | - * |
|
115 | - * @return TemplateResponse|RedirectResponse |
|
116 | - */ |
|
117 | - public function showLoginForm($user, $redirect_url, $remember_login) { |
|
118 | - if ($this->userSession->isLoggedIn()) { |
|
119 | - return new RedirectResponse(OC_Util::getDefaultPageUrl()); |
|
120 | - } |
|
106 | + /** |
|
107 | + * @PublicPage |
|
108 | + * @NoCSRFRequired |
|
109 | + * @UseSession |
|
110 | + * |
|
111 | + * @param string $user |
|
112 | + * @param string $redirect_url |
|
113 | + * @param string $remember_login |
|
114 | + * |
|
115 | + * @return TemplateResponse|RedirectResponse |
|
116 | + */ |
|
117 | + public function showLoginForm($user, $redirect_url, $remember_login) { |
|
118 | + if ($this->userSession->isLoggedIn()) { |
|
119 | + return new RedirectResponse(OC_Util::getDefaultPageUrl()); |
|
120 | + } |
|
121 | 121 | |
122 | - $parameters = array(); |
|
123 | - $loginMessages = $this->session->get('loginMessages'); |
|
124 | - $errors = []; |
|
125 | - $messages = []; |
|
126 | - if (is_array($loginMessages)) { |
|
127 | - list($errors, $messages) = $loginMessages; |
|
128 | - } |
|
129 | - $this->session->remove('loginMessages'); |
|
130 | - foreach ($errors as $value) { |
|
131 | - $parameters[$value] = true; |
|
132 | - } |
|
122 | + $parameters = array(); |
|
123 | + $loginMessages = $this->session->get('loginMessages'); |
|
124 | + $errors = []; |
|
125 | + $messages = []; |
|
126 | + if (is_array($loginMessages)) { |
|
127 | + list($errors, $messages) = $loginMessages; |
|
128 | + } |
|
129 | + $this->session->remove('loginMessages'); |
|
130 | + foreach ($errors as $value) { |
|
131 | + $parameters[$value] = true; |
|
132 | + } |
|
133 | 133 | |
134 | - $parameters['messages'] = $messages; |
|
135 | - if (!is_null($user) && $user !== '') { |
|
136 | - $parameters['loginName'] = $user; |
|
137 | - $parameters['user_autofocus'] = false; |
|
138 | - } else { |
|
139 | - $parameters['loginName'] = ''; |
|
140 | - $parameters['user_autofocus'] = true; |
|
141 | - } |
|
142 | - if (!empty($redirect_url)) { |
|
143 | - $parameters['redirect_url'] = $redirect_url; |
|
144 | - } |
|
134 | + $parameters['messages'] = $messages; |
|
135 | + if (!is_null($user) && $user !== '') { |
|
136 | + $parameters['loginName'] = $user; |
|
137 | + $parameters['user_autofocus'] = false; |
|
138 | + } else { |
|
139 | + $parameters['loginName'] = ''; |
|
140 | + $parameters['user_autofocus'] = true; |
|
141 | + } |
|
142 | + if (!empty($redirect_url)) { |
|
143 | + $parameters['redirect_url'] = $redirect_url; |
|
144 | + } |
|
145 | 145 | |
146 | - $parameters['canResetPassword'] = true; |
|
147 | - $parameters['resetPasswordLink'] = $this->config->getSystemValue('lost_password_link', ''); |
|
148 | - if (!$parameters['resetPasswordLink']) { |
|
149 | - if (!is_null($user) && $user !== '') { |
|
150 | - $userObj = $this->userManager->get($user); |
|
151 | - if ($userObj instanceof IUser) { |
|
152 | - $parameters['canResetPassword'] = $userObj->canChangePassword(); |
|
153 | - } |
|
154 | - } |
|
155 | - } |
|
146 | + $parameters['canResetPassword'] = true; |
|
147 | + $parameters['resetPasswordLink'] = $this->config->getSystemValue('lost_password_link', ''); |
|
148 | + if (!$parameters['resetPasswordLink']) { |
|
149 | + if (!is_null($user) && $user !== '') { |
|
150 | + $userObj = $this->userManager->get($user); |
|
151 | + if ($userObj instanceof IUser) { |
|
152 | + $parameters['canResetPassword'] = $userObj->canChangePassword(); |
|
153 | + } |
|
154 | + } |
|
155 | + } |
|
156 | 156 | |
157 | - $parameters['alt_login'] = OC_App::getAlternativeLogIns(); |
|
158 | - $parameters['rememberLoginAllowed'] = OC_Util::rememberLoginAllowed(); |
|
159 | - $parameters['rememberLoginState'] = !empty($remember_login) ? $remember_login : 0; |
|
157 | + $parameters['alt_login'] = OC_App::getAlternativeLogIns(); |
|
158 | + $parameters['rememberLoginAllowed'] = OC_Util::rememberLoginAllowed(); |
|
159 | + $parameters['rememberLoginState'] = !empty($remember_login) ? $remember_login : 0; |
|
160 | 160 | |
161 | - if (!is_null($user) && $user !== '') { |
|
162 | - $parameters['loginName'] = $user; |
|
163 | - $parameters['user_autofocus'] = false; |
|
164 | - } else { |
|
165 | - $parameters['loginName'] = ''; |
|
166 | - $parameters['user_autofocus'] = true; |
|
167 | - } |
|
161 | + if (!is_null($user) && $user !== '') { |
|
162 | + $parameters['loginName'] = $user; |
|
163 | + $parameters['user_autofocus'] = false; |
|
164 | + } else { |
|
165 | + $parameters['loginName'] = ''; |
|
166 | + $parameters['user_autofocus'] = true; |
|
167 | + } |
|
168 | 168 | |
169 | - return new TemplateResponse( |
|
170 | - $this->appName, 'login', $parameters, 'guest' |
|
171 | - ); |
|
172 | - } |
|
169 | + return new TemplateResponse( |
|
170 | + $this->appName, 'login', $parameters, 'guest' |
|
171 | + ); |
|
172 | + } |
|
173 | 173 | |
174 | - /** |
|
175 | - * @param string $redirectUrl |
|
176 | - * @return RedirectResponse |
|
177 | - */ |
|
178 | - private function generateRedirect($redirectUrl) { |
|
179 | - if (!is_null($redirectUrl) && $this->userSession->isLoggedIn()) { |
|
180 | - $location = $this->urlGenerator->getAbsoluteURL(urldecode($redirectUrl)); |
|
181 | - // Deny the redirect if the URL contains a @ |
|
182 | - // This prevents unvalidated redirects like ?redirect_url=:[email protected] |
|
183 | - if (strpos($location, '@') === false) { |
|
184 | - return new RedirectResponse($location); |
|
185 | - } |
|
186 | - } |
|
187 | - return new RedirectResponse(OC_Util::getDefaultPageUrl()); |
|
188 | - } |
|
174 | + /** |
|
175 | + * @param string $redirectUrl |
|
176 | + * @return RedirectResponse |
|
177 | + */ |
|
178 | + private function generateRedirect($redirectUrl) { |
|
179 | + if (!is_null($redirectUrl) && $this->userSession->isLoggedIn()) { |
|
180 | + $location = $this->urlGenerator->getAbsoluteURL(urldecode($redirectUrl)); |
|
181 | + // Deny the redirect if the URL contains a @ |
|
182 | + // This prevents unvalidated redirects like ?redirect_url=:[email protected] |
|
183 | + if (strpos($location, '@') === false) { |
|
184 | + return new RedirectResponse($location); |
|
185 | + } |
|
186 | + } |
|
187 | + return new RedirectResponse(OC_Util::getDefaultPageUrl()); |
|
188 | + } |
|
189 | 189 | |
190 | - /** |
|
191 | - * @PublicPage |
|
192 | - * @UseSession |
|
193 | - * @NoCSRFRequired |
|
194 | - * |
|
195 | - * @param string $user |
|
196 | - * @param string $password |
|
197 | - * @param string $redirect_url |
|
198 | - * @param string $timezone |
|
199 | - * @param string $timezone_offset |
|
200 | - * @return RedirectResponse |
|
201 | - */ |
|
202 | - public function tryLogin($user, $password, $redirect_url, $timezone = '', $timezone_offset = '') { |
|
203 | - $currentDelay = $this->throttler->getDelay($this->request->getRemoteAddress()); |
|
204 | - $this->throttler->sleepDelay($this->request->getRemoteAddress()); |
|
190 | + /** |
|
191 | + * @PublicPage |
|
192 | + * @UseSession |
|
193 | + * @NoCSRFRequired |
|
194 | + * |
|
195 | + * @param string $user |
|
196 | + * @param string $password |
|
197 | + * @param string $redirect_url |
|
198 | + * @param string $timezone |
|
199 | + * @param string $timezone_offset |
|
200 | + * @return RedirectResponse |
|
201 | + */ |
|
202 | + public function tryLogin($user, $password, $redirect_url, $timezone = '', $timezone_offset = '') { |
|
203 | + $currentDelay = $this->throttler->getDelay($this->request->getRemoteAddress()); |
|
204 | + $this->throttler->sleepDelay($this->request->getRemoteAddress()); |
|
205 | 205 | |
206 | - // If the user is already logged in and the CSRF check does not pass then |
|
207 | - // simply redirect the user to the correct page as required. This is the |
|
208 | - // case when an user has already logged-in, in another tab. |
|
209 | - if(!$this->request->passesCSRFCheck()) { |
|
210 | - return $this->generateRedirect($redirect_url); |
|
211 | - } |
|
206 | + // If the user is already logged in and the CSRF check does not pass then |
|
207 | + // simply redirect the user to the correct page as required. This is the |
|
208 | + // case when an user has already logged-in, in another tab. |
|
209 | + if(!$this->request->passesCSRFCheck()) { |
|
210 | + return $this->generateRedirect($redirect_url); |
|
211 | + } |
|
212 | 212 | |
213 | - $originalUser = $user; |
|
214 | - // TODO: Add all the insane error handling |
|
215 | - /* @var $loginResult IUser */ |
|
216 | - $loginResult = $this->userManager->checkPassword($user, $password); |
|
217 | - if ($loginResult === false) { |
|
218 | - $users = $this->userManager->getByEmail($user); |
|
219 | - // we only allow login by email if unique |
|
220 | - if (count($users) === 1) { |
|
221 | - $user = $users[0]->getUID(); |
|
222 | - $loginResult = $this->userManager->checkPassword($user, $password); |
|
223 | - } |
|
224 | - } |
|
225 | - if ($loginResult === false) { |
|
226 | - $this->throttler->registerAttempt('login', $this->request->getRemoteAddress(), ['user' => $originalUser]); |
|
227 | - if($currentDelay === 0) { |
|
228 | - $this->throttler->sleepDelay($this->request->getRemoteAddress()); |
|
229 | - } |
|
230 | - $this->session->set('loginMessages', [ |
|
231 | - ['invalidpassword'], [] |
|
232 | - ]); |
|
233 | - // Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name |
|
234 | - $args = !is_null($user) ? ['user' => $originalUser] : []; |
|
235 | - return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args)); |
|
236 | - } |
|
237 | - // TODO: remove password checks from above and let the user session handle failures |
|
238 | - // requires https://github.com/owncloud/core/pull/24616 |
|
239 | - $this->userSession->login($user, $password); |
|
240 | - $this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password); |
|
213 | + $originalUser = $user; |
|
214 | + // TODO: Add all the insane error handling |
|
215 | + /* @var $loginResult IUser */ |
|
216 | + $loginResult = $this->userManager->checkPassword($user, $password); |
|
217 | + if ($loginResult === false) { |
|
218 | + $users = $this->userManager->getByEmail($user); |
|
219 | + // we only allow login by email if unique |
|
220 | + if (count($users) === 1) { |
|
221 | + $user = $users[0]->getUID(); |
|
222 | + $loginResult = $this->userManager->checkPassword($user, $password); |
|
223 | + } |
|
224 | + } |
|
225 | + if ($loginResult === false) { |
|
226 | + $this->throttler->registerAttempt('login', $this->request->getRemoteAddress(), ['user' => $originalUser]); |
|
227 | + if($currentDelay === 0) { |
|
228 | + $this->throttler->sleepDelay($this->request->getRemoteAddress()); |
|
229 | + } |
|
230 | + $this->session->set('loginMessages', [ |
|
231 | + ['invalidpassword'], [] |
|
232 | + ]); |
|
233 | + // Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name |
|
234 | + $args = !is_null($user) ? ['user' => $originalUser] : []; |
|
235 | + return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args)); |
|
236 | + } |
|
237 | + // TODO: remove password checks from above and let the user session handle failures |
|
238 | + // requires https://github.com/owncloud/core/pull/24616 |
|
239 | + $this->userSession->login($user, $password); |
|
240 | + $this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password); |
|
241 | 241 | |
242 | - if ($timezone_offset !== '') { |
|
243 | - $this->config->setUserValue($loginResult->getUID(), 'core', 'timezone', $timezone); |
|
244 | - $this->session->set('timezone', $timezone_offset); |
|
245 | - } |
|
242 | + if ($timezone_offset !== '') { |
|
243 | + $this->config->setUserValue($loginResult->getUID(), 'core', 'timezone', $timezone); |
|
244 | + $this->session->set('timezone', $timezone_offset); |
|
245 | + } |
|
246 | 246 | |
247 | - if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) { |
|
248 | - $this->twoFactorManager->prepareTwoFactorLogin($loginResult); |
|
249 | - if (!is_null($redirect_url)) { |
|
250 | - return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge', [ |
|
251 | - 'redirect_url' => $redirect_url |
|
252 | - ])); |
|
253 | - } |
|
254 | - return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge')); |
|
255 | - } |
|
247 | + if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) { |
|
248 | + $this->twoFactorManager->prepareTwoFactorLogin($loginResult); |
|
249 | + if (!is_null($redirect_url)) { |
|
250 | + return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge', [ |
|
251 | + 'redirect_url' => $redirect_url |
|
252 | + ])); |
|
253 | + } |
|
254 | + return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge')); |
|
255 | + } |
|
256 | 256 | |
257 | - return $this->generateRedirect($redirect_url); |
|
258 | - } |
|
257 | + return $this->generateRedirect($redirect_url); |
|
258 | + } |
|
259 | 259 | |
260 | 260 | } |
@@ -206,7 +206,7 @@ discard block |
||
206 | 206 | // If the user is already logged in and the CSRF check does not pass then |
207 | 207 | // simply redirect the user to the correct page as required. This is the |
208 | 208 | // case when an user has already logged-in, in another tab. |
209 | - if(!$this->request->passesCSRFCheck()) { |
|
209 | + if (!$this->request->passesCSRFCheck()) { |
|
210 | 210 | return $this->generateRedirect($redirect_url); |
211 | 211 | } |
212 | 212 | |
@@ -224,7 +224,7 @@ discard block |
||
224 | 224 | } |
225 | 225 | if ($loginResult === false) { |
226 | 226 | $this->throttler->registerAttempt('login', $this->request->getRemoteAddress(), ['user' => $originalUser]); |
227 | - if($currentDelay === 0) { |
|
227 | + if ($currentDelay === 0) { |
|
228 | 228 | $this->throttler->sleepDelay($this->request->getRemoteAddress()); |
229 | 229 | } |
230 | 230 | $this->session->set('loginMessages', [ |
@@ -22,13 +22,10 @@ |
||
22 | 22 | namespace OC\Core\Controller; |
23 | 23 | |
24 | 24 | use OC\AppFramework\Http; |
25 | -use OC\AppFramework\Utility\TimeFactory; |
|
26 | -use OC\Authentication\Token\DefaultTokenProvider; |
|
27 | 25 | use OC\Authentication\Token\IProvider; |
28 | 26 | use OC\Authentication\Token\IToken; |
29 | 27 | use OC\Authentication\TwoFactorAuth\Manager as TwoFactorAuthManager; |
30 | 28 | use OC\User\Manager as UserManager; |
31 | -use OCA\User_LDAP\User\Manager; |
|
32 | 29 | use OCP\AppFramework\Controller; |
33 | 30 | use OCP\AppFramework\Http\JSONResponse; |
34 | 31 | use OCP\IRequest; |
@@ -37,72 +37,72 @@ |
||
37 | 37 | use OCP\Security\ISecureRandom; |
38 | 38 | |
39 | 39 | class TokenController extends Controller { |
40 | - /** @var UserManager */ |
|
41 | - private $userManager; |
|
42 | - /** @var IProvider */ |
|
43 | - private $tokenProvider; |
|
44 | - /** @var TwoFactorAuthManager */ |
|
45 | - private $twoFactorAuthManager; |
|
46 | - /** @var ISecureRandom */ |
|
47 | - private $secureRandom; |
|
40 | + /** @var UserManager */ |
|
41 | + private $userManager; |
|
42 | + /** @var IProvider */ |
|
43 | + private $tokenProvider; |
|
44 | + /** @var TwoFactorAuthManager */ |
|
45 | + private $twoFactorAuthManager; |
|
46 | + /** @var ISecureRandom */ |
|
47 | + private $secureRandom; |
|
48 | 48 | |
49 | - /** |
|
50 | - * @param string $appName |
|
51 | - * @param IRequest $request |
|
52 | - * @param UserManager $userManager |
|
53 | - * @param IProvider $tokenProvider |
|
54 | - * @param TwoFactorAuthManager $twoFactorAuthManager |
|
55 | - * @param ISecureRandom $secureRandom |
|
56 | - */ |
|
57 | - public function __construct($appName, |
|
58 | - IRequest $request, |
|
59 | - UserManager $userManager, |
|
60 | - IProvider $tokenProvider, |
|
61 | - TwoFactorAuthManager $twoFactorAuthManager, |
|
62 | - ISecureRandom $secureRandom) { |
|
63 | - parent::__construct($appName, $request); |
|
64 | - $this->userManager = $userManager; |
|
65 | - $this->tokenProvider = $tokenProvider; |
|
66 | - $this->secureRandom = $secureRandom; |
|
67 | - $this->twoFactorAuthManager = $twoFactorAuthManager; |
|
68 | - } |
|
49 | + /** |
|
50 | + * @param string $appName |
|
51 | + * @param IRequest $request |
|
52 | + * @param UserManager $userManager |
|
53 | + * @param IProvider $tokenProvider |
|
54 | + * @param TwoFactorAuthManager $twoFactorAuthManager |
|
55 | + * @param ISecureRandom $secureRandom |
|
56 | + */ |
|
57 | + public function __construct($appName, |
|
58 | + IRequest $request, |
|
59 | + UserManager $userManager, |
|
60 | + IProvider $tokenProvider, |
|
61 | + TwoFactorAuthManager $twoFactorAuthManager, |
|
62 | + ISecureRandom $secureRandom) { |
|
63 | + parent::__construct($appName, $request); |
|
64 | + $this->userManager = $userManager; |
|
65 | + $this->tokenProvider = $tokenProvider; |
|
66 | + $this->secureRandom = $secureRandom; |
|
67 | + $this->twoFactorAuthManager = $twoFactorAuthManager; |
|
68 | + } |
|
69 | 69 | |
70 | - /** |
|
71 | - * Generate a new access token clients can authenticate with |
|
72 | - * |
|
73 | - * @PublicPage |
|
74 | - * @NoCSRFRequired |
|
75 | - * |
|
76 | - * @param string $user |
|
77 | - * @param string $password |
|
78 | - * @param string $name the name of the client |
|
79 | - * @return JSONResponse |
|
80 | - */ |
|
81 | - public function generateToken($user, $password, $name = 'unknown client') { |
|
82 | - if (is_null($user) || is_null($password)) { |
|
83 | - $response = new JSONResponse(); |
|
84 | - $response->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); |
|
85 | - return $response; |
|
86 | - } |
|
87 | - $loginName = $user; |
|
88 | - $user = $this->userManager->checkPassword($loginName, $password); |
|
89 | - if ($user === false) { |
|
90 | - $response = new JSONResponse(); |
|
91 | - $response->setStatus(Http::STATUS_UNAUTHORIZED); |
|
92 | - return $response; |
|
93 | - } |
|
70 | + /** |
|
71 | + * Generate a new access token clients can authenticate with |
|
72 | + * |
|
73 | + * @PublicPage |
|
74 | + * @NoCSRFRequired |
|
75 | + * |
|
76 | + * @param string $user |
|
77 | + * @param string $password |
|
78 | + * @param string $name the name of the client |
|
79 | + * @return JSONResponse |
|
80 | + */ |
|
81 | + public function generateToken($user, $password, $name = 'unknown client') { |
|
82 | + if (is_null($user) || is_null($password)) { |
|
83 | + $response = new JSONResponse(); |
|
84 | + $response->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); |
|
85 | + return $response; |
|
86 | + } |
|
87 | + $loginName = $user; |
|
88 | + $user = $this->userManager->checkPassword($loginName, $password); |
|
89 | + if ($user === false) { |
|
90 | + $response = new JSONResponse(); |
|
91 | + $response->setStatus(Http::STATUS_UNAUTHORIZED); |
|
92 | + return $response; |
|
93 | + } |
|
94 | 94 | |
95 | - if ($this->twoFactorAuthManager->isTwoFactorAuthenticated($user)) { |
|
96 | - $resp = new JSONResponse(); |
|
97 | - $resp->setStatus(Http::STATUS_UNAUTHORIZED); |
|
98 | - return $resp; |
|
99 | - } |
|
95 | + if ($this->twoFactorAuthManager->isTwoFactorAuthenticated($user)) { |
|
96 | + $resp = new JSONResponse(); |
|
97 | + $resp->setStatus(Http::STATUS_UNAUTHORIZED); |
|
98 | + return $resp; |
|
99 | + } |
|
100 | 100 | |
101 | - $token = $this->secureRandom->generate(128); |
|
102 | - $this->tokenProvider->generateToken($token, $user->getUID(), $loginName, $password, $name, IToken::PERMANENT_TOKEN); |
|
103 | - return [ |
|
104 | - 'token' => $token, |
|
105 | - ]; |
|
106 | - } |
|
101 | + $token = $this->secureRandom->generate(128); |
|
102 | + $this->tokenProvider->generateToken($token, $user->getUID(), $loginName, $password, $name, IToken::PERMANENT_TOKEN); |
|
103 | + return [ |
|
104 | + 'token' => $token, |
|
105 | + ]; |
|
106 | + } |
|
107 | 107 | |
108 | 108 | } |
@@ -219,7 +219,7 @@ |
||
219 | 219 | * @param array $groupSharesById |
220 | 220 | * @param array $subShares |
221 | 221 | * |
222 | - * @return true if the share is valid, false if it needs repair |
|
222 | + * @return boolean if the share is valid, false if it needs repair |
|
223 | 223 | */ |
224 | 224 | private function isThisShareValid($groupSharesById, $subShares) { |
225 | 225 | $foundTargets = []; |
@@ -173,7 +173,7 @@ discard block |
||
173 | 173 | $pickedShare = null; |
174 | 174 | // sort by stime, this also properly sorts the direct user share if any |
175 | 175 | @usort($subShares, function($a, $b) { |
176 | - return ((int)$a['stime'] - (int)$b['stime']); |
|
176 | + return ((int) $a['stime'] - (int) $b['stime']); |
|
177 | 177 | }); |
178 | 178 | |
179 | 179 | foreach ($subShares as $subShare) { |
@@ -222,7 +222,7 @@ discard block |
||
222 | 222 | // check whether the user opted out completely of all subshares |
223 | 223 | $optedOut = true; |
224 | 224 | foreach ($subShares as $subShare) { |
225 | - if ((int)$subShare['permissions'] !== 0) { |
|
225 | + if ((int) $subShare['permissions'] !== 0) { |
|
226 | 226 | $optedOut = false; |
227 | 227 | break; |
228 | 228 | } |
@@ -231,7 +231,7 @@ discard block |
||
231 | 231 | $shareIds = []; |
232 | 232 | foreach ($subShares as $subShare) { |
233 | 233 | // only if the user deleted some subshares but not all, adjust the permissions of that subshare |
234 | - if (!$optedOut && (int)$subShare['permissions'] === 0 && (int)$subShare['share_type'] === DefaultShareProvider::SHARE_TYPE_USERGROUP) { |
|
234 | + if (!$optedOut && (int) $subShare['permissions'] === 0 && (int) $subShare['share_type'] === DefaultShareProvider::SHARE_TYPE_USERGROUP) { |
|
235 | 235 | // set permissions from parent group share |
236 | 236 | $permissions = $groupSharesById[$subShare['parent']]['permissions']; |
237 | 237 | |
@@ -244,7 +244,7 @@ discard block |
||
244 | 244 | } else { |
245 | 245 | // gather share ids for bulk target update |
246 | 246 | if ($subShare['file_target'] !== $targetPath) { |
247 | - $shareIds[] = (int)$subShare['id']; |
|
247 | + $shareIds[] = (int) $subShare['id']; |
|
248 | 248 | } |
249 | 249 | } |
250 | 250 | } |
@@ -43,332 +43,332 @@ |
||
43 | 43 | */ |
44 | 44 | class RepairUnmergedShares implements IRepairStep { |
45 | 45 | |
46 | - /** @var \OCP\IConfig */ |
|
47 | - protected $config; |
|
48 | - |
|
49 | - /** @var \OCP\IDBConnection */ |
|
50 | - protected $connection; |
|
51 | - |
|
52 | - /** @var IUserManager */ |
|
53 | - protected $userManager; |
|
54 | - |
|
55 | - /** @var IGroupManager */ |
|
56 | - protected $groupManager; |
|
57 | - |
|
58 | - /** @var IQueryBuilder */ |
|
59 | - private $queryGetSharesWithUsers; |
|
60 | - |
|
61 | - /** @var IQueryBuilder */ |
|
62 | - private $queryUpdateSharePermissionsAndTarget; |
|
63 | - |
|
64 | - /** @var IQueryBuilder */ |
|
65 | - private $queryUpdateShareInBatch; |
|
66 | - |
|
67 | - /** |
|
68 | - * @param \OCP\IConfig $config |
|
69 | - * @param \OCP\IDBConnection $connection |
|
70 | - */ |
|
71 | - public function __construct( |
|
72 | - IConfig $config, |
|
73 | - IDBConnection $connection, |
|
74 | - IUserManager $userManager, |
|
75 | - IGroupManager $groupManager |
|
76 | - ) { |
|
77 | - $this->connection = $connection; |
|
78 | - $this->config = $config; |
|
79 | - $this->userManager = $userManager; |
|
80 | - $this->groupManager = $groupManager; |
|
81 | - } |
|
82 | - |
|
83 | - public function getName() { |
|
84 | - return 'Repair unmerged shares'; |
|
85 | - } |
|
86 | - |
|
87 | - /** |
|
88 | - * Builds prepared queries for reuse |
|
89 | - */ |
|
90 | - private function buildPreparedQueries() { |
|
91 | - /** |
|
92 | - * Retrieve shares for a given user/group and share type |
|
93 | - */ |
|
94 | - $query = $this->connection->getQueryBuilder(); |
|
95 | - $query |
|
96 | - ->select('item_source', 'id', 'file_target', 'permissions', 'parent', 'share_type', 'stime') |
|
97 | - ->from('share') |
|
98 | - ->where($query->expr()->eq('share_type', $query->createParameter('shareType'))) |
|
99 | - ->andWhere($query->expr()->in('share_with', $query->createParameter('shareWiths'))) |
|
100 | - ->andWhere($query->expr()->in('item_type', $query->createParameter('itemTypes'))) |
|
101 | - ->orderBy('item_source', 'ASC') |
|
102 | - ->addOrderBy('stime', 'ASC'); |
|
103 | - |
|
104 | - $this->queryGetSharesWithUsers = $query; |
|
105 | - |
|
106 | - /** |
|
107 | - * Updates the file_target to the given value for all given share ids. |
|
108 | - * |
|
109 | - * This updates several shares in bulk which is faster than individually. |
|
110 | - */ |
|
111 | - $query = $this->connection->getQueryBuilder(); |
|
112 | - $query->update('share') |
|
113 | - ->set('file_target', $query->createParameter('file_target')) |
|
114 | - ->where($query->expr()->in('id', $query->createParameter('ids'))); |
|
115 | - |
|
116 | - $this->queryUpdateShareInBatch = $query; |
|
117 | - |
|
118 | - /** |
|
119 | - * Updates the share permissions and target path of a single share. |
|
120 | - */ |
|
121 | - $query = $this->connection->getQueryBuilder(); |
|
122 | - $query->update('share') |
|
123 | - ->set('permissions', $query->createParameter('permissions')) |
|
124 | - ->set('file_target', $query->createParameter('file_target')) |
|
125 | - ->where($query->expr()->eq('id', $query->createParameter('shareid'))); |
|
126 | - |
|
127 | - $this->queryUpdateSharePermissionsAndTarget = $query; |
|
128 | - |
|
129 | - } |
|
130 | - |
|
131 | - private function getSharesWithUser($shareType, $shareWiths) { |
|
132 | - $groupedShares = []; |
|
133 | - |
|
134 | - $query = $this->queryGetSharesWithUsers; |
|
135 | - $query->setParameter('shareWiths', $shareWiths, IQueryBuilder::PARAM_STR_ARRAY); |
|
136 | - $query->setParameter('shareType', $shareType); |
|
137 | - $query->setParameter('itemTypes', ['file', 'folder'], IQueryBuilder::PARAM_STR_ARRAY); |
|
138 | - |
|
139 | - $shares = $query->execute()->fetchAll(); |
|
140 | - |
|
141 | - // group by item_source |
|
142 | - foreach ($shares as $share) { |
|
143 | - if (!isset($groupedShares[$share['item_source']])) { |
|
144 | - $groupedShares[$share['item_source']] = []; |
|
145 | - } |
|
146 | - $groupedShares[$share['item_source']][] = $share; |
|
147 | - } |
|
148 | - return $groupedShares; |
|
149 | - } |
|
150 | - |
|
151 | - private function isPotentialDuplicateName($name) { |
|
152 | - return (preg_match('/\(\d+\)(\.[^\.]+)?$/', $name) === 1); |
|
153 | - } |
|
154 | - |
|
155 | - /** |
|
156 | - * Decide on the best target name based on all group shares and subshares, |
|
157 | - * goal is to increase the likeliness that the chosen name matches what |
|
158 | - * the user is expecting. |
|
159 | - * |
|
160 | - * For this, we discard the entries with parenthesis "(2)". |
|
161 | - * In case the user also renamed the duplicates to a legitimate name, this logic |
|
162 | - * will still pick the most recent one as it's the one the user is most likely to |
|
163 | - * remember renaming. |
|
164 | - * |
|
165 | - * If no suitable subshare is found, use the least recent group share instead. |
|
166 | - * |
|
167 | - * @param array $groupShares group share entries |
|
168 | - * @param array $subShares sub share entries |
|
169 | - * |
|
170 | - * @return string chosen target name |
|
171 | - */ |
|
172 | - private function findBestTargetName($groupShares, $subShares) { |
|
173 | - $pickedShare = null; |
|
174 | - // sort by stime, this also properly sorts the direct user share if any |
|
175 | - @usort($subShares, function($a, $b) { |
|
176 | - return ((int)$a['stime'] - (int)$b['stime']); |
|
177 | - }); |
|
178 | - |
|
179 | - foreach ($subShares as $subShare) { |
|
180 | - // skip entries that have parenthesis with numbers |
|
181 | - if ($this->isPotentialDuplicateName($subShare['file_target'])) { |
|
182 | - continue; |
|
183 | - } |
|
184 | - // pick any share found that would match, the last being the most recent |
|
185 | - $pickedShare = $subShare; |
|
186 | - } |
|
187 | - |
|
188 | - // no suitable subshare found |
|
189 | - if ($pickedShare === null) { |
|
190 | - // use least recent group share target instead |
|
191 | - $pickedShare = $groupShares[0]; |
|
192 | - } |
|
193 | - |
|
194 | - return $pickedShare['file_target']; |
|
195 | - } |
|
196 | - |
|
197 | - /** |
|
198 | - * Fix the given received share represented by the set of group shares |
|
199 | - * and matching sub shares |
|
200 | - * |
|
201 | - * @param array $groupShares group share entries |
|
202 | - * @param array $subShares sub share entries |
|
203 | - * |
|
204 | - * @return boolean false if the share was not repaired, true if it was |
|
205 | - */ |
|
206 | - private function fixThisShare($groupShares, $subShares) { |
|
207 | - if (empty($subShares)) { |
|
208 | - return false; |
|
209 | - } |
|
210 | - |
|
211 | - $groupSharesById = []; |
|
212 | - foreach ($groupShares as $groupShare) { |
|
213 | - $groupSharesById[$groupShare['id']] = $groupShare; |
|
214 | - } |
|
215 | - |
|
216 | - if ($this->isThisShareValid($groupSharesById, $subShares)) { |
|
217 | - return false; |
|
218 | - } |
|
219 | - |
|
220 | - $targetPath = $this->findBestTargetName($groupShares, $subShares); |
|
221 | - |
|
222 | - // check whether the user opted out completely of all subshares |
|
223 | - $optedOut = true; |
|
224 | - foreach ($subShares as $subShare) { |
|
225 | - if ((int)$subShare['permissions'] !== 0) { |
|
226 | - $optedOut = false; |
|
227 | - break; |
|
228 | - } |
|
229 | - } |
|
230 | - |
|
231 | - $shareIds = []; |
|
232 | - foreach ($subShares as $subShare) { |
|
233 | - // only if the user deleted some subshares but not all, adjust the permissions of that subshare |
|
234 | - if (!$optedOut && (int)$subShare['permissions'] === 0 && (int)$subShare['share_type'] === DefaultShareProvider::SHARE_TYPE_USERGROUP) { |
|
235 | - // set permissions from parent group share |
|
236 | - $permissions = $groupSharesById[$subShare['parent']]['permissions']; |
|
237 | - |
|
238 | - // fix permissions and target directly |
|
239 | - $query = $this->queryUpdateSharePermissionsAndTarget; |
|
240 | - $query->setParameter('shareid', $subShare['id']); |
|
241 | - $query->setParameter('file_target', $targetPath); |
|
242 | - $query->setParameter('permissions', $permissions); |
|
243 | - $query->execute(); |
|
244 | - } else { |
|
245 | - // gather share ids for bulk target update |
|
246 | - if ($subShare['file_target'] !== $targetPath) { |
|
247 | - $shareIds[] = (int)$subShare['id']; |
|
248 | - } |
|
249 | - } |
|
250 | - } |
|
251 | - |
|
252 | - if (!empty($shareIds)) { |
|
253 | - $query = $this->queryUpdateShareInBatch; |
|
254 | - $query->setParameter('ids', $shareIds, IQueryBuilder::PARAM_INT_ARRAY); |
|
255 | - $query->setParameter('file_target', $targetPath); |
|
256 | - $query->execute(); |
|
257 | - } |
|
258 | - |
|
259 | - return true; |
|
260 | - } |
|
261 | - |
|
262 | - /** |
|
263 | - * Checks whether the number of group shares is balanced with the child subshares. |
|
264 | - * If all group shares have exactly one subshare, and the target of every subshare |
|
265 | - * is the same, then the share is valid. |
|
266 | - * If however there is a group share entry that has no matching subshare, it means |
|
267 | - * we're in the bogus situation and the whole share must be repaired |
|
268 | - * |
|
269 | - * @param array $groupSharesById |
|
270 | - * @param array $subShares |
|
271 | - * |
|
272 | - * @return true if the share is valid, false if it needs repair |
|
273 | - */ |
|
274 | - private function isThisShareValid($groupSharesById, $subShares) { |
|
275 | - $foundTargets = []; |
|
276 | - |
|
277 | - // every group share needs to have exactly one matching subshare |
|
278 | - foreach ($subShares as $subShare) { |
|
279 | - $foundTargets[$subShare['file_target']] = true; |
|
280 | - if (count($foundTargets) > 1) { |
|
281 | - // not all the same target path value => invalid |
|
282 | - return false; |
|
283 | - } |
|
284 | - if (isset($groupSharesById[$subShare['parent']])) { |
|
285 | - // remove it from the list as we found it |
|
286 | - unset($groupSharesById[$subShare['parent']]); |
|
287 | - } |
|
288 | - } |
|
289 | - |
|
290 | - // if we found one subshare per group entry, the set will be empty. |
|
291 | - // If not empty, it means that one of the group shares did not have |
|
292 | - // a matching subshare entry. |
|
293 | - return empty($groupSharesById); |
|
294 | - } |
|
295 | - |
|
296 | - /** |
|
297 | - * Detect unmerged received shares and merge them properly |
|
298 | - */ |
|
299 | - private function fixUnmergedShares(IOutput $out, IUser $user) { |
|
300 | - $groups = $this->groupManager->getUserGroupIds($user); |
|
301 | - if (empty($groups)) { |
|
302 | - // user is in no groups, so can't have received group shares |
|
303 | - return; |
|
304 | - } |
|
305 | - |
|
306 | - // get all subshares grouped by item source |
|
307 | - $subSharesByItemSource = $this->getSharesWithUser(DefaultShareProvider::SHARE_TYPE_USERGROUP, [$user->getUID()]); |
|
308 | - |
|
309 | - // because sometimes one wants to give the user more permissions than the group share |
|
310 | - $userSharesByItemSource = $this->getSharesWithUser(Constants::SHARE_TYPE_USER, [$user->getUID()]); |
|
311 | - |
|
312 | - if (empty($subSharesByItemSource) && empty($userSharesByItemSource)) { |
|
313 | - // nothing to repair for this user, no need to do extra queries |
|
314 | - return; |
|
315 | - } |
|
316 | - |
|
317 | - $groupSharesByItemSource = $this->getSharesWithUser(Constants::SHARE_TYPE_GROUP, $groups); |
|
318 | - if (empty($groupSharesByItemSource) && empty($userSharesByItemSource)) { |
|
319 | - // nothing to repair for this user |
|
320 | - return; |
|
321 | - } |
|
322 | - |
|
323 | - foreach ($groupSharesByItemSource as $itemSource => $groupShares) { |
|
324 | - $subShares = []; |
|
325 | - if (isset($subSharesByItemSource[$itemSource])) { |
|
326 | - $subShares = $subSharesByItemSource[$itemSource]; |
|
327 | - } |
|
328 | - |
|
329 | - if (isset($userSharesByItemSource[$itemSource])) { |
|
330 | - // add it to the subshares to get a similar treatment |
|
331 | - $subShares = array_merge($subShares, $userSharesByItemSource[$itemSource]); |
|
332 | - } |
|
333 | - |
|
334 | - $this->fixThisShare($groupShares, $subShares); |
|
335 | - } |
|
336 | - } |
|
337 | - |
|
338 | - /** |
|
339 | - * Count all the users |
|
340 | - * |
|
341 | - * @return int |
|
342 | - */ |
|
343 | - private function countUsers() { |
|
344 | - $allCount = $this->userManager->countUsers(); |
|
345 | - |
|
346 | - $totalCount = 0; |
|
347 | - foreach ($allCount as $backend => $count) { |
|
348 | - $totalCount += $count; |
|
349 | - } |
|
350 | - |
|
351 | - return $totalCount; |
|
352 | - } |
|
353 | - |
|
354 | - public function run(IOutput $output) { |
|
355 | - $ocVersionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0'); |
|
356 | - if (version_compare($ocVersionFromBeforeUpdate, '9.1.0.16', '<')) { |
|
357 | - // this situation was only possible between 9.0.0 and 9.0.3 included |
|
358 | - |
|
359 | - $function = function(IUser $user) use ($output) { |
|
360 | - $this->fixUnmergedShares($output, $user); |
|
361 | - $output->advance(); |
|
362 | - }; |
|
363 | - |
|
364 | - $this->buildPreparedQueries(); |
|
365 | - |
|
366 | - $userCount = $this->countUsers(); |
|
367 | - $output->startProgress($userCount); |
|
368 | - |
|
369 | - $this->userManager->callForAllUsers($function); |
|
370 | - |
|
371 | - $output->finishProgress(); |
|
372 | - } |
|
373 | - } |
|
46 | + /** @var \OCP\IConfig */ |
|
47 | + protected $config; |
|
48 | + |
|
49 | + /** @var \OCP\IDBConnection */ |
|
50 | + protected $connection; |
|
51 | + |
|
52 | + /** @var IUserManager */ |
|
53 | + protected $userManager; |
|
54 | + |
|
55 | + /** @var IGroupManager */ |
|
56 | + protected $groupManager; |
|
57 | + |
|
58 | + /** @var IQueryBuilder */ |
|
59 | + private $queryGetSharesWithUsers; |
|
60 | + |
|
61 | + /** @var IQueryBuilder */ |
|
62 | + private $queryUpdateSharePermissionsAndTarget; |
|
63 | + |
|
64 | + /** @var IQueryBuilder */ |
|
65 | + private $queryUpdateShareInBatch; |
|
66 | + |
|
67 | + /** |
|
68 | + * @param \OCP\IConfig $config |
|
69 | + * @param \OCP\IDBConnection $connection |
|
70 | + */ |
|
71 | + public function __construct( |
|
72 | + IConfig $config, |
|
73 | + IDBConnection $connection, |
|
74 | + IUserManager $userManager, |
|
75 | + IGroupManager $groupManager |
|
76 | + ) { |
|
77 | + $this->connection = $connection; |
|
78 | + $this->config = $config; |
|
79 | + $this->userManager = $userManager; |
|
80 | + $this->groupManager = $groupManager; |
|
81 | + } |
|
82 | + |
|
83 | + public function getName() { |
|
84 | + return 'Repair unmerged shares'; |
|
85 | + } |
|
86 | + |
|
87 | + /** |
|
88 | + * Builds prepared queries for reuse |
|
89 | + */ |
|
90 | + private function buildPreparedQueries() { |
|
91 | + /** |
|
92 | + * Retrieve shares for a given user/group and share type |
|
93 | + */ |
|
94 | + $query = $this->connection->getQueryBuilder(); |
|
95 | + $query |
|
96 | + ->select('item_source', 'id', 'file_target', 'permissions', 'parent', 'share_type', 'stime') |
|
97 | + ->from('share') |
|
98 | + ->where($query->expr()->eq('share_type', $query->createParameter('shareType'))) |
|
99 | + ->andWhere($query->expr()->in('share_with', $query->createParameter('shareWiths'))) |
|
100 | + ->andWhere($query->expr()->in('item_type', $query->createParameter('itemTypes'))) |
|
101 | + ->orderBy('item_source', 'ASC') |
|
102 | + ->addOrderBy('stime', 'ASC'); |
|
103 | + |
|
104 | + $this->queryGetSharesWithUsers = $query; |
|
105 | + |
|
106 | + /** |
|
107 | + * Updates the file_target to the given value for all given share ids. |
|
108 | + * |
|
109 | + * This updates several shares in bulk which is faster than individually. |
|
110 | + */ |
|
111 | + $query = $this->connection->getQueryBuilder(); |
|
112 | + $query->update('share') |
|
113 | + ->set('file_target', $query->createParameter('file_target')) |
|
114 | + ->where($query->expr()->in('id', $query->createParameter('ids'))); |
|
115 | + |
|
116 | + $this->queryUpdateShareInBatch = $query; |
|
117 | + |
|
118 | + /** |
|
119 | + * Updates the share permissions and target path of a single share. |
|
120 | + */ |
|
121 | + $query = $this->connection->getQueryBuilder(); |
|
122 | + $query->update('share') |
|
123 | + ->set('permissions', $query->createParameter('permissions')) |
|
124 | + ->set('file_target', $query->createParameter('file_target')) |
|
125 | + ->where($query->expr()->eq('id', $query->createParameter('shareid'))); |
|
126 | + |
|
127 | + $this->queryUpdateSharePermissionsAndTarget = $query; |
|
128 | + |
|
129 | + } |
|
130 | + |
|
131 | + private function getSharesWithUser($shareType, $shareWiths) { |
|
132 | + $groupedShares = []; |
|
133 | + |
|
134 | + $query = $this->queryGetSharesWithUsers; |
|
135 | + $query->setParameter('shareWiths', $shareWiths, IQueryBuilder::PARAM_STR_ARRAY); |
|
136 | + $query->setParameter('shareType', $shareType); |
|
137 | + $query->setParameter('itemTypes', ['file', 'folder'], IQueryBuilder::PARAM_STR_ARRAY); |
|
138 | + |
|
139 | + $shares = $query->execute()->fetchAll(); |
|
140 | + |
|
141 | + // group by item_source |
|
142 | + foreach ($shares as $share) { |
|
143 | + if (!isset($groupedShares[$share['item_source']])) { |
|
144 | + $groupedShares[$share['item_source']] = []; |
|
145 | + } |
|
146 | + $groupedShares[$share['item_source']][] = $share; |
|
147 | + } |
|
148 | + return $groupedShares; |
|
149 | + } |
|
150 | + |
|
151 | + private function isPotentialDuplicateName($name) { |
|
152 | + return (preg_match('/\(\d+\)(\.[^\.]+)?$/', $name) === 1); |
|
153 | + } |
|
154 | + |
|
155 | + /** |
|
156 | + * Decide on the best target name based on all group shares and subshares, |
|
157 | + * goal is to increase the likeliness that the chosen name matches what |
|
158 | + * the user is expecting. |
|
159 | + * |
|
160 | + * For this, we discard the entries with parenthesis "(2)". |
|
161 | + * In case the user also renamed the duplicates to a legitimate name, this logic |
|
162 | + * will still pick the most recent one as it's the one the user is most likely to |
|
163 | + * remember renaming. |
|
164 | + * |
|
165 | + * If no suitable subshare is found, use the least recent group share instead. |
|
166 | + * |
|
167 | + * @param array $groupShares group share entries |
|
168 | + * @param array $subShares sub share entries |
|
169 | + * |
|
170 | + * @return string chosen target name |
|
171 | + */ |
|
172 | + private function findBestTargetName($groupShares, $subShares) { |
|
173 | + $pickedShare = null; |
|
174 | + // sort by stime, this also properly sorts the direct user share if any |
|
175 | + @usort($subShares, function($a, $b) { |
|
176 | + return ((int)$a['stime'] - (int)$b['stime']); |
|
177 | + }); |
|
178 | + |
|
179 | + foreach ($subShares as $subShare) { |
|
180 | + // skip entries that have parenthesis with numbers |
|
181 | + if ($this->isPotentialDuplicateName($subShare['file_target'])) { |
|
182 | + continue; |
|
183 | + } |
|
184 | + // pick any share found that would match, the last being the most recent |
|
185 | + $pickedShare = $subShare; |
|
186 | + } |
|
187 | + |
|
188 | + // no suitable subshare found |
|
189 | + if ($pickedShare === null) { |
|
190 | + // use least recent group share target instead |
|
191 | + $pickedShare = $groupShares[0]; |
|
192 | + } |
|
193 | + |
|
194 | + return $pickedShare['file_target']; |
|
195 | + } |
|
196 | + |
|
197 | + /** |
|
198 | + * Fix the given received share represented by the set of group shares |
|
199 | + * and matching sub shares |
|
200 | + * |
|
201 | + * @param array $groupShares group share entries |
|
202 | + * @param array $subShares sub share entries |
|
203 | + * |
|
204 | + * @return boolean false if the share was not repaired, true if it was |
|
205 | + */ |
|
206 | + private function fixThisShare($groupShares, $subShares) { |
|
207 | + if (empty($subShares)) { |
|
208 | + return false; |
|
209 | + } |
|
210 | + |
|
211 | + $groupSharesById = []; |
|
212 | + foreach ($groupShares as $groupShare) { |
|
213 | + $groupSharesById[$groupShare['id']] = $groupShare; |
|
214 | + } |
|
215 | + |
|
216 | + if ($this->isThisShareValid($groupSharesById, $subShares)) { |
|
217 | + return false; |
|
218 | + } |
|
219 | + |
|
220 | + $targetPath = $this->findBestTargetName($groupShares, $subShares); |
|
221 | + |
|
222 | + // check whether the user opted out completely of all subshares |
|
223 | + $optedOut = true; |
|
224 | + foreach ($subShares as $subShare) { |
|
225 | + if ((int)$subShare['permissions'] !== 0) { |
|
226 | + $optedOut = false; |
|
227 | + break; |
|
228 | + } |
|
229 | + } |
|
230 | + |
|
231 | + $shareIds = []; |
|
232 | + foreach ($subShares as $subShare) { |
|
233 | + // only if the user deleted some subshares but not all, adjust the permissions of that subshare |
|
234 | + if (!$optedOut && (int)$subShare['permissions'] === 0 && (int)$subShare['share_type'] === DefaultShareProvider::SHARE_TYPE_USERGROUP) { |
|
235 | + // set permissions from parent group share |
|
236 | + $permissions = $groupSharesById[$subShare['parent']]['permissions']; |
|
237 | + |
|
238 | + // fix permissions and target directly |
|
239 | + $query = $this->queryUpdateSharePermissionsAndTarget; |
|
240 | + $query->setParameter('shareid', $subShare['id']); |
|
241 | + $query->setParameter('file_target', $targetPath); |
|
242 | + $query->setParameter('permissions', $permissions); |
|
243 | + $query->execute(); |
|
244 | + } else { |
|
245 | + // gather share ids for bulk target update |
|
246 | + if ($subShare['file_target'] !== $targetPath) { |
|
247 | + $shareIds[] = (int)$subShare['id']; |
|
248 | + } |
|
249 | + } |
|
250 | + } |
|
251 | + |
|
252 | + if (!empty($shareIds)) { |
|
253 | + $query = $this->queryUpdateShareInBatch; |
|
254 | + $query->setParameter('ids', $shareIds, IQueryBuilder::PARAM_INT_ARRAY); |
|
255 | + $query->setParameter('file_target', $targetPath); |
|
256 | + $query->execute(); |
|
257 | + } |
|
258 | + |
|
259 | + return true; |
|
260 | + } |
|
261 | + |
|
262 | + /** |
|
263 | + * Checks whether the number of group shares is balanced with the child subshares. |
|
264 | + * If all group shares have exactly one subshare, and the target of every subshare |
|
265 | + * is the same, then the share is valid. |
|
266 | + * If however there is a group share entry that has no matching subshare, it means |
|
267 | + * we're in the bogus situation and the whole share must be repaired |
|
268 | + * |
|
269 | + * @param array $groupSharesById |
|
270 | + * @param array $subShares |
|
271 | + * |
|
272 | + * @return true if the share is valid, false if it needs repair |
|
273 | + */ |
|
274 | + private function isThisShareValid($groupSharesById, $subShares) { |
|
275 | + $foundTargets = []; |
|
276 | + |
|
277 | + // every group share needs to have exactly one matching subshare |
|
278 | + foreach ($subShares as $subShare) { |
|
279 | + $foundTargets[$subShare['file_target']] = true; |
|
280 | + if (count($foundTargets) > 1) { |
|
281 | + // not all the same target path value => invalid |
|
282 | + return false; |
|
283 | + } |
|
284 | + if (isset($groupSharesById[$subShare['parent']])) { |
|
285 | + // remove it from the list as we found it |
|
286 | + unset($groupSharesById[$subShare['parent']]); |
|
287 | + } |
|
288 | + } |
|
289 | + |
|
290 | + // if we found one subshare per group entry, the set will be empty. |
|
291 | + // If not empty, it means that one of the group shares did not have |
|
292 | + // a matching subshare entry. |
|
293 | + return empty($groupSharesById); |
|
294 | + } |
|
295 | + |
|
296 | + /** |
|
297 | + * Detect unmerged received shares and merge them properly |
|
298 | + */ |
|
299 | + private function fixUnmergedShares(IOutput $out, IUser $user) { |
|
300 | + $groups = $this->groupManager->getUserGroupIds($user); |
|
301 | + if (empty($groups)) { |
|
302 | + // user is in no groups, so can't have received group shares |
|
303 | + return; |
|
304 | + } |
|
305 | + |
|
306 | + // get all subshares grouped by item source |
|
307 | + $subSharesByItemSource = $this->getSharesWithUser(DefaultShareProvider::SHARE_TYPE_USERGROUP, [$user->getUID()]); |
|
308 | + |
|
309 | + // because sometimes one wants to give the user more permissions than the group share |
|
310 | + $userSharesByItemSource = $this->getSharesWithUser(Constants::SHARE_TYPE_USER, [$user->getUID()]); |
|
311 | + |
|
312 | + if (empty($subSharesByItemSource) && empty($userSharesByItemSource)) { |
|
313 | + // nothing to repair for this user, no need to do extra queries |
|
314 | + return; |
|
315 | + } |
|
316 | + |
|
317 | + $groupSharesByItemSource = $this->getSharesWithUser(Constants::SHARE_TYPE_GROUP, $groups); |
|
318 | + if (empty($groupSharesByItemSource) && empty($userSharesByItemSource)) { |
|
319 | + // nothing to repair for this user |
|
320 | + return; |
|
321 | + } |
|
322 | + |
|
323 | + foreach ($groupSharesByItemSource as $itemSource => $groupShares) { |
|
324 | + $subShares = []; |
|
325 | + if (isset($subSharesByItemSource[$itemSource])) { |
|
326 | + $subShares = $subSharesByItemSource[$itemSource]; |
|
327 | + } |
|
328 | + |
|
329 | + if (isset($userSharesByItemSource[$itemSource])) { |
|
330 | + // add it to the subshares to get a similar treatment |
|
331 | + $subShares = array_merge($subShares, $userSharesByItemSource[$itemSource]); |
|
332 | + } |
|
333 | + |
|
334 | + $this->fixThisShare($groupShares, $subShares); |
|
335 | + } |
|
336 | + } |
|
337 | + |
|
338 | + /** |
|
339 | + * Count all the users |
|
340 | + * |
|
341 | + * @return int |
|
342 | + */ |
|
343 | + private function countUsers() { |
|
344 | + $allCount = $this->userManager->countUsers(); |
|
345 | + |
|
346 | + $totalCount = 0; |
|
347 | + foreach ($allCount as $backend => $count) { |
|
348 | + $totalCount += $count; |
|
349 | + } |
|
350 | + |
|
351 | + return $totalCount; |
|
352 | + } |
|
353 | + |
|
354 | + public function run(IOutput $output) { |
|
355 | + $ocVersionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0'); |
|
356 | + if (version_compare($ocVersionFromBeforeUpdate, '9.1.0.16', '<')) { |
|
357 | + // this situation was only possible between 9.0.0 and 9.0.3 included |
|
358 | + |
|
359 | + $function = function(IUser $user) use ($output) { |
|
360 | + $this->fixUnmergedShares($output, $user); |
|
361 | + $output->advance(); |
|
362 | + }; |
|
363 | + |
|
364 | + $this->buildPreparedQueries(); |
|
365 | + |
|
366 | + $userCount = $this->countUsers(); |
|
367 | + $output->startProgress($userCount); |
|
368 | + |
|
369 | + $this->userManager->callForAllUsers($function); |
|
370 | + |
|
371 | + $output->finishProgress(); |
|
372 | + } |
|
373 | + } |
|
374 | 374 | } |
@@ -21,12 +21,10 @@ |
||
21 | 21 | |
22 | 22 | namespace OCA\User_LDAP; |
23 | 23 | |
24 | -use OCP\IUserBackend; |
|
25 | 24 | use OCP\LDAP\ILDAPProvider; |
26 | 25 | use OCP\LDAP\IDeletionFlagSupport; |
27 | 26 | use OCP\IServerContainer; |
28 | 27 | use OCA\User_LDAP\User\DeletedUsersIndex; |
29 | -use OCA\User_LDAP\Mapping\UserMapping; |
|
30 | 28 | |
31 | 29 | /** |
32 | 30 | * LDAP provider for pulic access to the LDAP backend. |
@@ -33,155 +33,155 @@ |
||
33 | 33 | */ |
34 | 34 | class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport { |
35 | 35 | |
36 | - private $backend; |
|
37 | - private $logger; |
|
38 | - private $helper; |
|
39 | - private $deletedUsersIndex; |
|
36 | + private $backend; |
|
37 | + private $logger; |
|
38 | + private $helper; |
|
39 | + private $deletedUsersIndex; |
|
40 | 40 | |
41 | - /** |
|
42 | - * Create new LDAPProvider |
|
43 | - * @param \OCP\IServerContainer $serverContainer |
|
44 | - * @throws \Exception if user_ldap app was not enabled |
|
45 | - */ |
|
46 | - public function __construct(IServerContainer $serverContainer, Helper $helper, DeletedUsersIndex $deletedUsersIndex) { |
|
47 | - $this->logger = $serverContainer->getLogger(); |
|
48 | - $this->helper = $helper; |
|
49 | - $this->deletedUsersIndex = $deletedUsersIndex; |
|
50 | - foreach ($serverContainer->getUserManager()->getBackends() as $backend){ |
|
51 | - $this->logger->debug('instance '.get_class($backend).' backend.', ['app' => 'user_ldap']); |
|
52 | - if ($backend instanceof IUserLDAP) { |
|
53 | - $this->backend = $backend; |
|
54 | - return; |
|
55 | - } |
|
41 | + /** |
|
42 | + * Create new LDAPProvider |
|
43 | + * @param \OCP\IServerContainer $serverContainer |
|
44 | + * @throws \Exception if user_ldap app was not enabled |
|
45 | + */ |
|
46 | + public function __construct(IServerContainer $serverContainer, Helper $helper, DeletedUsersIndex $deletedUsersIndex) { |
|
47 | + $this->logger = $serverContainer->getLogger(); |
|
48 | + $this->helper = $helper; |
|
49 | + $this->deletedUsersIndex = $deletedUsersIndex; |
|
50 | + foreach ($serverContainer->getUserManager()->getBackends() as $backend){ |
|
51 | + $this->logger->debug('instance '.get_class($backend).' backend.', ['app' => 'user_ldap']); |
|
52 | + if ($backend instanceof IUserLDAP) { |
|
53 | + $this->backend = $backend; |
|
54 | + return; |
|
55 | + } |
|
56 | 56 | } |
57 | - throw new \Exception('To use the LDAPProvider, user_ldap app must be enabled'); |
|
58 | - } |
|
57 | + throw new \Exception('To use the LDAPProvider, user_ldap app must be enabled'); |
|
58 | + } |
|
59 | 59 | |
60 | - /** |
|
61 | - * Translate an user id to LDAP DN |
|
62 | - * @param string $uid user id |
|
63 | - * @return string with the LDAP DN |
|
64 | - * @throws \Exception if translation was unsuccessful |
|
65 | - */ |
|
66 | - public function getUserDN($uid) { |
|
67 | - if(!$this->backend->userExists($uid)){ |
|
68 | - throw new \Exception('User id not found in LDAP'); |
|
69 | - } |
|
70 | - $result = $this->backend->getLDAPAccess($uid)->username2dn($uid); |
|
71 | - if(!$result){ |
|
72 | - throw new \Exception('Translation to LDAP DN unsuccessful'); |
|
73 | - } |
|
74 | - return $result; |
|
75 | - } |
|
60 | + /** |
|
61 | + * Translate an user id to LDAP DN |
|
62 | + * @param string $uid user id |
|
63 | + * @return string with the LDAP DN |
|
64 | + * @throws \Exception if translation was unsuccessful |
|
65 | + */ |
|
66 | + public function getUserDN($uid) { |
|
67 | + if(!$this->backend->userExists($uid)){ |
|
68 | + throw new \Exception('User id not found in LDAP'); |
|
69 | + } |
|
70 | + $result = $this->backend->getLDAPAccess($uid)->username2dn($uid); |
|
71 | + if(!$result){ |
|
72 | + throw new \Exception('Translation to LDAP DN unsuccessful'); |
|
73 | + } |
|
74 | + return $result; |
|
75 | + } |
|
76 | 76 | |
77 | - /** |
|
78 | - * Translate a LDAP DN to an internal user name. If there is no mapping between |
|
79 | - * the DN and the user name, a new one will be created. |
|
80 | - * @param string $dn LDAP DN |
|
81 | - * @return string with the internal user name |
|
82 | - * @throws \Exception if translation was unsuccessful |
|
83 | - */ |
|
84 | - public function getUserName($dn) { |
|
85 | - $result = $this->backend->dn2UserName($dn); |
|
86 | - if(!$result){ |
|
87 | - throw new \Exception('Translation to internal user name unsuccessful'); |
|
88 | - } |
|
89 | - return $result; |
|
90 | - } |
|
77 | + /** |
|
78 | + * Translate a LDAP DN to an internal user name. If there is no mapping between |
|
79 | + * the DN and the user name, a new one will be created. |
|
80 | + * @param string $dn LDAP DN |
|
81 | + * @return string with the internal user name |
|
82 | + * @throws \Exception if translation was unsuccessful |
|
83 | + */ |
|
84 | + public function getUserName($dn) { |
|
85 | + $result = $this->backend->dn2UserName($dn); |
|
86 | + if(!$result){ |
|
87 | + throw new \Exception('Translation to internal user name unsuccessful'); |
|
88 | + } |
|
89 | + return $result; |
|
90 | + } |
|
91 | 91 | |
92 | - /** |
|
93 | - * Convert a stored DN so it can be used as base parameter for LDAP queries. |
|
94 | - * @param string $dn the DN in question |
|
95 | - * @return string |
|
96 | - */ |
|
97 | - public function DNasBaseParameter($dn) { |
|
98 | - return $this->helper->DNasBaseParameter($dn); |
|
99 | - } |
|
92 | + /** |
|
93 | + * Convert a stored DN so it can be used as base parameter for LDAP queries. |
|
94 | + * @param string $dn the DN in question |
|
95 | + * @return string |
|
96 | + */ |
|
97 | + public function DNasBaseParameter($dn) { |
|
98 | + return $this->helper->DNasBaseParameter($dn); |
|
99 | + } |
|
100 | 100 | |
101 | - /** |
|
102 | - * Sanitize a DN received from the LDAP server. |
|
103 | - * @param array $dn the DN in question |
|
104 | - * @return array the sanitized DN |
|
105 | - */ |
|
106 | - public function sanitizeDN($dn) { |
|
107 | - return $this->helper->sanitizeDN($dn); |
|
108 | - } |
|
101 | + /** |
|
102 | + * Sanitize a DN received from the LDAP server. |
|
103 | + * @param array $dn the DN in question |
|
104 | + * @return array the sanitized DN |
|
105 | + */ |
|
106 | + public function sanitizeDN($dn) { |
|
107 | + return $this->helper->sanitizeDN($dn); |
|
108 | + } |
|
109 | 109 | |
110 | - /** |
|
111 | - * Return a new LDAP connection resource for the specified user. |
|
112 | - * The connection must be closed manually. |
|
113 | - * @param string $uid user id |
|
114 | - * @return resource of the LDAP connection |
|
115 | - * @throws \Exception if user id was not found in LDAP |
|
116 | - */ |
|
117 | - public function getLDAPConnection($uid) { |
|
118 | - if(!$this->backend->userExists($uid)){ |
|
119 | - throw new \Exception('User id not found in LDAP'); |
|
120 | - } |
|
121 | - return $this->backend->getNewLDAPConnection($uid); |
|
122 | - } |
|
110 | + /** |
|
111 | + * Return a new LDAP connection resource for the specified user. |
|
112 | + * The connection must be closed manually. |
|
113 | + * @param string $uid user id |
|
114 | + * @return resource of the LDAP connection |
|
115 | + * @throws \Exception if user id was not found in LDAP |
|
116 | + */ |
|
117 | + public function getLDAPConnection($uid) { |
|
118 | + if(!$this->backend->userExists($uid)){ |
|
119 | + throw new \Exception('User id not found in LDAP'); |
|
120 | + } |
|
121 | + return $this->backend->getNewLDAPConnection($uid); |
|
122 | + } |
|
123 | 123 | |
124 | - /** |
|
125 | - * Get the LDAP base for users. |
|
126 | - * @param string $uid user id |
|
127 | - * @return string the base for users |
|
128 | - * @throws \Exception if user id was not found in LDAP |
|
129 | - */ |
|
130 | - public function getLDAPBaseUsers($uid) { |
|
131 | - if(!$this->backend->userExists($uid)){ |
|
132 | - throw new \Exception('User id not found in LDAP'); |
|
133 | - } |
|
134 | - return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_users']; |
|
135 | - } |
|
124 | + /** |
|
125 | + * Get the LDAP base for users. |
|
126 | + * @param string $uid user id |
|
127 | + * @return string the base for users |
|
128 | + * @throws \Exception if user id was not found in LDAP |
|
129 | + */ |
|
130 | + public function getLDAPBaseUsers($uid) { |
|
131 | + if(!$this->backend->userExists($uid)){ |
|
132 | + throw new \Exception('User id not found in LDAP'); |
|
133 | + } |
|
134 | + return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_users']; |
|
135 | + } |
|
136 | 136 | |
137 | - /** |
|
138 | - * Get the LDAP base for groups. |
|
139 | - * @param string $uid user id |
|
140 | - * @return string the base for groups |
|
141 | - * @throws \Exception if user id was not found in LDAP |
|
142 | - */ |
|
143 | - public function getLDAPBaseGroups($uid) { |
|
144 | - if(!$this->backend->userExists($uid)){ |
|
145 | - throw new \Exception('User id not found in LDAP'); |
|
146 | - } |
|
147 | - return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_groups']; |
|
148 | - } |
|
137 | + /** |
|
138 | + * Get the LDAP base for groups. |
|
139 | + * @param string $uid user id |
|
140 | + * @return string the base for groups |
|
141 | + * @throws \Exception if user id was not found in LDAP |
|
142 | + */ |
|
143 | + public function getLDAPBaseGroups($uid) { |
|
144 | + if(!$this->backend->userExists($uid)){ |
|
145 | + throw new \Exception('User id not found in LDAP'); |
|
146 | + } |
|
147 | + return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_groups']; |
|
148 | + } |
|
149 | 149 | |
150 | - /** |
|
151 | - * Clear the cache if a cache is used, otherwise do nothing. |
|
152 | - * @param string $uid user id |
|
153 | - * @throws \Exception if user id was not found in LDAP |
|
154 | - */ |
|
155 | - public function clearCache($uid) { |
|
156 | - if(!$this->backend->userExists($uid)){ |
|
157 | - throw new \Exception('User id not found in LDAP'); |
|
158 | - } |
|
159 | - $this->backend->getLDAPAccess($uid)->getConnection()->clearCache(); |
|
160 | - } |
|
150 | + /** |
|
151 | + * Clear the cache if a cache is used, otherwise do nothing. |
|
152 | + * @param string $uid user id |
|
153 | + * @throws \Exception if user id was not found in LDAP |
|
154 | + */ |
|
155 | + public function clearCache($uid) { |
|
156 | + if(!$this->backend->userExists($uid)){ |
|
157 | + throw new \Exception('User id not found in LDAP'); |
|
158 | + } |
|
159 | + $this->backend->getLDAPAccess($uid)->getConnection()->clearCache(); |
|
160 | + } |
|
161 | 161 | |
162 | - /** |
|
163 | - * Check whether a LDAP DN exists |
|
164 | - * @param string $dn LDAP DN |
|
165 | - * @return bool whether the DN exists |
|
166 | - */ |
|
167 | - public function dnExists($dn) { |
|
168 | - $result = $this->backend->dn2UserName($dn); |
|
169 | - return !$result ? false : true; |
|
170 | - } |
|
162 | + /** |
|
163 | + * Check whether a LDAP DN exists |
|
164 | + * @param string $dn LDAP DN |
|
165 | + * @return bool whether the DN exists |
|
166 | + */ |
|
167 | + public function dnExists($dn) { |
|
168 | + $result = $this->backend->dn2UserName($dn); |
|
169 | + return !$result ? false : true; |
|
170 | + } |
|
171 | 171 | |
172 | - /** |
|
173 | - * Flag record for deletion. |
|
174 | - * @param string $uid user id |
|
175 | - */ |
|
176 | - public function flagRecord($uid) { |
|
177 | - $this->deletedUsersIndex->markUser($uid); |
|
178 | - } |
|
172 | + /** |
|
173 | + * Flag record for deletion. |
|
174 | + * @param string $uid user id |
|
175 | + */ |
|
176 | + public function flagRecord($uid) { |
|
177 | + $this->deletedUsersIndex->markUser($uid); |
|
178 | + } |
|
179 | 179 | |
180 | - /** |
|
181 | - * Unflag record for deletion. |
|
182 | - * @param string $uid user id |
|
183 | - */ |
|
184 | - public function unflagRecord($uid) { |
|
185 | - //do nothing |
|
186 | - } |
|
180 | + /** |
|
181 | + * Unflag record for deletion. |
|
182 | + * @param string $uid user id |
|
183 | + */ |
|
184 | + public function unflagRecord($uid) { |
|
185 | + //do nothing |
|
186 | + } |
|
187 | 187 | } |
@@ -47,7 +47,7 @@ discard block |
||
47 | 47 | $this->logger = $serverContainer->getLogger(); |
48 | 48 | $this->helper = $helper; |
49 | 49 | $this->deletedUsersIndex = $deletedUsersIndex; |
50 | - foreach ($serverContainer->getUserManager()->getBackends() as $backend){ |
|
50 | + foreach ($serverContainer->getUserManager()->getBackends() as $backend) { |
|
51 | 51 | $this->logger->debug('instance '.get_class($backend).' backend.', ['app' => 'user_ldap']); |
52 | 52 | if ($backend instanceof IUserLDAP) { |
53 | 53 | $this->backend = $backend; |
@@ -64,11 +64,11 @@ discard block |
||
64 | 64 | * @throws \Exception if translation was unsuccessful |
65 | 65 | */ |
66 | 66 | public function getUserDN($uid) { |
67 | - if(!$this->backend->userExists($uid)){ |
|
67 | + if (!$this->backend->userExists($uid)) { |
|
68 | 68 | throw new \Exception('User id not found in LDAP'); |
69 | 69 | } |
70 | 70 | $result = $this->backend->getLDAPAccess($uid)->username2dn($uid); |
71 | - if(!$result){ |
|
71 | + if (!$result) { |
|
72 | 72 | throw new \Exception('Translation to LDAP DN unsuccessful'); |
73 | 73 | } |
74 | 74 | return $result; |
@@ -83,7 +83,7 @@ discard block |
||
83 | 83 | */ |
84 | 84 | public function getUserName($dn) { |
85 | 85 | $result = $this->backend->dn2UserName($dn); |
86 | - if(!$result){ |
|
86 | + if (!$result) { |
|
87 | 87 | throw new \Exception('Translation to internal user name unsuccessful'); |
88 | 88 | } |
89 | 89 | return $result; |
@@ -115,7 +115,7 @@ discard block |
||
115 | 115 | * @throws \Exception if user id was not found in LDAP |
116 | 116 | */ |
117 | 117 | public function getLDAPConnection($uid) { |
118 | - if(!$this->backend->userExists($uid)){ |
|
118 | + if (!$this->backend->userExists($uid)) { |
|
119 | 119 | throw new \Exception('User id not found in LDAP'); |
120 | 120 | } |
121 | 121 | return $this->backend->getNewLDAPConnection($uid); |
@@ -128,7 +128,7 @@ discard block |
||
128 | 128 | * @throws \Exception if user id was not found in LDAP |
129 | 129 | */ |
130 | 130 | public function getLDAPBaseUsers($uid) { |
131 | - if(!$this->backend->userExists($uid)){ |
|
131 | + if (!$this->backend->userExists($uid)) { |
|
132 | 132 | throw new \Exception('User id not found in LDAP'); |
133 | 133 | } |
134 | 134 | return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_users']; |
@@ -141,7 +141,7 @@ discard block |
||
141 | 141 | * @throws \Exception if user id was not found in LDAP |
142 | 142 | */ |
143 | 143 | public function getLDAPBaseGroups($uid) { |
144 | - if(!$this->backend->userExists($uid)){ |
|
144 | + if (!$this->backend->userExists($uid)) { |
|
145 | 145 | throw new \Exception('User id not found in LDAP'); |
146 | 146 | } |
147 | 147 | return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_groups']; |
@@ -153,7 +153,7 @@ discard block |
||
153 | 153 | * @throws \Exception if user id was not found in LDAP |
154 | 154 | */ |
155 | 155 | public function clearCache($uid) { |
156 | - if(!$this->backend->userExists($uid)){ |
|
156 | + if (!$this->backend->userExists($uid)) { |
|
157 | 157 | throw new \Exception('User id not found in LDAP'); |
158 | 158 | } |
159 | 159 | $this->backend->getLDAPAccess($uid)->getConnection()->clearCache(); |