This repository has been archived by the owner on Jan 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request zendframework/zendframework#7310 from kanellov/fea…
…ture/auth_callback_adapter Callback Authentication Adapter
- Loading branch information
113 parents
27f99e1
+
3e34c2c
+
cda46d9
+
dcb9687
+
4fa209d
+
cb65c9a
+
0f058eb
+
88238c7
+
6d3555d
+
bf1b675
+
8918c09
+
1528233
+
a6f33f5
+
aee8483
+
9b1ad90
+
92baf0c
+
782d34b
+
da3b5e2
+
8c5486e
+
08b5959
+
29cb9fc
+
a79175d
+
186ebc9
+
3af3a6e
+
3d17935
+
df05eb8
+
e421e0f
+
00bb39e
+
78b260b
+
a6c654b
+
6dcb060
+
ba14e90
+
dc7d636
+
06375a2
+
53fdaa9
+
80ccc9b
+
fa80520
+
4009aca
+
ad280cb
+
b0d3db4
+
9b28224
+
49a871c
+
4145ab4
+
ff8e603
+
abd0527
+
9dc2f89
+
20317fc
+
da6fd5b
+
1702218
+
487a6e9
+
6051222
+
80b8984
+
a1a90b3
+
1d03186
+
b2e7f7a
+
a185b42
+
533f958
+
cfc5d6f
+
da7d3f0
+
d11e4f8
+
598cfab
+
0955e03
+
8e03b2a
+
c8941af
+
1589b26
+
6e2a869
+
3c9218d
+
fed889d
+
3355853
+
89e0cd8
+
e795f2b
+
16438c0
+
c93bd38
+
ac50ffc
+
a9bc506
+
eef23f4
+
fcda91a
+
056a288
+
607ac6f
+
30f7828
+
9d2a936
+
3747749
+
17325fb
+
4e43d4b
+
0dcaf98
+
3f8e8ac
+
32407f8
+
6e0bb7b
+
c865c5f
+
95c45dc
+
4829cce
+
89ebbef
+
99e35fb
+
7636944
+
0b01291
+
54ce65a
+
387aa24
+
f045e85
+
0c22da5
+
0361731
+
4e9baee
+
c1bb548
+
84412c5
+
7513c64
+
798a19b
+
09479f7
+
67965c9
+
bbb5844
+
ad506d6
+
28ac5df
+
cef7726
+
223cfff
+
81682ab
commit 9ec836b
Showing
2 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?php | ||
/** | ||
* Zend Framework (http://framework.zend.com/) | ||
* | ||
* @link http://github.com/zendframework/zf2 for the canonical source repository | ||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) | ||
* @license http://framework.zend.com/license/new-bsd New BSD License | ||
*/ | ||
|
||
namespace Zend\Authentication\Adapter; | ||
|
||
use Zend\Authentication\Exception\InvalidArgumentException; | ||
use Zend\Authentication\Exception\RuntimeException; | ||
use Zend\Authentication\Result; | ||
|
||
/** | ||
* Authentication Adapter authenticates using callback function. | ||
* The Callback function must return the identity on authentication success | ||
* and false on authentication failure. | ||
*/ | ||
class Callback extends AbstractAdapter | ||
{ | ||
/** | ||
* @var callable | ||
*/ | ||
protected $callback; | ||
|
||
/** | ||
* Class constructor | ||
* | ||
* @param callable $callback the autentication callback | ||
*/ | ||
public function __construct($callback = null) | ||
{ | ||
if (!is_null($callback)) { | ||
$this->setCallback($callback); | ||
} | ||
} | ||
|
||
/** | ||
* Authenticate | ||
* @return \Zend\Authentication\Result the authentication result | ||
* @throws RuntimeException | ||
*/ | ||
public function authenticate() | ||
{ | ||
$callback = $this->getCallback(); | ||
if (is_null($callback)) { | ||
throw new RuntimeException('No callback provided'); | ||
} | ||
try { | ||
$identity = call_user_func($callback, $this->getIdentity(), $this->getCredential()); | ||
if (!$identity) { | ||
return new Result(Result::FAILURE, null, array('Authentication failure')); | ||
} | ||
} catch (\Exception $e) { | ||
return new Result(Result::FAILURE_UNCATEGORIZED, null, array($e->getMessage())); | ||
} | ||
|
||
return new Result(Result::SUCCESS, $identity, array('Authentication success')); | ||
} | ||
|
||
/** | ||
* Gets the value of callback. | ||
* | ||
* @return mixed | ||
*/ | ||
public function getCallback() | ||
{ | ||
return $this->callback; | ||
} | ||
|
||
/** | ||
* Sets the value of callback. | ||
* | ||
* @param mixed $callback the callback | ||
* @throws InvalidArgumentException | ||
* | ||
* @return self | ||
*/ | ||
public function setCallback($callback) | ||
{ | ||
if (!is_callable($callback)) { | ||
throw new InvalidArgumentException('Invalid callback provided'); | ||
} | ||
|
||
$this->callback = $callback; | ||
|
||
return $this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
<?php | ||
/** | ||
* Zend Framework (http://framework.zend.com/) | ||
* | ||
* @link http://github.com/zendframework/zf2 for the canonical source repository | ||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) | ||
* @license http://framework.zend.com/license/new-bsd New BSD License | ||
* @package Zend_Authentication | ||
*/ | ||
|
||
namespace ZendTest\Authentication\Adapter; | ||
|
||
use Zend\Authentication; | ||
use Zend\Authentication\Adapter; | ||
|
||
/** | ||
* @group Zend_Auth | ||
*/ | ||
class CallbackTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* Callback authentication adapter | ||
* | ||
* @var \Zend\Authentication\Adapter\Callback | ||
*/ | ||
protected $_adapter = null; | ||
|
||
/** | ||
* Set up test configuration | ||
*/ | ||
public function setUp() | ||
{ | ||
$this->_setupAuthAdapter(); | ||
} | ||
|
||
public function tearDown() | ||
{ | ||
$this->_adapter = null; | ||
} | ||
|
||
/** | ||
* Ensures expected behavior for an invalid callback | ||
*/ | ||
public function testSetCallbackThrowsException() | ||
{ | ||
$this->setExpectedException( | ||
'Zend\Authentication\Exception\InvalidArgumentException', | ||
'Invalid callback provided' | ||
); | ||
$this->_adapter->setCallback('This is not a valid callback'); | ||
} | ||
|
||
/** | ||
* Ensures setter/getter behaviour for callback | ||
*/ | ||
public function testCallbackSetGetMethods() | ||
{ | ||
$callback = function () { | ||
}; | ||
$this->_adapter->setCallback($callback); | ||
$this->assertEquals($callback, $this->_adapter->getCallback()); | ||
} | ||
|
||
/** | ||
* Ensures constructor sets callback if provided | ||
*/ | ||
public function testClassConstructorSetCallback() | ||
{ | ||
$callback = function () { | ||
}; | ||
$adapter = new Adapter\Callback($callback); | ||
$this->assertEquals($callback, $adapter->getCallback()); | ||
} | ||
|
||
/** | ||
* Ensures authenticate throws Exception if no callback is defined | ||
*/ | ||
public function testAuthenticateThrowsException() | ||
{ | ||
$this->setExpectedException( | ||
'Zend\Authentication\Exception\RuntimeException', | ||
'No callback provided' | ||
); | ||
$this->_adapter->authenticate(); | ||
} | ||
|
||
/** | ||
* Ensures identity and credential are provided as arguments to callback | ||
*/ | ||
public function testAuthenticateProvidesCallbackWithIdentityAndCredentials() | ||
{ | ||
$adapter = $this->_adapter; | ||
$adapter->setIdentity('testIdentity'); | ||
$adapter->setCredential('testCredential'); | ||
$that = $this; | ||
$callback = function ($identity, $credential) use ($that, $adapter) { | ||
$that->assertEquals($identity, $adapter->getIdentity()); | ||
$that->assertEquals($credential, $adapter->getCredential()); | ||
}; | ||
$this->_adapter->setCallback($callback); | ||
$this->_adapter->authenticate(); | ||
} | ||
|
||
/** | ||
* Ensures authentication result is invalid when callback throws exception | ||
*/ | ||
public function testAuthenticateResultIfCallbackThrows() | ||
{ | ||
$adapter = $this->_adapter; | ||
$exception = new \Exception('Callback Exception'); | ||
$callback = function () use ($exception) { | ||
throw $exception; | ||
}; | ||
$adapter->setCallback($callback); | ||
$result = $adapter->authenticate(); | ||
$this->assertFalse($result->isValid()); | ||
$this->assertEquals(Authentication\Result::FAILURE_UNCATEGORIZED, $result->getCode()); | ||
$this->assertEquals(array($exception->getMessage()), $result->getMessages()); | ||
} | ||
|
||
/** | ||
* Ensures authentication result is invalid when callback returns falsy value | ||
*/ | ||
public function testAuthenticateResultIfCallbackReturnsFalsy() | ||
{ | ||
$that = $this; | ||
$adapter = $this->_adapter; | ||
$falsyValues = array(false, null, '', '0', array(), 0, 0.0); | ||
array_map(function ($falsy) use ($that, $adapter) { | ||
$callback = function () use ($falsy) { | ||
return $falsy; | ||
}; | ||
$adapter->setCallback($callback); | ||
$result = $adapter->authenticate(); | ||
$that->assertFalse($result->isValid()); | ||
$that->assertEquals(Authentication\Result::FAILURE, $result->getCode()); | ||
$that->assertEquals(array('Authentication failure'), $result->getMessages()); | ||
}, $falsyValues); | ||
} | ||
|
||
/** | ||
* Ensures authentication result is valid when callback returns truthy value | ||
*/ | ||
public function testAuthenticateResultIfCallbackReturnsIdentity() | ||
{ | ||
$adapter = $this->_adapter; | ||
$callback = function () { | ||
return 'identity'; | ||
}; | ||
$adapter->setCallback($callback); | ||
$result = $adapter->authenticate(); | ||
$this->assertTrue($result->isValid()); | ||
$this->assertEquals(Authentication\Result::SUCCESS, $result->getCode()); | ||
$this->assertEquals('identity', $result->getIdentity()); | ||
$this->assertEquals(array('Authentication success'), $result->getMessages()); | ||
} | ||
|
||
protected function _setupAuthAdapter() | ||
{ | ||
$this->_adapter = new Adapter\Callback(); | ||
} | ||
} |