123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810 |
- <?php
- declare(strict_types=1);
- /**
- * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- namespace OC\AppFramework\Bootstrap;
- use Closure;
- use OCP\Calendar\Resource\IBackend as IResourceBackend;
- use OCP\Calendar\Room\IBackend as IRoomBackend;
- use OCP\Collaboration\Reference\IReferenceProvider;
- use OCP\SpeechToText\ISpeechToTextProvider;
- use OCP\Talk\ITalkBackend;
- use OCP\Translation\ITranslationProvider;
- use RuntimeException;
- use function array_shift;
- use OC\Support\CrashReport\Registry;
- use OCP\AppFramework\App;
- use OCP\AppFramework\Bootstrap\IRegistrationContext;
- use OCP\AppFramework\Middleware;
- use OCP\AppFramework\Services\InitialStateProvider;
- use OCP\Authentication\IAlternativeLogin;
- use OCP\Calendar\ICalendarProvider;
- use OCP\Capabilities\ICapability;
- use OCP\Dashboard\IManager;
- use OCP\Dashboard\IWidget;
- use OCP\EventDispatcher\IEventDispatcher;
- use OCP\Files\Template\ICustomTemplateProvider;
- use OCP\Http\WellKnown\IHandler;
- use OCP\Notification\INotifier;
- use OCP\Profile\ILinkAction;
- use OCP\Search\IProvider;
- use OCP\Share\IPublicShareTemplateProvider;
- use OCP\Support\CrashReport\IReporter;
- use OCP\UserMigration\IMigrator as IUserMigrator;
- use Psr\Log\LoggerInterface;
- use Throwable;
- class RegistrationContext {
- /** @var ServiceRegistration<ICapability>[] */
- private $capabilities = [];
- /** @var ServiceRegistration<IReporter>[] */
- private $crashReporters = [];
- /** @var ServiceRegistration<IWidget>[] */
- private $dashboardPanels = [];
- /** @var ServiceRegistration<ILinkAction>[] */
- private $profileLinkActions = [];
- /** @var null|ServiceRegistration<ITalkBackend> */
- private $talkBackendRegistration = null;
- /** @var ServiceRegistration<IResourceBackend>[] */
- private $calendarResourceBackendRegistrations = [];
- /** @var ServiceRegistration<IRoomBackend>[] */
- private $calendarRoomBackendRegistrations = [];
- /** @var ServiceRegistration<IUserMigrator>[] */
- private $userMigrators = [];
- /** @var ServiceFactoryRegistration[] */
- private $services = [];
- /** @var ServiceAliasRegistration[] */
- private $aliases = [];
- /** @var ParameterRegistration[] */
- private $parameters = [];
- /** @var EventListenerRegistration[] */
- private $eventListeners = [];
- /** @var MiddlewareRegistration[] */
- private $middlewares = [];
- /** @var ServiceRegistration<IProvider>[] */
- private $searchProviders = [];
- /** @var ServiceRegistration<IAlternativeLogin>[] */
- private $alternativeLogins = [];
- /** @var ServiceRegistration<InitialStateProvider>[] */
- private $initialStates = [];
- /** @var ServiceRegistration<IHandler>[] */
- private $wellKnownHandlers = [];
- /** @var ServiceRegistration<ISpeechToTextProvider>[] */
- private $speechToTextProviders = [];
- /** @var ServiceRegistration<ICustomTemplateProvider>[] */
- private $templateProviders = [];
- /** @var ServiceRegistration<ITranslationProvider>[] */
- private $translationProviders = [];
- /** @var ServiceRegistration<INotifier>[] */
- private $notifierServices = [];
- /** @var ServiceRegistration<\OCP\Authentication\TwoFactorAuth\IProvider>[] */
- private $twoFactorProviders = [];
- /** @var ServiceRegistration<ICalendarProvider>[] */
- private $calendarProviders = [];
- /** @var ServiceRegistration<IReferenceProvider>[] */
- private array $referenceProviders = [];
- /** @var ParameterRegistration[] */
- private $sensitiveMethods = [];
- /** @var ServiceRegistration<IPublicShareTemplateProvider>[] */
- private $publicShareTemplateProviders = [];
- /** @var LoggerInterface */
- private $logger;
- /** @var PreviewProviderRegistration[] */
- private $previewProviders = [];
- public function __construct(LoggerInterface $logger) {
- $this->logger = $logger;
- }
- public function for(string $appId): IRegistrationContext {
- return new class($appId, $this) implements IRegistrationContext {
- /** @var string */
- private $appId;
- /** @var RegistrationContext */
- private $context;
- public function __construct(string $appId, RegistrationContext $context) {
- $this->appId = $appId;
- $this->context = $context;
- }
- public function registerCapability(string $capability): void {
- $this->context->registerCapability(
- $this->appId,
- $capability
- );
- }
- public function registerCrashReporter(string $reporterClass): void {
- $this->context->registerCrashReporter(
- $this->appId,
- $reporterClass
- );
- }
- public function registerDashboardWidget(string $widgetClass): void {
- $this->context->registerDashboardPanel(
- $this->appId,
- $widgetClass
- );
- }
- public function registerService(string $name, callable $factory, bool $shared = true): void {
- $this->context->registerService(
- $this->appId,
- $name,
- $factory,
- $shared
- );
- }
- public function registerServiceAlias(string $alias, string $target): void {
- $this->context->registerServiceAlias(
- $this->appId,
- $alias,
- $target
- );
- }
- public function registerParameter(string $name, $value): void {
- $this->context->registerParameter(
- $this->appId,
- $name,
- $value
- );
- }
- public function registerEventListener(string $event, string $listener, int $priority = 0): void {
- $this->context->registerEventListener(
- $this->appId,
- $event,
- $listener,
- $priority
- );
- }
- public function registerMiddleware(string $class, bool $global = false): void {
- $this->context->registerMiddleware(
- $this->appId,
- $class,
- $global,
- );
- }
- public function registerSearchProvider(string $class): void {
- $this->context->registerSearchProvider(
- $this->appId,
- $class
- );
- }
- public function registerAlternativeLogin(string $class): void {
- $this->context->registerAlternativeLogin(
- $this->appId,
- $class
- );
- }
- public function registerInitialStateProvider(string $class): void {
- $this->context->registerInitialState(
- $this->appId,
- $class
- );
- }
- public function registerWellKnownHandler(string $class): void {
- $this->context->registerWellKnown(
- $this->appId,
- $class
- );
- }
- public function registerSpeechToTextProvider(string $providerClass): void {
- $this->context->registerSpeechToTextProvider(
- $this->appId,
- $providerClass
- );
- }
- public function registerTemplateProvider(string $providerClass): void {
- $this->context->registerTemplateProvider(
- $this->appId,
- $providerClass
- );
- }
- public function registerTranslationProvider(string $providerClass): void {
- $this->context->registerTranslationProvider(
- $this->appId,
- $providerClass
- );
- }
- public function registerNotifierService(string $notifierClass): void {
- $this->context->registerNotifierService(
- $this->appId,
- $notifierClass
- );
- }
- public function registerTwoFactorProvider(string $twoFactorProviderClass): void {
- $this->context->registerTwoFactorProvider(
- $this->appId,
- $twoFactorProviderClass
- );
- }
- public function registerPreviewProvider(string $previewProviderClass, string $mimeTypeRegex): void {
- $this->context->registerPreviewProvider(
- $this->appId,
- $previewProviderClass,
- $mimeTypeRegex
- );
- }
- public function registerCalendarProvider(string $class): void {
- $this->context->registerCalendarProvider(
- $this->appId,
- $class
- );
- }
- public function registerReferenceProvider(string $class): void {
- $this->context->registerReferenceProvider(
- $this->appId,
- $class
- );
- }
- public function registerProfileLinkAction(string $actionClass): void {
- $this->context->registerProfileLinkAction(
- $this->appId,
- $actionClass
- );
- }
- public function registerTalkBackend(string $backend): void {
- $this->context->registerTalkBackend(
- $this->appId,
- $backend
- );
- }
- public function registerCalendarResourceBackend(string $class): void {
- $this->context->registerCalendarResourceBackend(
- $this->appId,
- $class
- );
- }
- public function registerCalendarRoomBackend(string $class): void {
- $this->context->registerCalendarRoomBackend(
- $this->appId,
- $class
- );
- }
- public function registerUserMigrator(string $migratorClass): void {
- $this->context->registerUserMigrator(
- $this->appId,
- $migratorClass
- );
- }
- public function registerSensitiveMethods(string $class, array $methods): void {
- $this->context->registerSensitiveMethods(
- $this->appId,
- $class,
- $methods
- );
- }
- public function registerPublicShareTemplateProvider(string $class): void {
- $this->context->registerPublicShareTemplateProvider(
- $this->appId,
- $class
- );
- }
- };
- }
- /**
- * @psalm-param class-string<ICapability> $capability
- */
- public function registerCapability(string $appId, string $capability): void {
- $this->capabilities[] = new ServiceRegistration($appId, $capability);
- }
- /**
- * @psalm-param class-string<IReporter> $capability
- */
- public function registerCrashReporter(string $appId, string $reporterClass): void {
- $this->crashReporters[] = new ServiceRegistration($appId, $reporterClass);
- }
- /**
- * @psalm-param class-string<IWidget> $capability
- */
- public function registerDashboardPanel(string $appId, string $panelClass): void {
- $this->dashboardPanels[] = new ServiceRegistration($appId, $panelClass);
- }
- public function registerService(string $appId, string $name, callable $factory, bool $shared = true): void {
- $this->services[] = new ServiceFactoryRegistration($appId, $name, $factory, $shared);
- }
- public function registerServiceAlias(string $appId, string $alias, string $target): void {
- $this->aliases[] = new ServiceAliasRegistration($appId, $alias, $target);
- }
- public function registerParameter(string $appId, string $name, $value): void {
- $this->parameters[] = new ParameterRegistration($appId, $name, $value);
- }
- public function registerEventListener(string $appId, string $event, string $listener, int $priority = 0): void {
- $this->eventListeners[] = new EventListenerRegistration($appId, $event, $listener, $priority);
- }
- /**
- * @psalm-param class-string<Middleware> $class
- */
- public function registerMiddleware(string $appId, string $class, bool $global): void {
- $this->middlewares[] = new MiddlewareRegistration($appId, $class, $global);
- }
- public function registerSearchProvider(string $appId, string $class) {
- $this->searchProviders[] = new ServiceRegistration($appId, $class);
- }
- public function registerAlternativeLogin(string $appId, string $class): void {
- $this->alternativeLogins[] = new ServiceRegistration($appId, $class);
- }
- public function registerInitialState(string $appId, string $class): void {
- $this->initialStates[] = new ServiceRegistration($appId, $class);
- }
- public function registerWellKnown(string $appId, string $class): void {
- $this->wellKnownHandlers[] = new ServiceRegistration($appId, $class);
- }
- public function registerSpeechToTextProvider(string $appId, string $class): void {
- $this->speechToTextProviders[] = new ServiceRegistration($appId, $class);
- }
- public function registerTemplateProvider(string $appId, string $class): void {
- $this->templateProviders[] = new ServiceRegistration($appId, $class);
- }
- public function registerTranslationProvider(string $appId, string $class): void {
- $this->translationProviders[] = new ServiceRegistration($appId, $class);
- }
- public function registerNotifierService(string $appId, string $class): void {
- $this->notifierServices[] = new ServiceRegistration($appId, $class);
- }
- public function registerTwoFactorProvider(string $appId, string $class): void {
- $this->twoFactorProviders[] = new ServiceRegistration($appId, $class);
- }
- public function registerPreviewProvider(string $appId, string $class, string $mimeTypeRegex): void {
- $this->previewProviders[] = new PreviewProviderRegistration($appId, $class, $mimeTypeRegex);
- }
- public function registerCalendarProvider(string $appId, string $class): void {
- $this->calendarProviders[] = new ServiceRegistration($appId, $class);
- }
- public function registerReferenceProvider(string $appId, string $class): void {
- $this->referenceProviders[] = new ServiceRegistration($appId, $class);
- }
- /**
- * @psalm-param class-string<ILinkAction> $actionClass
- */
- public function registerProfileLinkAction(string $appId, string $actionClass): void {
- $this->profileLinkActions[] = new ServiceRegistration($appId, $actionClass);
- }
- /**
- * @psalm-param class-string<ITalkBackend> $backend
- */
- public function registerTalkBackend(string $appId, string $backend) {
- // Some safeguards for invalid registrations
- if ($appId !== 'spreed') {
- throw new RuntimeException("Only the Talk app is allowed to register a Talk backend");
- }
- if ($this->talkBackendRegistration !== null) {
- throw new RuntimeException("There can only be one Talk backend");
- }
- $this->talkBackendRegistration = new ServiceRegistration($appId, $backend);
- }
- public function registerCalendarResourceBackend(string $appId, string $class) {
- $this->calendarResourceBackendRegistrations[] = new ServiceRegistration(
- $appId,
- $class,
- );
- }
- public function registerCalendarRoomBackend(string $appId, string $class) {
- $this->calendarRoomBackendRegistrations[] = new ServiceRegistration(
- $appId,
- $class,
- );
- }
- /**
- * @psalm-param class-string<IUserMigrator> $migratorClass
- */
- public function registerUserMigrator(string $appId, string $migratorClass): void {
- $this->userMigrators[] = new ServiceRegistration($appId, $migratorClass);
- }
- public function registerSensitiveMethods(string $appId, string $class, array $methods): void {
- $methods = array_filter($methods, 'is_string');
- $this->sensitiveMethods[] = new ParameterRegistration($appId, $class, $methods);
- }
- public function registerPublicShareTemplateProvider(string $appId, string $class): void {
- $this->publicShareTemplateProviders[] = new ServiceRegistration($appId, $class);
- }
- /**
- * @param App[] $apps
- */
- public function delegateCapabilityRegistrations(array $apps): void {
- while (($registration = array_shift($this->capabilities)) !== null) {
- $appId = $registration->getAppId();
- if (!isset($apps[$appId])) {
- // If we land here something really isn't right. But at least we caught the
- // notice that is otherwise emitted for the undefined index
- $this->logger->error("App $appId not loaded for the capability registration");
- continue;
- }
- try {
- $apps[$appId]
- ->getContainer()
- ->registerCapability($registration->getService());
- } catch (Throwable $e) {
- $this->logger->error("Error during capability registration of $appId: " . $e->getMessage(), [
- 'exception' => $e,
- ]);
- }
- }
- }
- /**
- * @param App[] $apps
- */
- public function delegateCrashReporterRegistrations(array $apps, Registry $registry): void {
- while (($registration = array_shift($this->crashReporters)) !== null) {
- try {
- $registry->registerLazy($registration->getService());
- } catch (Throwable $e) {
- $appId = $registration->getAppId();
- $this->logger->error("Error during crash reporter registration of $appId: " . $e->getMessage(), [
- 'exception' => $e,
- ]);
- }
- }
- }
- /**
- * @param App[] $apps
- */
- public function delegateDashboardPanelRegistrations(IManager $dashboardManager): void {
- while (($panel = array_shift($this->dashboardPanels)) !== null) {
- try {
- $dashboardManager->lazyRegisterWidget($panel->getService(), $panel->getAppId());
- } catch (Throwable $e) {
- $appId = $panel->getAppId();
- $this->logger->error("Error during dashboard registration of $appId: " . $e->getMessage(), [
- 'exception' => $e,
- ]);
- }
- }
- }
- public function delegateEventListenerRegistrations(IEventDispatcher $eventDispatcher): void {
- while (($registration = array_shift($this->eventListeners)) !== null) {
- try {
- $eventDispatcher->addServiceListener(
- $registration->getEvent(),
- $registration->getService(),
- $registration->getPriority()
- );
- } catch (Throwable $e) {
- $appId = $registration->getAppId();
- $this->logger->error("Error during event listener registration of $appId: " . $e->getMessage(), [
- 'exception' => $e,
- ]);
- }
- }
- }
- /**
- * @param App[] $apps
- */
- public function delegateContainerRegistrations(array $apps): void {
- while (($registration = array_shift($this->services)) !== null) {
- $appId = $registration->getAppId();
- if (!isset($apps[$appId])) {
- // If we land here something really isn't right. But at least we caught the
- // notice that is otherwise emitted for the undefined index
- $this->logger->error("App $appId not loaded for the container service registration");
- continue;
- }
- try {
- /**
- * Register the service and convert the callable into a \Closure if necessary
- */
- $apps[$appId]
- ->getContainer()
- ->registerService(
- $registration->getName(),
- Closure::fromCallable($registration->getFactory()),
- $registration->isShared()
- );
- } catch (Throwable $e) {
- $this->logger->error("Error during service registration of $appId: " . $e->getMessage(), [
- 'exception' => $e,
- ]);
- }
- }
- while (($registration = array_shift($this->aliases)) !== null) {
- $appId = $registration->getAppId();
- if (!isset($apps[$appId])) {
- // If we land here something really isn't right. But at least we caught the
- // notice that is otherwise emitted for the undefined index
- $this->logger->error("App $appId not loaded for the container alias registration");
- continue;
- }
- try {
- $apps[$appId]
- ->getContainer()
- ->registerAlias(
- $registration->getAlias(),
- $registration->getTarget()
- );
- } catch (Throwable $e) {
- $this->logger->error("Error during service alias registration of $appId: " . $e->getMessage(), [
- 'exception' => $e,
- ]);
- }
- }
- while (($registration = array_shift($this->parameters)) !== null) {
- $appId = $registration->getAppId();
- if (!isset($apps[$appId])) {
- // If we land here something really isn't right. But at least we caught the
- // notice that is otherwise emitted for the undefined index
- $this->logger->error("App $appId not loaded for the container parameter registration");
- continue;
- }
- try {
- $apps[$appId]
- ->getContainer()
- ->registerParameter(
- $registration->getName(),
- $registration->getValue()
- );
- } catch (Throwable $e) {
- $this->logger->error("Error during service parameter registration of $appId: " . $e->getMessage(), [
- 'exception' => $e,
- ]);
- }
- }
- }
- /**
- * @return MiddlewareRegistration[]
- */
- public function getMiddlewareRegistrations(): array {
- return $this->middlewares;
- }
- /**
- * @return ServiceRegistration<IProvider>[]
- */
- public function getSearchProviders(): array {
- return $this->searchProviders;
- }
- /**
- * @return ServiceRegistration<IAlternativeLogin>[]
- */
- public function getAlternativeLogins(): array {
- return $this->alternativeLogins;
- }
- /**
- * @return ServiceRegistration<InitialStateProvider>[]
- */
- public function getInitialStates(): array {
- return $this->initialStates;
- }
- /**
- * @return ServiceRegistration<IHandler>[]
- */
- public function getWellKnownHandlers(): array {
- return $this->wellKnownHandlers;
- }
- /**
- * @return ServiceRegistration<ISpeechToTextProvider>[]
- */
- public function getSpeechToTextProviders(): array {
- return $this->speechToTextProviders;
- }
- /**
- * @return ServiceRegistration<ICustomTemplateProvider>[]
- */
- public function getTemplateProviders(): array {
- return $this->templateProviders;
- }
- /**
- * @return ServiceRegistration<ITranslationProvider>[]
- */
- public function getTranslationProviders(): array {
- return $this->translationProviders;
- }
- /**
- * @return ServiceRegistration<INotifier>[]
- */
- public function getNotifierServices(): array {
- return $this->notifierServices;
- }
- /**
- * @return ServiceRegistration<\OCP\Authentication\TwoFactorAuth\IProvider>[]
- */
- public function getTwoFactorProviders(): array {
- return $this->twoFactorProviders;
- }
- /**
- * @return PreviewProviderRegistration[]
- */
- public function getPreviewProviders(): array {
- return $this->previewProviders;
- }
- /**
- * @return ServiceRegistration<ICalendarProvider>[]
- */
- public function getCalendarProviders(): array {
- return $this->calendarProviders;
- }
- /**
- * @return ServiceRegistration<IReferenceProvider>[]
- */
- public function getReferenceProviders(): array {
- return $this->referenceProviders;
- }
- /**
- * @return ServiceRegistration<ILinkAction>[]
- */
- public function getProfileLinkActions(): array {
- return $this->profileLinkActions;
- }
- /**
- * @return ServiceRegistration|null
- * @psalm-return ServiceRegistration<ITalkBackend>|null
- */
- public function getTalkBackendRegistration(): ?ServiceRegistration {
- return $this->talkBackendRegistration;
- }
- /**
- * @return ServiceRegistration[]
- * @psalm-return ServiceRegistration<IResourceBackend>[]
- */
- public function getCalendarResourceBackendRegistrations(): array {
- return $this->calendarResourceBackendRegistrations;
- }
- /**
- * @return ServiceRegistration[]
- * @psalm-return ServiceRegistration<IRoomBackend>[]
- */
- public function getCalendarRoomBackendRegistrations(): array {
- return $this->calendarRoomBackendRegistrations;
- }
- /**
- * @return ServiceRegistration<IUserMigrator>[]
- */
- public function getUserMigrators(): array {
- return $this->userMigrators;
- }
- /**
- * @return ParameterRegistration[]
- */
- public function getSensitiveMethods(): array {
- return $this->sensitiveMethods;
- }
- /**
- * @return ServiceRegistration<IPublicShareTemplateProvider>[]
- */
- public function getPublicShareTemplateProviders(): array {
- return $this->publicShareTemplateProviders;
- }
- }
|