Failed Conditions
Push — v7 ( a94305...5a1c51 )
by Florent
02:15
created

JWSLoader::populatePayload()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 8.7624
c 0
b 0
f 0
cc 5
eloc 15
nc 7
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2017 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace Jose\Component\Signature;
15
16
use Assert\Assertion;
17
use Base64Url\Base64Url;
18
19
/**
20
 * Class able to load JWS.
21
 */
22
final class JWSLoader
23
{
24
    /**
25
     * Load data and return a JWS object.
26
     * Compact, Flattened or complete serialization formats are supported.
27
     *
28
     * @param string $input A string that represents a JWS
29
     *
30
     * @return JWS
31
     */
32
    public static function load(string $input): JWS
33
    {
34
        $json = JWSConverter::convert($input);
35
36
        $jws = JWS::create();
37
38
        foreach ($json['signatures'] as $signature) {
39
            $bin_signature = Base64Url::decode($signature['signature']);
40
            $protected_headers = self::getProtectedHeaders($signature);
41
            $headers = self::getHeaders($signature);
42
43
            $jws = $jws->addSignature($bin_signature, $protected_headers, $headers);
44
        }
45
46
        self::populatePayload($jws, $json);
47
48
        return $jws;
49
    }
50
51
    /**
52
     * @param array $data
53
     *
54
     * @return string|null
55
     */
56
    private static function getProtectedHeaders(array $data): ?string
57
    {
58
        if (array_key_exists('protected', $data)) {
59
            return $data['protected'];
60
        }
61
62
        return null;
63
    }
64
65
    /**
66
     * @param array $data
67
     *
68
     * @return array
69
     */
70
    private static function getHeaders(array $data): array
71
    {
72
        if (array_key_exists('header', $data)) {
73
            return $data['header'];
74
        }
75
76
        return [];
77
    }
78
79
    /**
80
     * @param JWS   $jws
81
     * @param array $data
82
     */
83
    private static function populatePayload(JWS &$jws, array $data)
84
    {
85
        if (array_key_exists('payload', $data)) {
86
            $isPayloadEncoded = null;
87
            foreach ($jws->getSignatures() as $signature) {
88
                if (null === $isPayloadEncoded) {
89
                    $isPayloadEncoded = self::isPayloadEncoded($signature);
90
                }
91
                Assertion::eq($isPayloadEncoded, self::isPayloadEncoded($signature), 'Foreign payload encoding detected. The JWS cannot be loaded.');
92
            }
93
            $payload = $data['payload'];
94
            $jws = $jws->withAttachedPayload();
95
            $jws = $jws->withEncodedPayload($payload);
96
            if (false !== $isPayloadEncoded) {
97
                $payload = Base64Url::decode($payload);
98
            }
99
            $jws = $jws->withPayload($payload);
100
        } else {
101
            $jws = $jws->withDetachedPayload();
102
        }
103
    }
104
105
    /**
106
     * @param Signature $signature
107
     *
108
     * @return bool
109
     */
110
    private static function isPayloadEncoded(Signature $signature): bool
111
    {
112
        return !$signature->hasProtectedHeader('b64') || true === $signature->getProtectedHeader('b64');
113
    }
114
}
115