generated from Nodarx/template
Initial service DAV module
This commit is contained in:
+236
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\HTTP\Auth;
|
||||
|
||||
use Sabre\HTTP\Request;
|
||||
use Sabre\HTTP\Response;
|
||||
|
||||
class AWSTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var Sabre\HTTP\Response
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* @var Sabre\HTTP\Request
|
||||
*/
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* @var Sabre\HTTP\Auth\AWS
|
||||
*/
|
||||
private $auth;
|
||||
|
||||
public const REALM = 'SabreDAV unittest';
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->response = new Response();
|
||||
$this->request = new Request('GET', '/');
|
||||
$this->auth = new AWS(self::REALM, $this->request, $this->response);
|
||||
}
|
||||
|
||||
public function testNoHeader()
|
||||
{
|
||||
$this->request->setMethod('GET');
|
||||
$result = $this->auth->init();
|
||||
|
||||
$this->assertFalse($result, 'No AWS Authorization header was supplied, so we should have gotten false');
|
||||
$this->assertEquals(AWS::ERR_NOAWSHEADER, $this->auth->errorCode);
|
||||
}
|
||||
|
||||
public function testInvalidAuthorizationHeader()
|
||||
{
|
||||
$this->request->setMethod('GET');
|
||||
$this->request->setHeader('Authorization', 'Invalid Auth Header');
|
||||
|
||||
$this->assertFalse($this->auth->init(), 'The Invalid AWS authorization header');
|
||||
}
|
||||
|
||||
public function testIncorrectContentMD5()
|
||||
{
|
||||
$accessKey = 'accessKey';
|
||||
$secretKey = 'secretKey';
|
||||
|
||||
$this->request->setMethod('GET');
|
||||
$this->request->setHeaders([
|
||||
'Authorization' => "AWS $accessKey:sig",
|
||||
'Content-MD5' => 'garbage',
|
||||
]);
|
||||
$this->request->setUrl('/');
|
||||
|
||||
$this->auth->init();
|
||||
$result = $this->auth->validate($secretKey);
|
||||
|
||||
$this->assertFalse($result);
|
||||
$this->assertEquals(AWS::ERR_MD5CHECKSUMWRONG, $this->auth->errorCode);
|
||||
}
|
||||
|
||||
public function testNoDate()
|
||||
{
|
||||
$accessKey = 'accessKey';
|
||||
$secretKey = 'secretKey';
|
||||
$content = 'thisisthebody';
|
||||
$contentMD5 = base64_encode(md5($content, true));
|
||||
|
||||
$this->request->setMethod('POST');
|
||||
$this->request->setHeaders([
|
||||
'Authorization' => "AWS $accessKey:sig",
|
||||
'Content-MD5' => $contentMD5,
|
||||
]);
|
||||
$this->request->setUrl('/');
|
||||
$this->request->setBody($content);
|
||||
|
||||
$this->auth->init();
|
||||
$result = $this->auth->validate($secretKey);
|
||||
|
||||
$this->assertFalse($result);
|
||||
$this->assertEquals(AWS::ERR_INVALIDDATEFORMAT, $this->auth->errorCode);
|
||||
}
|
||||
|
||||
public function testFutureDate()
|
||||
{
|
||||
$accessKey = 'accessKey';
|
||||
$secretKey = 'secretKey';
|
||||
$content = 'thisisthebody';
|
||||
$contentMD5 = base64_encode(md5($content, true));
|
||||
|
||||
$date = new \DateTime('@'.(time() + (60 * 20)));
|
||||
$date->setTimeZone(new \DateTimeZone('GMT'));
|
||||
$date = $date->format('D, d M Y H:i:s \\G\\M\\T');
|
||||
|
||||
$this->request->setMethod('POST');
|
||||
$this->request->setHeaders([
|
||||
'Authorization' => "AWS $accessKey:sig",
|
||||
'Content-MD5' => $contentMD5,
|
||||
'Date' => $date,
|
||||
]);
|
||||
|
||||
$this->request->setBody($content);
|
||||
|
||||
$this->auth->init();
|
||||
$result = $this->auth->validate($secretKey);
|
||||
|
||||
$this->assertFalse($result);
|
||||
$this->assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode);
|
||||
}
|
||||
|
||||
public function testPastDate()
|
||||
{
|
||||
$accessKey = 'accessKey';
|
||||
$secretKey = 'secretKey';
|
||||
$content = 'thisisthebody';
|
||||
$contentMD5 = base64_encode(md5($content, true));
|
||||
|
||||
$date = new \DateTime('@'.(time() - (60 * 20)));
|
||||
$date->setTimeZone(new \DateTimeZone('GMT'));
|
||||
$date = $date->format('D, d M Y H:i:s \\G\\M\\T');
|
||||
|
||||
$this->request->setMethod('POST');
|
||||
$this->request->setHeaders([
|
||||
'Authorization' => "AWS $accessKey:sig",
|
||||
'Content-MD5' => $contentMD5,
|
||||
'Date' => $date,
|
||||
]);
|
||||
|
||||
$this->request->setBody($content);
|
||||
|
||||
$this->auth->init();
|
||||
$result = $this->auth->validate($secretKey);
|
||||
|
||||
$this->assertFalse($result);
|
||||
$this->assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode);
|
||||
}
|
||||
|
||||
public function testIncorrectSignature()
|
||||
{
|
||||
$accessKey = 'accessKey';
|
||||
$secretKey = 'secretKey';
|
||||
$content = 'thisisthebody';
|
||||
|
||||
$contentMD5 = base64_encode(md5($content, true));
|
||||
|
||||
$date = new \DateTime('now');
|
||||
$date->setTimeZone(new \DateTimeZone('GMT'));
|
||||
$date = $date->format('D, d M Y H:i:s \\G\\M\\T');
|
||||
|
||||
$this->request->setUrl('/');
|
||||
$this->request->setMethod('POST');
|
||||
$this->request->setHeaders([
|
||||
'Authorization' => "AWS $accessKey:sig",
|
||||
'Content-MD5' => $contentMD5,
|
||||
'X-amz-date' => $date,
|
||||
]);
|
||||
$this->request->setBody($content);
|
||||
|
||||
$this->auth->init();
|
||||
$result = $this->auth->validate($secretKey);
|
||||
|
||||
$this->assertFalse($result);
|
||||
$this->assertEquals(AWS::ERR_INVALIDSIGNATURE, $this->auth->errorCode);
|
||||
}
|
||||
|
||||
public function testValidRequest()
|
||||
{
|
||||
$accessKey = 'accessKey';
|
||||
$secretKey = 'secretKey';
|
||||
$content = 'thisisthebody';
|
||||
$contentMD5 = base64_encode(md5($content, true));
|
||||
|
||||
$date = new \DateTime('now');
|
||||
$date->setTimeZone(new \DateTimeZone('GMT'));
|
||||
$date = $date->format('D, d M Y H:i:s \\G\\M\\T');
|
||||
|
||||
$sig = base64_encode($this->hmacsha1($secretKey,
|
||||
"POST\n$contentMD5\n\n$date\nx-amz-date:$date\n/evert"
|
||||
));
|
||||
|
||||
$this->request->setUrl('/evert');
|
||||
$this->request->setMethod('POST');
|
||||
$this->request->setHeaders([
|
||||
'Authorization' => "AWS $accessKey:$sig",
|
||||
'Content-MD5' => $contentMD5,
|
||||
'X-amz-date' => $date,
|
||||
]);
|
||||
|
||||
$this->request->setBody($content);
|
||||
|
||||
$this->auth->init();
|
||||
$result = $this->auth->validate($secretKey);
|
||||
|
||||
$this->assertTrue($result, 'Signature did not validate, got errorcode '.$this->auth->errorCode);
|
||||
$this->assertEquals($accessKey, $this->auth->getAccessKey());
|
||||
}
|
||||
|
||||
public function test401()
|
||||
{
|
||||
$this->auth->requireLogin();
|
||||
$test = preg_match('/^AWS$/', $this->response->getHeader('WWW-Authenticate'), $matches);
|
||||
$this->assertTrue(true == $test, 'The WWW-Authenticate response didn\'t match our pattern');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an HMAC-SHA1 signature.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function hmacsha1($key, $message)
|
||||
{
|
||||
$blocksize = 64;
|
||||
if (strlen($key) > $blocksize) {
|
||||
$key = pack('H*', sha1($key));
|
||||
}
|
||||
$key = str_pad($key, $blocksize, chr(0x00));
|
||||
$ipad = str_repeat(chr(0x36), $blocksize);
|
||||
$opad = str_repeat(chr(0x5C), $blocksize);
|
||||
$hmac = pack('H*', sha1(($key ^ $opad).pack('H*', sha1(($key ^ $ipad).$message))));
|
||||
|
||||
return $hmac;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\HTTP\Auth;
|
||||
|
||||
use Sabre\HTTP\Request;
|
||||
use Sabre\HTTP\Response;
|
||||
|
||||
class BasicTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testGetCredentials()
|
||||
{
|
||||
$request = new Request('GET', '/', [
|
||||
'Authorization' => 'Basic '.base64_encode('user:pass:bla'),
|
||||
]);
|
||||
|
||||
$basic = new Basic('Dagger', $request, new Response());
|
||||
|
||||
$this->assertEquals([
|
||||
'user',
|
||||
'pass:bla',
|
||||
], $basic->getCredentials());
|
||||
}
|
||||
|
||||
public function testGetInvalidCredentialsColonMissing()
|
||||
{
|
||||
$request = new Request('GET', '/', [
|
||||
'Authorization' => 'Basic '.base64_encode('userpass'),
|
||||
]);
|
||||
|
||||
$basic = new Basic('Dagger', $request, new Response());
|
||||
|
||||
$this->assertNull($basic->getCredentials());
|
||||
}
|
||||
|
||||
public function testGetCredentialsNoHeader()
|
||||
{
|
||||
$request = new Request('GET', '/', []);
|
||||
$basic = new Basic('Dagger', $request, new Response());
|
||||
|
||||
$this->assertNull($basic->getCredentials());
|
||||
}
|
||||
|
||||
public function testGetCredentialsNotBasic()
|
||||
{
|
||||
$request = new Request('GET', '/', [
|
||||
'Authorization' => 'QBasic '.base64_encode('user:pass:bla'),
|
||||
]);
|
||||
$basic = new Basic('Dagger', $request, new Response());
|
||||
|
||||
$this->assertNull($basic->getCredentials());
|
||||
}
|
||||
|
||||
public function testRequireLogin()
|
||||
{
|
||||
$response = new Response();
|
||||
$request = new Request('GET', '/');
|
||||
|
||||
$basic = new Basic('Dagger', $request, $response);
|
||||
|
||||
$basic->requireLogin();
|
||||
|
||||
$this->assertEquals('Basic realm="Dagger", charset="UTF-8"', $response->getHeader('WWW-Authenticate'));
|
||||
$this->assertEquals(401, $response->getStatus());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\HTTP\Auth;
|
||||
|
||||
use Sabre\HTTP\Request;
|
||||
use Sabre\HTTP\Response;
|
||||
|
||||
class BearerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testGetToken()
|
||||
{
|
||||
$request = new Request('GET', '/', [
|
||||
'Authorization' => 'Bearer 12345',
|
||||
]);
|
||||
|
||||
$bearer = new Bearer('Dagger', $request, new Response());
|
||||
|
||||
$this->assertEquals(
|
||||
'12345',
|
||||
$bearer->getToken()
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetCredentialsNoHeader()
|
||||
{
|
||||
$request = new Request('GET', '/', []);
|
||||
$bearer = new Bearer('Dagger', $request, new Response());
|
||||
|
||||
$this->assertNull($bearer->getToken());
|
||||
}
|
||||
|
||||
public function testGetCredentialsNotBearer()
|
||||
{
|
||||
$request = new Request('GET', '/', [
|
||||
'Authorization' => 'QBearer 12345',
|
||||
]);
|
||||
$bearer = new Bearer('Dagger', $request, new Response());
|
||||
|
||||
$this->assertNull($bearer->getToken());
|
||||
}
|
||||
|
||||
public function testRequireLogin()
|
||||
{
|
||||
$response = new Response();
|
||||
$request = new Request('GET', '/');
|
||||
$bearer = new Bearer('Dagger', $request, $response);
|
||||
|
||||
$bearer->requireLogin();
|
||||
|
||||
$this->assertEquals('Bearer realm="Dagger"', $response->getHeader('WWW-Authenticate'));
|
||||
$this->assertEquals(401, $response->getStatus());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\HTTP\Auth;
|
||||
|
||||
use Sabre\HTTP\Request;
|
||||
use Sabre\HTTP\Response;
|
||||
|
||||
class DigestTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var Sabre\HTTP\Response
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* request.
|
||||
*
|
||||
* @var Sabre\HTTP\Request
|
||||
*/
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* @var Sabre\HTTP\Auth\Digest
|
||||
*/
|
||||
private $auth;
|
||||
|
||||
public const REALM = 'SabreDAV unittest';
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->response = new Response();
|
||||
$this->request = new Request('GET', '/');
|
||||
$this->auth = new Digest(self::REALM, $this->request, $this->response);
|
||||
}
|
||||
|
||||
public function testDigest()
|
||||
{
|
||||
list($nonce, $opaque) = $this->getServerTokens();
|
||||
|
||||
$username = 'admin';
|
||||
$password = '12345';
|
||||
$nc = '00002';
|
||||
$cnonce = uniqid();
|
||||
|
||||
$digestHash = md5(
|
||||
md5($username.':'.self::REALM.':'.$password).':'.
|
||||
$nonce.':'.
|
||||
$nc.':'.
|
||||
$cnonce.':'.
|
||||
'auth:'.
|
||||
md5('GET:/')
|
||||
);
|
||||
|
||||
$this->request->setMethod('GET');
|
||||
$this->request->setHeader('Authorization', 'Digest username="'.$username.'", realm="'.self::REALM.'", nonce="'.$nonce.'", uri="/", response="'.$digestHash.'", opaque="'.$opaque.'", qop=auth,nc='.$nc.',cnonce="'.$cnonce.'"');
|
||||
|
||||
$this->auth->init();
|
||||
|
||||
$this->assertEquals($username, $this->auth->getUsername());
|
||||
$this->assertEquals(self::REALM, $this->auth->getRealm());
|
||||
$this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1');
|
||||
$this->assertTrue($this->auth->validatePassword($password), 'Authentication is deemed invalid through validatePassword');
|
||||
}
|
||||
|
||||
public function testInvalidDigest()
|
||||
{
|
||||
list($nonce, $opaque) = $this->getServerTokens();
|
||||
|
||||
$username = 'admin';
|
||||
$password = 12345;
|
||||
$nc = '00002';
|
||||
$cnonce = uniqid();
|
||||
|
||||
$digestHash = md5(
|
||||
md5($username.':'.self::REALM.':'.$password).':'.
|
||||
$nonce.':'.
|
||||
$nc.':'.
|
||||
$cnonce.':'.
|
||||
'auth:'.
|
||||
md5('GET:/')
|
||||
);
|
||||
|
||||
$this->request->setMethod('GET');
|
||||
$this->request->setHeader('Authorization', 'Digest username="'.$username.'", realm="'.self::REALM.'", nonce="'.$nonce.'", uri="/", response="'.$digestHash.'", opaque="'.$opaque.'", qop=auth,nc='.$nc.',cnonce="'.$cnonce.'"');
|
||||
|
||||
$this->auth->init();
|
||||
|
||||
$this->assertFalse($this->auth->validateA1(md5($username.':'.self::REALM.':'.($password.'randomness'))), 'Authentication is deemed invalid through validateA1');
|
||||
}
|
||||
|
||||
public function testInvalidDigest2()
|
||||
{
|
||||
$this->request->setMethod('GET');
|
||||
$this->request->setHeader('Authorization', 'basic blablabla');
|
||||
|
||||
$this->auth->init();
|
||||
$this->assertFalse($this->auth->validateA1(md5('user:realm:password')));
|
||||
}
|
||||
|
||||
public function testDigestAuthInt()
|
||||
{
|
||||
$this->auth->setQOP(Digest::QOP_AUTHINT);
|
||||
list($nonce, $opaque) = $this->getServerTokens(Digest::QOP_AUTHINT);
|
||||
|
||||
$username = 'admin';
|
||||
$password = 12345;
|
||||
$nc = '00003';
|
||||
$cnonce = uniqid();
|
||||
|
||||
$digestHash = md5(
|
||||
md5($username.':'.self::REALM.':'.$password).':'.
|
||||
$nonce.':'.
|
||||
$nc.':'.
|
||||
$cnonce.':'.
|
||||
'auth-int:'.
|
||||
md5('POST:/:'.md5('body'))
|
||||
);
|
||||
|
||||
$this->request->setMethod('POST');
|
||||
$this->request->setHeader('Authorization', 'Digest username="'.$username.'", realm="'.self::REALM.'", nonce="'.$nonce.'", uri="/", response="'.$digestHash.'", opaque="'.$opaque.'", qop=auth-int,nc='.$nc.',cnonce="'.$cnonce.'"');
|
||||
$this->request->setBody('body');
|
||||
|
||||
$this->auth->init();
|
||||
|
||||
$this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1');
|
||||
}
|
||||
|
||||
public function testDigestAuthBoth()
|
||||
{
|
||||
$this->auth->setQOP(Digest::QOP_AUTHINT | Digest::QOP_AUTH);
|
||||
list($nonce, $opaque) = $this->getServerTokens(Digest::QOP_AUTHINT | Digest::QOP_AUTH);
|
||||
|
||||
$username = 'admin';
|
||||
$password = 12345;
|
||||
$nc = '00003';
|
||||
$cnonce = uniqid();
|
||||
|
||||
$digestHash = md5(
|
||||
md5($username.':'.self::REALM.':'.$password).':'.
|
||||
$nonce.':'.
|
||||
$nc.':'.
|
||||
$cnonce.':'.
|
||||
'auth-int:'.
|
||||
md5('POST:/:'.md5('body'))
|
||||
);
|
||||
|
||||
$this->request->setMethod('POST');
|
||||
$this->request->setHeader('Authorization', 'Digest username="'.$username.'", realm="'.self::REALM.'", nonce="'.$nonce.'", uri="/", response="'.$digestHash.'", opaque="'.$opaque.'", qop=auth-int,nc='.$nc.',cnonce="'.$cnonce.'"');
|
||||
$this->request->setBody('body');
|
||||
|
||||
$this->auth->init();
|
||||
|
||||
$this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1');
|
||||
}
|
||||
|
||||
private function getServerTokens($qop = Digest::QOP_AUTH)
|
||||
{
|
||||
$this->auth->requireLogin();
|
||||
|
||||
switch ($qop) {
|
||||
case Digest::QOP_AUTH: $qopstr = 'auth';
|
||||
break;
|
||||
case Digest::QOP_AUTHINT: $qopstr = 'auth-int';
|
||||
break;
|
||||
default: $qopstr = 'auth,auth-int';
|
||||
break;
|
||||
}
|
||||
|
||||
$test = preg_match('/Digest realm="'.self::REALM.'",qop="'.$qopstr.'",nonce="([0-9a-f]*)",opaque="([0-9a-f]*)"/',
|
||||
$this->response->getHeader('WWW-Authenticate'), $matches);
|
||||
|
||||
$this->assertTrue(true == $test, 'The WWW-Authenticate response didn\'t match our pattern. We received: '.$this->response->getHeader('WWW-Authenticate'));
|
||||
|
||||
$nonce = $matches[1];
|
||||
$opaque = $matches[2];
|
||||
|
||||
// Reset our environment
|
||||
$this->setUp();
|
||||
$this->auth->setQOP($qop);
|
||||
|
||||
return [$nonce, $opaque];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user