Completed
Push — master ( 580028...d7e9e8 )
by Charles
02:19
created

Json25519Parser::parse()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 42
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 42
rs 4.909
cc 9
eloc 24
nc 9
nop 2
1
<?php
2
3
namespace yrc\web;
4
5
use yii\helpers\Json;
6
use yii\web\JsonParser;
7
use yrc\api\models\TokenKeyPair;
8
9
use yii\web\BadRequestHttpException;
10
use Yii;
11
12
/**
13
 * Allows for requests to be encrypted and signed via Curve/Ed 25519 cryptography via libsodium
14
 * @class Json25519 Parser
15
 */
16
class Json25519Parser extends JsonParser
17
{
18
    const HASH_HEADER = 'x-hashid';
19
20
    const PUBLICKEY_HEADER = 'x-pubkey';
21
22
    /**
23
     * Parses a HTTP request body.
24
     * @param string $rawBody the raw HTTP request body.
25
     * @param string $contentType the content type specified for the request body.
26
     * @return array parameters parsed from the request body
27
     * @throws BadRequestHttpException if the body contains invalid json and [[throwException]] is `true`.
28
     */
29
    public function parse($rawBody, $contentType)
30
    {
31
        // If the content type isn't application/json+25519 try the parent validator
32
        if ($contentType !== 'application/json+25519') {
33
            return parent::parse($rawBody, $contentType);
34
        }
35
36
        // Fetch the hash from the header
37
        $hash = Yii::$app->request->getHeaders()->get(self::HASH_HEADER, null);
38
        if ($hash === null) {
39
            throw new BadRequestHttpException(Yii::t('yrc', 'Missing x-hashid header'));
40
        }
41
42
        $token = TokenKeyPair::find(['hash' => $hash])->one();
43
44
        if ($token === null) {
45
            throw new BadRequestHttpException(Yii::t('yrc', 'Invalid x-hashid header. The provided header is either invalid or expired.'));
46
        }
47
        try {
48
            // We are using an anonymous box so as to not identity the customer
49
            $rawBody = \Sodium\crypto_box_seal_open(
50
                \base64_decode($rawBody),
51
                $token->getBoxKeyPair()
52
            );
53
54
            if ($rawBody === false) {
55
                throw new \Exception;
56
            }
57
        } catch (\Exception $e) {
58
            throw new BadRequestHttpException(Yii::t('yrc', 'Invalid x-hashid header. The provided header is either invalid or expired.'));
59
        }
60
61
        try {
62
            $parameters = Json::decode($rawBody, $this->asArray);
63
            return $parameters === null ? [] : $parameters;
64
        } catch (InvalidParamException $e) {
0 ignored issues
show
Bug introduced by
The class yrc\web\InvalidParamException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
65
            if ($this->throwException) {
66
                throw new BadRequestHttpException('Invalid JSON data in request body: ' . $e->getMessage());
67
            }
68
            return [];
69
        }
70
    }
71
}