-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Mailer] Improve oauth setup #52585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 7.4
Are you sure you want to change the base?
[Mailer] Improve oauth setup #52585
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2556,6 +2556,11 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co | |
} else { | ||
$mailer->replaceArgument(1, $messageBus ? new Reference($messageBus) : new Reference('messenger.default_bus', ContainerInterface::NULL_ON_INVALID_REFERENCE)); | ||
} | ||
$authenticators = []; | ||
foreach ($config['smtp']['authenticators'] ?? [] as $authenticator) { | ||
$authenticators[] = new Reference($authenticator); | ||
} | ||
$container->getDefinition('mailer.transport_factory.smtp')->setArgument(3, $authenticators); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. according to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the weird error message could be because of inlining the transport factory services. It might be inside one of the inlined services inside the mailer service. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is that a bug of the DI container, or should i be doing something differently? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would not call it a bug. The hard thing is that inline definitions don't have an id. So that's hard to know how to mention them in error messages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if it is not a bug, what do i need differently to set the parameter on the correct place? |
||
|
||
$classToServices = [ | ||
MailerBridge\Brevo\Transport\BrevoTransportFactory::class => 'mailer.transport_factory.brevo', | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator; | ||
|
||
return static function (ContainerConfigurator $container) { | ||
$container->extension('framework', [ | ||
'annotations' => false, | ||
'http_method_override' => false, | ||
'handle_all_throwables' => true, | ||
'php_errors' => ['log' => true], | ||
'mailer' => [ | ||
'smtp' => [ | ||
'authenticators' => [ | ||
'my_authenticator_service1', | ||
'my_authenticator_service2', | ||
], | ||
], | ||
], | ||
]); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" ?> | ||
|
||
<container xmlns="http://symfony.com/schema/dic/services" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns:framework="http://symfony.com/schema/dic/symfony" | ||
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd | ||
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> | ||
|
||
<framework:config http-method-override="false" handle-all-throwables="true"> | ||
<framework:annotations enabled="false" /> | ||
<framework:php-errors log="true" /> | ||
<framework:mailer dsn="smtp://example.com"> | ||
<framework:smtp> | ||
<framework:authenticator>my_authenticator_service1</framework:authenticator> | ||
<framework:authenticator>my_authenticator_service2</framework:authenticator> | ||
</framework:smtp> | ||
</framework:mailer> | ||
</framework:config> | ||
</container> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
framework: | ||
annotations: false | ||
http_method_override: false | ||
handle_all_throwables: true | ||
php_errors: | ||
log: true | ||
mailer: | ||
smtp: | ||
authenticators: | ||
- my_authenticator_service1 | ||
- my_authenticator_service2 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Mailer\Transport\Smtp\Auth; | ||
|
||
/** | ||
* The auth token provider knows how to create a valid token for the XOAuth2Authenticator. | ||
* | ||
* Usually with OAuth, you will need to do some web request to fetch the token. | ||
* You also want to cache the token for as long as it is valid. | ||
*/ | ||
interface AuthTokenProviderInterface | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TokenProviderInterface? |
||
{ | ||
/** | ||
* Acquire the authentication token. | ||
*/ | ||
public function getToken(): string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,23 +11,41 @@ | |
|
||
namespace Symfony\Component\Mailer\Transport\Smtp; | ||
|
||
use Psr\EventDispatcher\EventDispatcherInterface; | ||
use Psr\Log\LoggerInterface; | ||
use Symfony\Component\Mailer\Transport\AbstractTransportFactory; | ||
use Symfony\Component\Mailer\Transport\Dsn; | ||
use Symfony\Component\Mailer\Transport\Smtp\Auth\AuthenticatorInterface; | ||
use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; | ||
use Symfony\Component\Mailer\Transport\TransportInterface; | ||
use Symfony\Contracts\HttpClient\HttpClientInterface; | ||
|
||
/** | ||
* @author Konstantin Myakshin <[email protected]> | ||
*/ | ||
final class EsmtpTransportFactory extends AbstractTransportFactory | ||
{ | ||
/** | ||
* @var AuthenticatorInterface[] | ||
*/ | ||
private ?array $authenticators; | ||
|
||
/** | ||
* @param AuthenticatorInterface[]|null $authenticators | ||
*/ | ||
public function __construct(EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null, array $authenticators = null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure we need the new argument: calling setAuthenticators on the resulting instance should be enough |
||
{ | ||
parent::__construct($dispatcher, $client, $logger); | ||
$this->authenticators = $authenticators; | ||
} | ||
|
||
public function create(Dsn $dsn): TransportInterface | ||
{ | ||
$tls = 'smtps' === $dsn->getScheme() ? true : null; | ||
$port = $dsn->getPort(0); | ||
$host = $dsn->getHost(); | ||
|
||
$transport = new EsmtpTransport($host, $port, $tls, $this->dispatcher, $this->logger); | ||
$transport = new EsmtpTransport($host, $port, $tls, $this->dispatcher, $this->logger, null, $this->authenticators); | ||
|
||
/** @var SocketStream $stream */ | ||
$stream = $transport->getStream(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of adding a new config entry, I'd suggest passing a tagged_locator in the service definition
we should define the default authenticators as services with low priority so that then adding a new authenticator is just a matter of creating a new class that implements AuthenticatorInterface, thanks to registerForAutoconfiguration.