PinEntry::setOption()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
ccs 0
cts 5
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\PinEntry;
6
7
use BitWasp\PinEntry\Assuan\Assuan;
8
use BitWasp\PinEntry\Exception\PinEntryException;
9
use BitWasp\PinEntry\PinValidation\PinValidatorInterface;
10
use BitWasp\PinEntry\Process\ProcessInterface;
11
12
class PinEntry
13
{
14
    /**
15
     * @var ProcessInterface
16
     */
17
    private $process;
18
19
    /**
20
     * @var Assuan
21
     */
22
    private $assuan;
23
24
    public function __construct(ProcessInterface $process, Assuan $assuan = null)
25
    {
26
        $response = $process->recv();
27
        if ($response !== "OK Pleased to meet you\n") {
28
            throw new PinEntryException("First message from pinentry did not match expected value");
29
        }
30
        $this->process = $process;
31
        $this->assuan = $assuan ?: new Assuan();
32
    }
33
34
    /**
35
     * @param string $key
36
     * @param string $value
37
     * @return Response
38
     * @throws Exception\RemotePinEntryException
39
     */
40
    public function setOption(string $key, string $value): Response
41
    {
42
        $this->assuan->send($this->process, Command::OPTION, "{$key} {$value}");
43
        $msg = $this->assuan->parseResponse($this->process);
44
        return $msg;
45
    }
46
47
    public function getPID(): int
48
    {
49
        return (int) $this->getInfo('pid');
50
    }
51
52
    public function getVersion(): string
53
    {
54
        return $this->getInfo('version');
55
    }
56
57
    public function getInfo(string $type): string
58
    {
59
        $this->process->send(Command::GETINFO . " {$type}\n");
60
        $response = $this->assuan->parseResponse($this->process);
61
62
        if (empty($response->getData())) {
63
            throw new \RuntimeException("expecting info in response");
64
        }
65
        list ($result) = $response->getData();
66
67
        return $result;
68
    }
69
70
    public function getPin(PinRequest $request, PinValidatorInterface $pinValidator): string
71
    {
72
        foreach ($request->getCommands() as $command => $param) {
73
            $this->assuan->send($this->process, $command, $param);
74
            $this->assuan->parseResponse($this->process);
75
        }
76
77
        $error = null;
78
        $pin = '';
79
        while (!$pinValidator->validate($pin, $error)) {
80
            if ($pin !== '') {
81
                $this->assuan->send($this->process, Command::SETERROR, $error);
82
                $this->assuan->parseResponse($this->process);
83
            }
84
85
            $this->assuan->send($this->process, Command::GETPIN);
86
            $response = $this->assuan->parseResponse($this->process);
87
            if (empty($response->getData())) {
88
                throw new \RuntimeException("expecting pin in response");
89
            }
90
91
            list ($pin) = $response->getData();
92
        }
93
94
        return $pin;
95
    }
96
}
97