xref: /plugin/davcal/vendor/sabre/http/tests/HTTP/Auth/AWSTest.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\HTTP\Auth;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse Sabre\HTTP\Request;
6*a1a3b679SAndreas Boehleruse Sabre\HTTP\Response;
7*a1a3b679SAndreas Boehler
8*a1a3b679SAndreas Boehlerclass AWSTest extends \PHPUnit_Framework_TestCase {
9*a1a3b679SAndreas Boehler
10*a1a3b679SAndreas Boehler    /**
11*a1a3b679SAndreas Boehler     * @var Sabre\HTTP\Response
12*a1a3b679SAndreas Boehler     */
13*a1a3b679SAndreas Boehler    private $response;
14*a1a3b679SAndreas Boehler
15*a1a3b679SAndreas Boehler    /**
16*a1a3b679SAndreas Boehler     * @var Sabre\HTTP\Request
17*a1a3b679SAndreas Boehler     */
18*a1a3b679SAndreas Boehler    private $request;
19*a1a3b679SAndreas Boehler
20*a1a3b679SAndreas Boehler    /**
21*a1a3b679SAndreas Boehler     * @var Sabre\HTTP\Auth\AWS
22*a1a3b679SAndreas Boehler     */
23*a1a3b679SAndreas Boehler    private $auth;
24*a1a3b679SAndreas Boehler
25*a1a3b679SAndreas Boehler    const REALM = 'SabreDAV unittest';
26*a1a3b679SAndreas Boehler
27*a1a3b679SAndreas Boehler    function setUp() {
28*a1a3b679SAndreas Boehler
29*a1a3b679SAndreas Boehler        $this->response = new Response();
30*a1a3b679SAndreas Boehler        $this->request = new Request();
31*a1a3b679SAndreas Boehler        $this->auth = new AWS(self::REALM, $this->request, $this->response);
32*a1a3b679SAndreas Boehler
33*a1a3b679SAndreas Boehler    }
34*a1a3b679SAndreas Boehler
35*a1a3b679SAndreas Boehler    function testNoHeader() {
36*a1a3b679SAndreas Boehler
37*a1a3b679SAndreas Boehler        $this->request->setMethod('GET');
38*a1a3b679SAndreas Boehler        $result = $this->auth->init();
39*a1a3b679SAndreas Boehler
40*a1a3b679SAndreas Boehler        $this->assertFalse($result, 'No AWS Authorization header was supplied, so we should have gotten false');
41*a1a3b679SAndreas Boehler        $this->assertEquals(AWS::ERR_NOAWSHEADER, $this->auth->errorCode);
42*a1a3b679SAndreas Boehler
43*a1a3b679SAndreas Boehler    }
44*a1a3b679SAndreas Boehler
45*a1a3b679SAndreas Boehler    function testIncorrectContentMD5() {
46*a1a3b679SAndreas Boehler
47*a1a3b679SAndreas Boehler        $accessKey = 'accessKey';
48*a1a3b679SAndreas Boehler        $secretKey = 'secretKey';
49*a1a3b679SAndreas Boehler
50*a1a3b679SAndreas Boehler        $this->request->setMethod('GET');
51*a1a3b679SAndreas Boehler        $this->request->setHeaders([
52*a1a3b679SAndreas Boehler            'Authorization' => "AWS $accessKey:sig",
53*a1a3b679SAndreas Boehler            'Content-MD5'   => 'garbage',
54*a1a3b679SAndreas Boehler        ]);
55*a1a3b679SAndreas Boehler        $this->request->setUrl('/');
56*a1a3b679SAndreas Boehler
57*a1a3b679SAndreas Boehler        $this->auth->init();
58*a1a3b679SAndreas Boehler        $result = $this->auth->validate($secretKey);
59*a1a3b679SAndreas Boehler
60*a1a3b679SAndreas Boehler        $this->assertFalse($result);
61*a1a3b679SAndreas Boehler        $this->assertEquals(AWS::ERR_MD5CHECKSUMWRONG, $this->auth->errorCode);
62*a1a3b679SAndreas Boehler
63*a1a3b679SAndreas Boehler    }
64*a1a3b679SAndreas Boehler
65*a1a3b679SAndreas Boehler    function testNoDate() {
66*a1a3b679SAndreas Boehler
67*a1a3b679SAndreas Boehler        $accessKey = 'accessKey';
68*a1a3b679SAndreas Boehler        $secretKey = 'secretKey';
69*a1a3b679SAndreas Boehler        $content = 'thisisthebody';
70*a1a3b679SAndreas Boehler        $contentMD5 = base64_encode(md5($content, true));
71*a1a3b679SAndreas Boehler
72*a1a3b679SAndreas Boehler        $this->request->setMethod('POST');
73*a1a3b679SAndreas Boehler        $this->request->setHeaders([
74*a1a3b679SAndreas Boehler            'Authorization' => "AWS $accessKey:sig",
75*a1a3b679SAndreas Boehler            'Content-MD5'   => $contentMD5,
76*a1a3b679SAndreas Boehler        ]);
77*a1a3b679SAndreas Boehler        $this->request->setUrl('/');
78*a1a3b679SAndreas Boehler        $this->request->setBody($content);
79*a1a3b679SAndreas Boehler
80*a1a3b679SAndreas Boehler        $this->auth->init();
81*a1a3b679SAndreas Boehler        $result = $this->auth->validate($secretKey);
82*a1a3b679SAndreas Boehler
83*a1a3b679SAndreas Boehler        $this->assertFalse($result);
84*a1a3b679SAndreas Boehler        $this->assertEquals(AWS::ERR_INVALIDDATEFORMAT, $this->auth->errorCode);
85*a1a3b679SAndreas Boehler
86*a1a3b679SAndreas Boehler    }
87*a1a3b679SAndreas Boehler
88*a1a3b679SAndreas Boehler    function testFutureDate() {
89*a1a3b679SAndreas Boehler
90*a1a3b679SAndreas Boehler        $accessKey = 'accessKey';
91*a1a3b679SAndreas Boehler        $secretKey = 'secretKey';
92*a1a3b679SAndreas Boehler        $content = 'thisisthebody';
93*a1a3b679SAndreas Boehler        $contentMD5 = base64_encode(md5($content, true));
94*a1a3b679SAndreas Boehler
95*a1a3b679SAndreas Boehler        $date = new \DateTime('@' . (time() + (60 * 20)));
96*a1a3b679SAndreas Boehler        $date->setTimeZone(new \DateTimeZone('GMT'));
97*a1a3b679SAndreas Boehler        $date = $date->format('D, d M Y H:i:s \\G\\M\\T');
98*a1a3b679SAndreas Boehler
99*a1a3b679SAndreas Boehler        $this->request->setMethod('POST');
100*a1a3b679SAndreas Boehler        $this->request->setHeaders([
101*a1a3b679SAndreas Boehler            'Authorization' => "AWS $accessKey:sig",
102*a1a3b679SAndreas Boehler            'Content-MD5'   => $contentMD5,
103*a1a3b679SAndreas Boehler            'Date'          => $date,
104*a1a3b679SAndreas Boehler        ]);
105*a1a3b679SAndreas Boehler
106*a1a3b679SAndreas Boehler        $this->request->setBody($content);
107*a1a3b679SAndreas Boehler
108*a1a3b679SAndreas Boehler        $this->auth->init();
109*a1a3b679SAndreas Boehler        $result = $this->auth->validate($secretKey);
110*a1a3b679SAndreas Boehler
111*a1a3b679SAndreas Boehler        $this->assertFalse($result);
112*a1a3b679SAndreas Boehler        $this->assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode);
113*a1a3b679SAndreas Boehler
114*a1a3b679SAndreas Boehler    }
115*a1a3b679SAndreas Boehler
116*a1a3b679SAndreas Boehler    function testPastDate() {
117*a1a3b679SAndreas Boehler
118*a1a3b679SAndreas Boehler        $accessKey = 'accessKey';
119*a1a3b679SAndreas Boehler        $secretKey = 'secretKey';
120*a1a3b679SAndreas Boehler        $content = 'thisisthebody';
121*a1a3b679SAndreas Boehler        $contentMD5 = base64_encode(md5($content, true));
122*a1a3b679SAndreas Boehler
123*a1a3b679SAndreas Boehler        $date = new \DateTime('@' . (time() - (60 * 20)));
124*a1a3b679SAndreas Boehler        $date->setTimeZone(new \DateTimeZone('GMT'));
125*a1a3b679SAndreas Boehler        $date = $date->format('D, d M Y H:i:s \\G\\M\\T');
126*a1a3b679SAndreas Boehler
127*a1a3b679SAndreas Boehler        $this->request->setMethod('POST');
128*a1a3b679SAndreas Boehler        $this->request->setHeaders([
129*a1a3b679SAndreas Boehler            'Authorization' => "AWS $accessKey:sig",
130*a1a3b679SAndreas Boehler            'Content-MD5'   => $contentMD5,
131*a1a3b679SAndreas Boehler            'Date'          => $date,
132*a1a3b679SAndreas Boehler        ]);
133*a1a3b679SAndreas Boehler
134*a1a3b679SAndreas Boehler        $this->request->setBody($content);
135*a1a3b679SAndreas Boehler
136*a1a3b679SAndreas Boehler        $this->auth->init();
137*a1a3b679SAndreas Boehler        $result = $this->auth->validate($secretKey);
138*a1a3b679SAndreas Boehler
139*a1a3b679SAndreas Boehler        $this->assertFalse($result);
140*a1a3b679SAndreas Boehler        $this->assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode);
141*a1a3b679SAndreas Boehler
142*a1a3b679SAndreas Boehler    }
143*a1a3b679SAndreas Boehler
144*a1a3b679SAndreas Boehler    function testIncorrectSignature() {
145*a1a3b679SAndreas Boehler
146*a1a3b679SAndreas Boehler        $accessKey = 'accessKey';
147*a1a3b679SAndreas Boehler        $secretKey = 'secretKey';
148*a1a3b679SAndreas Boehler        $content = 'thisisthebody';
149*a1a3b679SAndreas Boehler
150*a1a3b679SAndreas Boehler        $contentMD5 = base64_encode(md5($content, true));
151*a1a3b679SAndreas Boehler
152*a1a3b679SAndreas Boehler        $date = new \DateTime('now');
153*a1a3b679SAndreas Boehler        $date->setTimeZone(new \DateTimeZone('GMT'));
154*a1a3b679SAndreas Boehler        $date = $date->format('D, d M Y H:i:s \\G\\M\\T');
155*a1a3b679SAndreas Boehler
156*a1a3b679SAndreas Boehler        $this->request->setUrl('/');
157*a1a3b679SAndreas Boehler        $this->request->setMethod('POST');
158*a1a3b679SAndreas Boehler        $this->request->setHeaders([
159*a1a3b679SAndreas Boehler            'Authorization' => "AWS $accessKey:sig",
160*a1a3b679SAndreas Boehler            'Content-MD5'   => $contentMD5,
161*a1a3b679SAndreas Boehler            'X-amz-date'    => $date,
162*a1a3b679SAndreas Boehler        ]);
163*a1a3b679SAndreas Boehler        $this->request->setBody($content);
164*a1a3b679SAndreas Boehler
165*a1a3b679SAndreas Boehler        $this->request->setBody($content);
166*a1a3b679SAndreas Boehler
167*a1a3b679SAndreas Boehler        $this->auth->init();
168*a1a3b679SAndreas Boehler        $result = $this->auth->validate($secretKey);
169*a1a3b679SAndreas Boehler
170*a1a3b679SAndreas Boehler        $this->assertFalse($result);
171*a1a3b679SAndreas Boehler        $this->assertEquals(AWS::ERR_INVALIDSIGNATURE, $this->auth->errorCode);
172*a1a3b679SAndreas Boehler
173*a1a3b679SAndreas Boehler    }
174*a1a3b679SAndreas Boehler
175*a1a3b679SAndreas Boehler    function testValidRequest() {
176*a1a3b679SAndreas Boehler
177*a1a3b679SAndreas Boehler        $accessKey = 'accessKey';
178*a1a3b679SAndreas Boehler        $secretKey = 'secretKey';
179*a1a3b679SAndreas Boehler        $content = 'thisisthebody';
180*a1a3b679SAndreas Boehler        $contentMD5 = base64_encode(md5($content, true));
181*a1a3b679SAndreas Boehler
182*a1a3b679SAndreas Boehler        $date = new \DateTime('now');
183*a1a3b679SAndreas Boehler        $date->setTimeZone(new \DateTimeZone('GMT'));
184*a1a3b679SAndreas Boehler        $date = $date->format('D, d M Y H:i:s \\G\\M\\T');
185*a1a3b679SAndreas Boehler
186*a1a3b679SAndreas Boehler
187*a1a3b679SAndreas Boehler        $sig = base64_encode($this->hmacsha1($secretKey,
188*a1a3b679SAndreas Boehler            "POST\n$contentMD5\n\n$date\nx-amz-date:$date\n/evert"
189*a1a3b679SAndreas Boehler        ));
190*a1a3b679SAndreas Boehler
191*a1a3b679SAndreas Boehler        $this->request->setUrl('/evert');
192*a1a3b679SAndreas Boehler        $this->request->setMethod('POST');
193*a1a3b679SAndreas Boehler        $this->request->setHeaders([
194*a1a3b679SAndreas Boehler            'Authorization' => "AWS $accessKey:$sig",
195*a1a3b679SAndreas Boehler            'Content-MD5'   => $contentMD5,
196*a1a3b679SAndreas Boehler            'X-amz-date'    => $date,
197*a1a3b679SAndreas Boehler        ]);
198*a1a3b679SAndreas Boehler
199*a1a3b679SAndreas Boehler        $this->request->setBody($content);
200*a1a3b679SAndreas Boehler
201*a1a3b679SAndreas Boehler        $this->auth->init();
202*a1a3b679SAndreas Boehler        $result = $this->auth->validate($secretKey);
203*a1a3b679SAndreas Boehler
204*a1a3b679SAndreas Boehler        $this->assertTrue($result, 'Signature did not validate, got errorcode ' . $this->auth->errorCode);
205*a1a3b679SAndreas Boehler        $this->assertEquals($accessKey, $this->auth->getAccessKey());
206*a1a3b679SAndreas Boehler
207*a1a3b679SAndreas Boehler    }
208*a1a3b679SAndreas Boehler
209*a1a3b679SAndreas Boehler    function test401() {
210*a1a3b679SAndreas Boehler
211*a1a3b679SAndreas Boehler        $this->auth->requireLogin();
212*a1a3b679SAndreas Boehler        $test = preg_match('/^AWS$/', $this->response->getHeader('WWW-Authenticate'), $matches);
213*a1a3b679SAndreas Boehler        $this->assertTrue($test == true, 'The WWW-Authenticate response didn\'t match our pattern');
214*a1a3b679SAndreas Boehler
215*a1a3b679SAndreas Boehler    }
216*a1a3b679SAndreas Boehler
217*a1a3b679SAndreas Boehler    /**
218*a1a3b679SAndreas Boehler     * Generates an HMAC-SHA1 signature
219*a1a3b679SAndreas Boehler     *
220*a1a3b679SAndreas Boehler     * @param string $key
221*a1a3b679SAndreas Boehler     * @param string $message
222*a1a3b679SAndreas Boehler     * @return string
223*a1a3b679SAndreas Boehler     */
224*a1a3b679SAndreas Boehler    private function hmacsha1($key, $message) {
225*a1a3b679SAndreas Boehler
226*a1a3b679SAndreas Boehler        $blocksize = 64;
227*a1a3b679SAndreas Boehler        if (strlen($key) > $blocksize)
228*a1a3b679SAndreas Boehler            $key = pack('H*', sha1($key));
229*a1a3b679SAndreas Boehler        $key = str_pad($key, $blocksize, chr(0x00));
230*a1a3b679SAndreas Boehler        $ipad = str_repeat(chr(0x36), $blocksize);
231*a1a3b679SAndreas Boehler        $opad = str_repeat(chr(0x5c), $blocksize);
232*a1a3b679SAndreas Boehler        $hmac = pack('H*', sha1(($key ^ $opad) . pack('H*', sha1(($key ^ $ipad) . $message))));
233*a1a3b679SAndreas Boehler        return $hmac;
234*a1a3b679SAndreas Boehler
235*a1a3b679SAndreas Boehler    }
236*a1a3b679SAndreas Boehler
237*a1a3b679SAndreas Boehler}
238