ForceTlsUpgradeNegotiation::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Protocol\Smtp\Negotiation;
5
6
use Genkgo\Mail\Exception\AssertionFailedException;
7
use Genkgo\Mail\Exception\ConnectionInsecureException;
8
use Genkgo\Mail\Protocol\ConnectionInterface;
9
use Genkgo\Mail\Protocol\Smtp\Client;
10
use Genkgo\Mail\Protocol\Smtp\NegotiationInterface;
11
use Genkgo\Mail\Protocol\Smtp\Request\EhloCommand;
12
use Genkgo\Mail\Protocol\Smtp\Request\HeloCommand;
13
use Genkgo\Mail\Protocol\Smtp\Request\StartTlsCommand;
14
use Genkgo\Mail\Protocol\Smtp\Response\EhloResponse;
15
16
final class ForceTlsUpgradeNegotiation implements NegotiationInterface
17
{
18
    /**
19
     * @var ConnectionInterface
20
     */
21
    private $connection;
22
23
    /**
24
     * @var string
25
     */
26
    private $ehlo;
27
28
    /**
29
     * @var int
30
     */
31
    private $crypto;
32
33
    /**
34
     * @param ConnectionInterface $connection
35
     * @param string $ehlo
36
     * @param int $crypto
37
     */
38 10
    public function __construct(
39
        ConnectionInterface $connection,
40
        string $ehlo,
41
        int $crypto
42
    ) {
43 10
        $this->connection = $connection;
44 10
        $this->ehlo = $ehlo;
45 10
        $this->crypto = $crypto;
46 10
    }
47
48
    /**
49
     * @param Client $client
50
     * @throws ConnectionInsecureException
51
     */
52 7
    public function negotiate(Client $client): void
53
    {
54 7
        if (!empty($this->connection->getMetaData(['crypto']))) {
55 1
            return;
56
        }
57
58 6
        $reply = $client->request(new EhloCommand($this->ehlo));
59
60 6
        if ($reply->isCommandNotImplemented()) {
61 2
            $reply = $client->request(new HeloCommand($this->ehlo));
62 2
            $reply->assertCompleted();
63
64
            try {
65
                $client
66 2
                    ->request(new StartTlsCommand())
67 2
                    ->assertCompleted();
68
69 1
                $this->connection->upgrade($this->crypto);
70 1
            } catch (AssertionFailedException $e) {
71 1
                throw new ConnectionInsecureException(
72 2
                    'Server does not support STARTTLS. Use smtps:// or to allow insecure connections use smtp-starttls://'
73
                );
74
            }
75
        } else {
76 4
            $reply->assertCompleted();
77
78 4
            $ehloResponse = new EhloResponse($reply);
79 4
            if ($ehloResponse->isAdvertising('STARTTLS')) {
80
                $client
81 3
                    ->request(new StartTlsCommand())
82 3
                    ->assertCompleted();
83
84 3
                $this->connection->upgrade($this->crypto);
85
            }
86
        }
87
88 5
        if (empty($this->connection->getMetaData(['crypto']))) {
89 1
            throw new ConnectionInsecureException(
90 1
                'Server does not support STARTTLS. Use smtps:// or to allow insecure connections use smtp-starttls://'
91
            );
92
        }
93 4
    }
94
}
95