Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace Aws\S3;
3
 
4
use Aws\Credentials\CredentialsInterface;
5
use GuzzleHttp\Psr7\Uri;
6
use Aws\Signature\SignatureTrait;
7
use Aws\Signature\SignatureV4 as SignatureV4;
8
use Aws\Api\TimestampShape as TimestampShape;
9
 
10
/**
11
 * Encapsulates the logic for getting the data for an S3 object POST upload form
12
 *
13
 * @link http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html
14
 * @link http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
15
 */
16
class PostObjectV4
17
{
18
    use SignatureTrait;
19
 
20
    private $client;
21
    private $bucket;
22
    private $formAttributes;
23
    private $formInputs;
24
 
25
    /**
26
     * Constructs the PostObject.
27
     *
28
     * The options array accepts the following keys:
29
     * @link http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
30
     *
31
     * @param S3ClientInterface $client     Client used with the POST object
32
     * @param string            $bucket     Bucket to use
33
     * @param array             $formInputs Associative array of form input
34
     *                                      fields.
35
     * @param array             $options    Policy condition options
36
     * @param mixed             $expiration Upload expiration time value. By
37
     *                                      default: 1 hour valid period.
38
     */
39
    public function __construct(
40
        S3ClientInterface $client,
41
        $bucket,
42
        array $formInputs,
43
        array $options = [],
44
        $expiration = '+1 hours'
45
    ) {
46
        $this->client = $client;
47
        $this->bucket = $bucket;
48
 
49
        // setup form attributes
50
        $this->formAttributes = [
51
            'action'  => $this->generateUri(),
52
            'method'  => 'POST',
53
            'enctype' => 'multipart/form-data'
54
        ];
55
 
56
        $credentials   = $this->client->getCredentials()->wait();
57
 
58
        if ($securityToken = $credentials->getSecurityToken()) {
59
            $options [] = ['x-amz-security-token' => $securityToken];
60
            $formInputs['X-Amz-Security-Token'] = $securityToken;
61
        }
62
 
63
        // setup basic policy
64
        $policy = [
65
            'expiration' => TimestampShape::format($expiration, 'iso8601'),
66
            'conditions' => $options,
67
        ];
68
 
69
        // setup basic formInputs
70
        $this->formInputs = $formInputs + ['key' => '${filename}'];
71
 
72
        // finalize policy and signature
73
 
74
        $this->formInputs += $this->getPolicyAndSignature(
75
            $credentials,
76
            $policy
77
        );
78
    }
79
 
80
    /**
81
     * Gets the S3 client.
82
     *
83
     * @return S3ClientInterface
84
     */
85
    public function getClient()
86
    {
87
        return $this->client;
88
    }
89
 
90
    /**
91
     * Gets the bucket name.
92
     *
93
     * @return string
94
     */
95
    public function getBucket()
96
    {
97
        return $this->bucket;
98
    }
99
 
100
    /**
101
     * Gets the form attributes as an array.
102
     *
103
     * @return array
104
     */
105
    public function getFormAttributes()
106
    {
107
        return $this->formAttributes;
108
    }
109
 
110
    /**
111
     * Set a form attribute.
112
     *
113
     * @param string $attribute Form attribute to set.
114
     * @param string $value     Value to set.
115
     */
116
    public function setFormAttribute($attribute, $value)
117
    {
118
        $this->formAttributes[$attribute] = $value;
119
    }
120
 
121
    /**
122
     * Gets the form inputs as an array.
123
     *
124
     * @return array
125
     */
126
    public function getFormInputs()
127
    {
128
        return $this->formInputs;
129
    }
130
 
131
    /**
132
     * Set a form input.
133
     *
134
     * @param string $field Field name to set
135
     * @param string $value Value to set.
136
     */
137
    public function setFormInput($field, $value)
138
    {
139
        $this->formInputs[$field] = $value;
140
    }
141
 
142
    private function generateUri()
143
    {
144
        $uri = new Uri($this->client->getEndpoint());
145
 
146
        if ($this->client->getConfig('use_path_style_endpoint') === true
147
            || ($uri->getScheme() === 'https'
148
            && strpos($this->bucket, '.') !== false)
149
        ) {
150
            // Use path-style URLs
151
            $uri = $uri->withPath("/{$this->bucket}");
152
        } else {
153
            // Use virtual-style URLs if haven't been set up already
154
            if (strpos($uri->getHost(), $this->bucket . '.') !== 0) {
155
                $uri = $uri->withHost($this->bucket . '.' . $uri->getHost());
156
            }
157
        }
158
 
159
        return (string) $uri;
160
    }
161
 
162
    protected function getPolicyAndSignature(
163
        CredentialsInterface $credentials,
164
        array $policy
165
    ){
166
        $ldt = gmdate(SignatureV4::ISO8601_BASIC);
167
        $sdt = substr($ldt, 0, 8);
168
        $policy['conditions'][] = ['X-Amz-Date' => $ldt];
169
 
170
        $region = $this->client->getRegion();
171
        $scope = $this->createScope($sdt, $region, 's3');
172
        $creds = "{$credentials->getAccessKeyId()}/$scope";
173
        $policy['conditions'][] = ['X-Amz-Credential' => $creds];
174
 
175
        $policy['conditions'][] = ['X-Amz-Algorithm' => "AWS4-HMAC-SHA256"];
176
 
177
        $jsonPolicy64 = base64_encode(json_encode($policy));
178
        $key = $this->getSigningKey(
179
            $sdt,
180
            $region,
181
            's3',
182
            $credentials->getSecretKey()
183
        );
184
 
185
        return [
186
            'X-Amz-Credential' => $creds,
187
            'X-Amz-Algorithm' => "AWS4-HMAC-SHA256",
188
            'X-Amz-Date' => $ldt,
189
            'Policy'           => $jsonPolicy64,
190
            'X-Amz-Signature'  => bin2hex(
191
                hash_hmac('sha256', $jsonPolicy64, $key, true)
192
            ),
193
        ];
194
    }
195
}