1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc. |
4
|
|
|
* |
5
|
|
|
* @author Arthur Schiwon <[email protected]> |
6
|
|
|
* @author Bernhard Posselt <[email protected]> |
7
|
|
|
* @author Bjoern Schiessle <[email protected]> |
8
|
|
|
* @author Christoph Wurst <[email protected]> |
9
|
|
|
* @author Daniel Kesselberg <[email protected]> |
10
|
|
|
* @author Joas Schilling <[email protected]> |
11
|
|
|
* @author Jörn Friedrich Dreyer <[email protected]> |
12
|
|
|
* @author Lukas Reschke <[email protected]> |
13
|
|
|
* @author Morris Jobke <[email protected]> |
14
|
|
|
* @author Robin McCorkell <[email protected]> |
15
|
|
|
* @author Roeland Jago Douma <[email protected]> |
16
|
|
|
* @author Sebastian Wessalowski <[email protected]> |
17
|
|
|
* @author Thomas Müller <[email protected]> |
18
|
|
|
* @author Thomas Tanghus <[email protected]> |
19
|
|
|
* |
20
|
|
|
* @license AGPL-3.0 |
21
|
|
|
* |
22
|
|
|
* This code is free software: you can redistribute it and/or modify |
23
|
|
|
* it under the terms of the GNU Affero General Public License, version 3, |
24
|
|
|
* as published by the Free Software Foundation. |
25
|
|
|
* |
26
|
|
|
* This program is distributed in the hope that it will be useful, |
27
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
28
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29
|
|
|
* GNU Affero General Public License for more details. |
30
|
|
|
* |
31
|
|
|
* You should have received a copy of the GNU Affero General Public License, version 3, |
32
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/> |
33
|
|
|
* |
34
|
|
|
*/ |
35
|
|
|
|
36
|
|
|
namespace OC\AppFramework\DependencyInjection; |
37
|
|
|
|
38
|
|
|
use OC; |
39
|
|
|
use OC\AppFramework\Http; |
40
|
|
|
use OC\AppFramework\Http\Dispatcher; |
41
|
|
|
use OC\AppFramework\Http\Output; |
42
|
|
|
use OC\AppFramework\Middleware\MiddlewareDispatcher; |
43
|
|
|
use OC\AppFramework\Middleware\OCSMiddleware; |
44
|
|
|
use OC\AppFramework\Middleware\Security\CORSMiddleware; |
45
|
|
|
use OC\AppFramework\Middleware\Security\RateLimitingMiddleware; |
46
|
|
|
use OC\AppFramework\Middleware\Security\SecurityMiddleware; |
47
|
|
|
use OC\AppFramework\Middleware\SessionMiddleware; |
48
|
|
|
use OC\AppFramework\Utility\SimpleContainer; |
49
|
|
|
use OC\Core\Middleware\TwoFactorMiddleware; |
50
|
|
|
use OC\ServerContainer; |
51
|
|
|
use OCA\WorkflowEngine\Manager; |
52
|
|
|
use OCP\AppFramework\Http\IOutput; |
53
|
|
|
use OCP\AppFramework\IAppContainer; |
54
|
|
|
use OCP\AppFramework\QueryException; |
55
|
|
|
use OCP\AppFramework\Services\IAppConfig; |
56
|
|
|
use OCP\AppFramework\Services\IInitialState; |
57
|
|
|
use OCP\AppFramework\Utility\IControllerMethodReflector; |
58
|
|
|
use OCP\AppFramework\Utility\ITimeFactory; |
59
|
|
|
use OCP\Files\Folder; |
60
|
|
|
use OCP\Files\IAppData; |
61
|
|
|
use OCP\Group\ISubAdmin; |
62
|
|
|
use OCP\IConfig; |
63
|
|
|
use OCP\IInitialStateService; |
64
|
|
|
use OCP\IL10N; |
65
|
|
|
use OCP\ILogger; |
66
|
|
|
use OCP\INavigationManager; |
67
|
|
|
use OCP\IRequest; |
68
|
|
|
use OCP\IServerContainer; |
69
|
|
|
use OCP\ISession; |
70
|
|
|
use OCP\IURLGenerator; |
71
|
|
|
use OCP\IUserSession; |
72
|
|
|
use Psr\Container\ContainerInterface; |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @deprecated 20.0.0 |
76
|
|
|
*/ |
77
|
|
|
class DIContainer extends SimpleContainer implements IAppContainer { |
|
|
|
|
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @var array |
81
|
|
|
*/ |
82
|
|
|
private $middleWares = []; |
83
|
|
|
|
84
|
|
|
/** @var ServerContainer */ |
85
|
|
|
private $server; |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Put your class dependencies in here |
89
|
|
|
* @param string $appName the name of the app |
90
|
|
|
* @param array $urlParams |
91
|
|
|
* @param ServerContainer|null $server |
92
|
|
|
*/ |
93
|
|
|
public function __construct($appName, $urlParams = [], ServerContainer $server = null) { |
94
|
|
|
parent::__construct(); |
95
|
|
|
$this['AppName'] = $appName; |
96
|
|
|
$this['urlParams'] = $urlParams; |
97
|
|
|
|
98
|
|
|
$this->registerAlias('Request', IRequest::class); |
99
|
|
|
|
100
|
|
|
/** @var \OC\ServerContainer $server */ |
101
|
|
|
if ($server === null) { |
102
|
|
|
$server = \OC::$server; |
103
|
|
|
} |
104
|
|
|
$this->server = $server; |
105
|
|
|
$this->server->registerAppContainer($appName, $this); |
106
|
|
|
|
107
|
|
|
// aliases |
108
|
|
|
$this->registerAlias('appName', 'AppName'); |
109
|
|
|
$this->registerAlias('webRoot', 'WebRoot'); |
110
|
|
|
$this->registerAlias('userId', 'UserId'); |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Core services |
114
|
|
|
*/ |
115
|
|
|
$this->registerService(IOutput::class, function () { |
116
|
|
|
return new Output($this->getServer()->getWebRoot()); |
117
|
|
|
}); |
118
|
|
|
|
119
|
|
|
$this->registerService(Folder::class, function () { |
120
|
|
|
return $this->getServer()->getUserFolder(); |
121
|
|
|
}); |
122
|
|
|
|
123
|
|
|
$this->registerService(IAppData::class, function (ContainerInterface $c) { |
124
|
|
|
return $this->getServer()->getAppDataDir($c->get('AppName')); |
|
|
|
|
125
|
|
|
}); |
126
|
|
|
|
127
|
|
|
$this->registerService(IL10N::class, function (ContainerInterface $c) { |
128
|
|
|
return $this->getServer()->getL10N($c->get('AppName')); |
129
|
|
|
}); |
130
|
|
|
|
131
|
|
|
// Log wrapper |
132
|
|
|
$this->registerService(ILogger::class, function (ContainerInterface $c) { |
133
|
|
|
return new OC\AppFramework\Logger($this->server->query(ILogger::class), $c->get('AppName')); |
134
|
|
|
}); |
135
|
|
|
|
136
|
|
|
$this->registerService(IServerContainer::class, function () { |
137
|
|
|
return $this->getServer(); |
138
|
|
|
}); |
139
|
|
|
$this->registerAlias('ServerContainer', IServerContainer::class); |
140
|
|
|
|
141
|
|
|
$this->registerService(\OCP\WorkflowEngine\IManager::class, function (ContainerInterface $c) { |
142
|
|
|
return $c->get(Manager::class); |
143
|
|
|
}); |
144
|
|
|
|
145
|
|
|
$this->registerService(ContainerInterface::class, function (ContainerInterface $c) { |
146
|
|
|
return $c; |
147
|
|
|
}); |
148
|
|
|
$this->registerAlias(IAppContainer::class, ContainerInterface::class); |
149
|
|
|
|
150
|
|
|
// commonly used attributes |
151
|
|
|
$this->registerService('UserId', function (ContainerInterface $c) { |
152
|
|
|
return $c->get(IUserSession::class)->getSession()->get('user_id'); |
153
|
|
|
}); |
154
|
|
|
|
155
|
|
|
$this->registerService('WebRoot', function (ContainerInterface $c) { |
156
|
|
|
return $c->get(IServerContainer::class)->getWebRoot(); |
157
|
|
|
}); |
158
|
|
|
|
159
|
|
|
$this->registerService('OC_Defaults', function (ContainerInterface $c) { |
160
|
|
|
return $c->get(IServerContainer::class)->getThemingDefaults(); |
161
|
|
|
}); |
162
|
|
|
|
163
|
|
|
$this->registerService('Protocol', function (ContainerInterface $c) { |
164
|
|
|
/** @var \OC\Server $server */ |
165
|
|
|
$server = $c->get(IServerContainer::class); |
166
|
|
|
$protocol = $server->getRequest()->getHttpProtocol(); |
167
|
|
|
return new Http($_SERVER, $protocol); |
168
|
|
|
}); |
169
|
|
|
|
170
|
|
|
$this->registerService('Dispatcher', function (ContainerInterface $c) { |
171
|
|
|
return new Dispatcher( |
172
|
|
|
$c->get('Protocol'), |
173
|
|
|
$c->get(MiddlewareDispatcher::class), |
174
|
|
|
$c->get(IControllerMethodReflector::class), |
175
|
|
|
$c->get(IRequest::class) |
176
|
|
|
); |
177
|
|
|
}); |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* App Framework default arguments |
181
|
|
|
*/ |
182
|
|
|
$this->registerParameter('corsMethods', 'PUT, POST, GET, DELETE, PATCH'); |
183
|
|
|
$this->registerParameter('corsAllowedHeaders', 'Authorization, Content-Type, Accept'); |
184
|
|
|
$this->registerParameter('corsMaxAge', 1728000); |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Middleware |
188
|
|
|
*/ |
189
|
|
|
$this->registerAlias('MiddlewareDispatcher', MiddlewareDispatcher::class); |
190
|
|
|
$this->registerService(MiddlewareDispatcher::class, function (ContainerInterface $c) { |
191
|
|
|
$server = $this->getServer(); |
192
|
|
|
|
193
|
|
|
$dispatcher = new MiddlewareDispatcher(); |
194
|
|
|
|
195
|
|
|
$dispatcher->registerMiddleware( |
196
|
|
|
$c->get(OC\AppFramework\Middleware\CompressionMiddleware::class) |
197
|
|
|
); |
198
|
|
|
|
199
|
|
|
$dispatcher->registerMiddleware($c->get(OC\AppFramework\Middleware\NotModifiedMiddleware::class)); |
200
|
|
|
|
201
|
|
|
$dispatcher->registerMiddleware( |
202
|
|
|
$c->get(OC\AppFramework\Middleware\Security\ReloadExecutionMiddleware::class) |
203
|
|
|
); |
204
|
|
|
|
205
|
|
|
$dispatcher->registerMiddleware( |
206
|
|
|
new OC\AppFramework\Middleware\Security\SameSiteCookieMiddleware( |
207
|
|
|
$c->get(IRequest::class), |
208
|
|
|
$c->get(IControllerMethodReflector::class) |
209
|
|
|
) |
210
|
|
|
); |
211
|
|
|
$dispatcher->registerMiddleware( |
212
|
|
|
new CORSMiddleware( |
213
|
|
|
$c->get(IRequest::class), |
214
|
|
|
$c->get(IControllerMethodReflector::class), |
215
|
|
|
$c->get(IUserSession::class), |
216
|
|
|
$c->get(OC\Security\Bruteforce\Throttler::class) |
217
|
|
|
) |
218
|
|
|
); |
219
|
|
|
$dispatcher->registerMiddleware( |
220
|
|
|
new OCSMiddleware( |
221
|
|
|
$c->get(IRequest::class) |
222
|
|
|
) |
223
|
|
|
); |
224
|
|
|
|
225
|
|
|
$securityMiddleware = new SecurityMiddleware( |
226
|
|
|
$c->get(IRequest::class), |
227
|
|
|
$c->get(IControllerMethodReflector::class), |
228
|
|
|
$c->get(INavigationManager::class), |
229
|
|
|
$c->get(IURLGenerator::class), |
230
|
|
|
$server->query(ILogger::class), |
|
|
|
|
231
|
|
|
$c->get('AppName'), |
232
|
|
|
$server->getUserSession()->isLoggedIn(), |
233
|
|
|
$server->getGroupManager()->isAdmin($this->getUserId()), |
234
|
|
|
$server->getUserSession()->getUser() !== null && $server->query(ISubAdmin::class)->isSubAdmin($server->getUserSession()->getUser()), |
|
|
|
|
235
|
|
|
$server->getAppManager(), |
236
|
|
|
$server->getL10N('lib') |
237
|
|
|
); |
238
|
|
|
$dispatcher->registerMiddleware($securityMiddleware); |
239
|
|
|
$dispatcher->registerMiddleware( |
240
|
|
|
new OC\AppFramework\Middleware\Security\CSPMiddleware( |
241
|
|
|
$server->query(OC\Security\CSP\ContentSecurityPolicyManager::class), |
|
|
|
|
242
|
|
|
$server->query(OC\Security\CSP\ContentSecurityPolicyNonceManager::class), |
|
|
|
|
243
|
|
|
$server->query(OC\Security\CSRF\CsrfTokenManager::class) |
|
|
|
|
244
|
|
|
) |
245
|
|
|
); |
246
|
|
|
$dispatcher->registerMiddleware( |
247
|
|
|
$server->query(OC\AppFramework\Middleware\Security\FeaturePolicyMiddleware::class) |
|
|
|
|
248
|
|
|
); |
249
|
|
|
$dispatcher->registerMiddleware( |
250
|
|
|
new OC\AppFramework\Middleware\Security\PasswordConfirmationMiddleware( |
251
|
|
|
$c->get(IControllerMethodReflector::class), |
252
|
|
|
$c->get(ISession::class), |
253
|
|
|
$c->get(IUserSession::class), |
254
|
|
|
$c->get(ITimeFactory::class) |
255
|
|
|
) |
256
|
|
|
); |
257
|
|
|
$dispatcher->registerMiddleware( |
258
|
|
|
new TwoFactorMiddleware( |
259
|
|
|
$c->get(OC\Authentication\TwoFactorAuth\Manager::class), |
260
|
|
|
$c->get(IUserSession::class), |
261
|
|
|
$c->get(ISession::class), |
262
|
|
|
$c->get(IURLGenerator::class), |
263
|
|
|
$c->get(IControllerMethodReflector::class), |
264
|
|
|
$c->get(IRequest::class) |
265
|
|
|
) |
266
|
|
|
); |
267
|
|
|
$dispatcher->registerMiddleware( |
268
|
|
|
new OC\AppFramework\Middleware\Security\BruteForceMiddleware( |
269
|
|
|
$c->get(IControllerMethodReflector::class), |
270
|
|
|
$c->get(OC\Security\Bruteforce\Throttler::class), |
271
|
|
|
$c->get(IRequest::class) |
272
|
|
|
) |
273
|
|
|
); |
274
|
|
|
$dispatcher->registerMiddleware( |
275
|
|
|
new RateLimitingMiddleware( |
276
|
|
|
$c->get(IRequest::class), |
277
|
|
|
$c->get(IUserSession::class), |
278
|
|
|
$c->get(IControllerMethodReflector::class), |
279
|
|
|
$c->get(OC\Security\RateLimiting\Limiter::class) |
280
|
|
|
) |
281
|
|
|
); |
282
|
|
|
$dispatcher->registerMiddleware( |
283
|
|
|
new OC\AppFramework\Middleware\PublicShare\PublicShareMiddleware( |
284
|
|
|
$c->get(IRequest::class), |
285
|
|
|
$c->get(ISession::class), |
286
|
|
|
$c->get(\OCP\IConfig::class) |
287
|
|
|
) |
288
|
|
|
); |
289
|
|
|
$dispatcher->registerMiddleware( |
290
|
|
|
$c->get(\OC\AppFramework\Middleware\AdditionalScriptsMiddleware::class) |
291
|
|
|
); |
292
|
|
|
|
293
|
|
|
foreach ($this->middleWares as $middleWare) { |
294
|
|
|
$dispatcher->registerMiddleware($c->get($middleWare)); |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
$dispatcher->registerMiddleware( |
298
|
|
|
new SessionMiddleware( |
299
|
|
|
$c->get(IControllerMethodReflector::class), |
300
|
|
|
$c->get(ISession::class) |
301
|
|
|
) |
302
|
|
|
); |
303
|
|
|
return $dispatcher; |
304
|
|
|
}); |
305
|
|
|
|
306
|
|
|
$this->registerService(IAppConfig::class, function (ContainerInterface $c) { |
307
|
|
|
return new OC\AppFramework\Services\AppConfig( |
308
|
|
|
$c->get(IConfig::class), |
309
|
|
|
$c->get('AppName') |
310
|
|
|
); |
311
|
|
|
}); |
312
|
|
|
$this->registerService(IInitialState::class, function (ContainerInterface $c) { |
313
|
|
|
return new OC\AppFramework\Services\InitialState( |
314
|
|
|
$c->get(IInitialStateService::class), |
315
|
|
|
$c->get('AppName') |
316
|
|
|
); |
317
|
|
|
}); |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* @return \OCP\IServerContainer |
322
|
|
|
*/ |
323
|
|
|
public function getServer() { |
324
|
|
|
return $this->server; |
|
|
|
|
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* @param string $middleWare |
329
|
|
|
* @return boolean|null |
330
|
|
|
*/ |
331
|
|
|
public function registerMiddleWare($middleWare) { |
332
|
|
|
if (in_array($middleWare, $this->middleWares, true) !== false) { |
333
|
|
|
return false; |
334
|
|
|
} |
335
|
|
|
$this->middleWares[] = $middleWare; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* used to return the appname of the set application |
340
|
|
|
* @return string the name of your application |
341
|
|
|
*/ |
342
|
|
|
public function getAppName() { |
343
|
|
|
return $this->query('AppName'); |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* @deprecated use IUserSession->isLoggedIn() |
348
|
|
|
* @return boolean |
349
|
|
|
*/ |
350
|
|
|
public function isLoggedIn() { |
351
|
|
|
return \OC::$server->getUserSession()->isLoggedIn(); |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
/** |
355
|
|
|
* @deprecated use IGroupManager->isAdmin($userId) |
356
|
|
|
* @return boolean |
357
|
|
|
*/ |
358
|
|
|
public function isAdminUser() { |
359
|
|
|
$uid = $this->getUserId(); |
360
|
|
|
return \OC_User::isAdminUser($uid); |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
private function getUserId() { |
364
|
|
|
return $this->getServer()->getSession()->get('user_id'); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* @deprecated use the ILogger instead |
369
|
|
|
* @param string $message |
370
|
|
|
* @param string $level |
371
|
|
|
* @return mixed |
372
|
|
|
*/ |
373
|
|
|
public function log($message, $level) { |
374
|
|
|
switch ($level) { |
375
|
|
|
case 'debug': |
376
|
|
|
$level = ILogger::DEBUG; |
377
|
|
|
break; |
378
|
|
|
case 'info': |
379
|
|
|
$level = ILogger::INFO; |
380
|
|
|
break; |
381
|
|
|
case 'warn': |
382
|
|
|
$level = ILogger::WARN; |
383
|
|
|
break; |
384
|
|
|
case 'fatal': |
385
|
|
|
$level = ILogger::FATAL; |
386
|
|
|
break; |
387
|
|
|
default: |
388
|
|
|
$level = ILogger::ERROR; |
389
|
|
|
break; |
390
|
|
|
} |
391
|
|
|
\OCP\Util::writeLog($this->getAppName(), $message, $level); |
|
|
|
|
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
/** |
395
|
|
|
* Register a capability |
396
|
|
|
* |
397
|
|
|
* @param string $serviceName e.g. 'OCA\Files\Capabilities' |
398
|
|
|
*/ |
399
|
|
|
public function registerCapability($serviceName) { |
400
|
|
|
$this->query('OC\CapabilitiesManager')->registerCapability(function () use ($serviceName) { |
401
|
|
|
return $this->query($serviceName); |
402
|
|
|
}); |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
public function has($id): bool { |
406
|
|
|
if (parent::has($id)) { |
407
|
|
|
return true; |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
if ($this->server->has($id, true)) { |
411
|
|
|
return true; |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
return false; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
public function query(string $name, bool $autoload = true) { |
418
|
|
|
try { |
419
|
|
|
return $this->queryNoFallback($name); |
420
|
|
|
} catch (QueryException $firstException) { |
421
|
|
|
try { |
422
|
|
|
return $this->getServer()->query($name, $autoload); |
|
|
|
|
423
|
|
|
} catch (QueryException $secondException) { |
424
|
|
|
if ($firstException->getCode() === 1) { |
425
|
|
|
throw $secondException; |
426
|
|
|
} |
427
|
|
|
throw $firstException; |
428
|
|
|
} |
429
|
|
|
} |
430
|
|
|
} |
431
|
|
|
|
432
|
|
|
/** |
433
|
|
|
* @param string $name |
434
|
|
|
* @return mixed |
435
|
|
|
* @throws QueryException if the query could not be resolved |
436
|
|
|
*/ |
437
|
|
|
public function queryNoFallback($name) { |
438
|
|
|
$name = $this->sanitizeName($name); |
439
|
|
|
|
440
|
|
|
if ($this->offsetExists($name)) { |
|
|
|
|
441
|
|
|
return parent::query($name); |
442
|
|
|
} elseif ($this['AppName'] === 'settings' && strpos($name, 'OC\\Settings\\') === 0) { |
443
|
|
|
return parent::query($name); |
444
|
|
|
} elseif ($this['AppName'] === 'core' && strpos($name, 'OC\\Core\\') === 0) { |
445
|
|
|
return parent::query($name); |
446
|
|
|
} elseif (strpos($name, \OC\AppFramework\App::buildAppNamespace($this['AppName']) . '\\') === 0) { |
447
|
|
|
return parent::query($name); |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
throw new QueryException('Could not resolve ' . $name . '!' . |
|
|
|
|
451
|
|
|
' Class can not be instantiated', 1); |
452
|
|
|
} |
453
|
|
|
} |
454
|
|
|
|
This interface has been deprecated. The supplier of the interface has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the interface will be removed and what other interface to use instead.