Completed
Push — master ( 76c0f1...a16dbf )
by Christian
01:43
created

PandaSigner::getInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
crap 1
1
<?php
2
3
/*
4
 * This file is part of the XabbuhPandaClient package.
5
 *
6
 * (c) Christian Flothmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Xabbuh\PandaClient\Signer;
13
14
use Xabbuh\PandaClient\Api\Account;
15
16
/**
17
 * Sign Panda HTTP requests.
18
 *
19
 * @author Christian Flothmann <[email protected]>
20
 */
21
class PandaSigner
22
{
23
    /**
24
     * Panda cloud id
25
     *
26
     * @var string
27
     */
28
    private $cloudId;
29
30
    /**
31
     * Panda Account
32
     *
33
     * @var Account
34
     */
35
    private $account;
36
37 10
    private function __construct()
38
    {
39 10
    }
40
41
    /**
42
     * Sets the cloud id.
43
     *
44
     * @param string $cloudId
45
     */
46 10
    public function setCloudId($cloudId)
47
    {
48 10
        $this->cloudId = $cloudId;
49 10
    }
50
51
    /**
52
     * Returns the cloud id.
53
     *
54
     * @return string
55
     */
56
    public function getCloudId()
57
    {
58
        return $this->cloudId;
59
    }
60
61
    /**
62
     * Sets the Account that contains the authorization information.
63
     *
64
     * @param Account $account
65
     */
66 10
    public function setAccount(Account $account)
67
    {
68 10
        $this->account = $account;
69 10
    }
70
71
    /**
72
     * Returns the Account used for generating signatures.
73
     *
74
     * @return Account
75
     */
76
    public function getAccount()
77
    {
78
        return $this->account;
79
    }
80
81
    /**
82
     * Generates the signature for a given set of request parameters and add
83
     * this signature to the set of parameters.
84
     *
85
     * @param string   $method The HTTP method
86
     * @param string   $path   The request path
87
     * @param string[] $params Request parameters
88
     *
89
     * @return string[] The signed parameters
90
     */
91 8
    public function signParams($method, $path, array $params = array())
92
    {
93 8
        $params = $this->completeParams($params);
94
95
        // generate the signature
96 8
        $params['signature'] = $this->signature($method, $path, $params);
97
98 8
        return $params;
99
    }
100
101
    /**
102
     * Generates the signature for an API requests based on its parameters.
103
     *
104
     * @param string   $method The HTTP method
105
     * @param string   $path   The request path
106
     * @param string[] $params Request parameters
107
     *
108
     * @return string The generated signature
109
     */
110 10
    public function signature($method, $path, array $params = array())
111
    {
112 10
        $params = $this->completeParams($params);
113
114 10
        ksort($params);
115
116 10
        if (isset($params['file'])) {
117
            unset($params['file']);
118
        }
119
120 10
        $canonicalQueryString = str_replace(
121 10
            array('+', '%5B', '%5D'),
122 10
            array('%20', '[', ']'),
123 10
            http_build_query($params, '', '&')
124
        );
125 10
        $stringToSign = sprintf(
126 10
            "%s\n%s\n%s\n%s",
127
            strtoupper($method),
128 10
            $this->account->getApiHost(),
129
            $path,
130
            $canonicalQueryString
131
        );
132 10
        $hmac = hash_hmac('sha256', $stringToSign, $this->account->getSecretKey(), true);
133
134 10
        return base64_encode($hmac);
135
    }
136
137
    /**
138
     * Returns a Signing instance for a Cloud.
139
     *
140
     * @param string  $cloudId The cloud id
141
     * @param Account $account The authorization details
142
     *
143
     * @return PandaSigner The generated Signing instance
144
     */
145 10
    public static function getInstance($cloudId, Account $account)
146
    {
147 10
        $signer = new PandaSigner();
148 10
        $signer->setCloudId($cloudId);
149 10
        $signer->setAccount($account);
150
151 10
        return $signer;
152
    }
153
154 10
    private function completeParams(array $params)
155
    {
156 10
        if (!isset($params['cloud_id'])) {
157 8
            $params['cloud_id'] = $this->cloudId;
158
        }
159
160 10
        if (!isset($params['access_key'])) {
161 8
            $params['access_key'] = $this->account->getAccessKey();
162
        }
163
164 10
        if (!isset($params['timestamp'])) {
165 6
            $oldTz = date_default_timezone_get();
166 6
            date_default_timezone_set('UTC');
167 6
            $params['timestamp'] = date('c');
168 6
            date_default_timezone_set($oldTz);
169
        }
170
171 10
        return $params;
172
    }
173
}
174