ForceTlsUpgradeNegotiation   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 100%

Importance

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

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A negotiate() 0 31 4
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Protocol\Imap\Negotiation;
5
6
use Genkgo\Mail\Exception\ConnectionInsecureException;
7
use Genkgo\Mail\Protocol\ConnectionInterface;
8
use Genkgo\Mail\Protocol\Imap\Client;
9
use Genkgo\Mail\Protocol\Imap\NegotiationInterface;
10
use Genkgo\Mail\Protocol\Imap\Request\CapabilityCommand;
11
use Genkgo\Mail\Protocol\Imap\Request\StartTlsCommand;
12
use Genkgo\Mail\Protocol\Imap\Response\Command\CapabilityCommandResponse;
13
use Genkgo\Mail\Protocol\Imap\Response\CompletionResult;
14
15
final class ForceTlsUpgradeNegotiation implements NegotiationInterface
16
{
17
    /**
18
     * @var ConnectionInterface
19
     */
20
    private $connection;
21
22
    /**
23
     * @var int
24
     */
25
    private $crypto;
26
27
    /**
28
     * @param ConnectionInterface $connection
29
     * @param int $crypto
30
     */
31 7
    public function __construct(
32
        ConnectionInterface $connection,
33
        int $crypto
34
    ) {
35 7
        $this->connection = $connection;
36 7
        $this->crypto = $crypto;
37 7
    }
38
39
    /**
40
     * @param Client $client
41
     * @throws ConnectionInsecureException
42
     */
43 4
    public function negotiate(Client $client): void
44
    {
45 4
        if (!empty($this->connection->getMetaData(['crypto']))) {
46 1
            return;
47
        }
48
49 3
        $responseList = $client->emit(new CapabilityCommand($client->newTag()));
50
51 3
        $capabilities = CapabilityCommandResponse::fromString($responseList->first()->getBody());
52
53
        $responseList
54 3
            ->last()
55 3
            ->assertCompletion(CompletionResult::ok())
56 3
            ->assertTagged();
57
58 3
        if ($capabilities->isAdvertising('STARTTLS')) {
59
            $client
60 2
                ->emit(new StartTlsCommand($client->newTag()))
61 2
                ->last()
62 2
                ->assertCompletion(CompletionResult::ok())
63 2
                ->assertTagged();
64
65 2
            $this->connection->upgrade($this->crypto);
66
        }
67
68 3
        if (empty($this->connection->getMetaData(['crypto']))) {
69 1
            throw new ConnectionInsecureException(
70 1
                'Server does not support STARTTLS. Use imaps:// or to allow insecure connections use imap-starttls://'
71
            );
72
        }
73 2
    }
74
}
75