Completed
Push — master ( 4edb1e...e1389e )
by Frederik
02:12
created

ForceTlsUpgradeNegotiation   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 5
lcom 1
cbo 7
dl 0
loc 60
c 0
b 0
f 0
rs 10
ccs 18
cts 18
cp 1

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
B negotiate() 0 23 4
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Protocol\Smtp\Negotiation;
5
6
use Genkgo\Mail\Exception\ConnectionInsecureException;
7
use Genkgo\Mail\Protocol\ConnectionInterface;
8
use Genkgo\Mail\Protocol\CryptoConstant;
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\StartTlsCommand;
13
use Genkgo\Mail\Protocol\Smtp\Response\EhloResponse;
14
15
final class ForceTlsUpgradeNegotiation implements NegotiationInterface
16
{
17
    /**
18
     * @var ConnectionInterface
19
     */
20
    private $connection;
21
    /**
22
     * @var string
23
     */
24
    private $ehlo;
25
    /**
26
     * @var int
27
     */
28
    private $crypto;
29
30
    /**
31
     * ConnectionNegotiation constructor.
32
     * @param ConnectionInterface $connection
33
     * @param string $ehlo
34
     * @param int $crypto
35
     */
36 7
    public function __construct(
37
        ConnectionInterface $connection,
38
        string $ehlo,
39
        int $crypto = CryptoConstant::TYPE_BEST_PRACTISE
40
    ) {
41 7
        $this->connection = $connection;
42 7
        $this->ehlo = $ehlo;
43 7
        $this->crypto = $crypto;
44 7
    }
45
46
47
    /**
48
     * @param Client $client
49
     * @throws ConnectionInsecureException
50
     */
51 4
    public function negotiate(Client $client): void
52
    {
53 4
        if (empty($this->connection->getMetaData(['crypto']))) {
54 4
            $reply = $client->request(new EhloCommand($this->ehlo));
55 4
            $reply->assertCompleted();
56
57 4
            $ehloResponse = new EhloResponse($reply);
58
59 4
            if ($ehloResponse->isAdvertising('STARTTLS')) {
60
                $client
61 3
                    ->request(new StartTlsCommand())
62 3
                    ->assertCompleted();
63
64 3
                $this->connection->upgrade($this->crypto);
65
            }
66
        }
67
68 4
        if (empty($this->connection->getMetaData(['crypto']))) {
69 1
            throw new ConnectionInsecureException(
70 1
                'Server does not support STARTTLS. Use smtp+tls:// or to allow insecure connections use smtp+plain://'
71
            );
72
        }
73
    }
74
}