Permalink
Browse files

Merge pull request #95 from superdweebie/storageFactory

Add authentication storage factory
  • Loading branch information...
2 parents 2dfa7fa + 5450968 commit 185aa3b8d8dcc58363fbd2b1af43892f6bb79869 @Ocramius Ocramius committed Oct 4, 2012
View
@@ -12,7 +12,7 @@ In order to authenticate a user (or anything else) against Doctrine, the followi
#### Authentication factory
-To make your life easier, DoctrineModule provides an Authentication factory through the ``DoctrineModule\Options\Authentication`` class.
+To make your life easier, DoctrineModule provides an Authentication factory through the ``DoctrineModule\Options\Authentication`` class.
The first task is to configure the Authentication by adding the ``authentication`` key to the ``doctrine`` key in your config file (we assume here that the entity we want to authentication is simply called `Application\Entity\User`):
@@ -80,23 +80,18 @@ class Module
'factories' => array(
'Zend\Authentication\AuthenticationService' => function($serviceManager) {
// If you are using DoctrineORMModule:
- $authenticationAdapter = $serviceManager->get('doctrine.authenticationadapter.orm_default');
- $authenticationStorage = $serviceManager->get('doctrine.authenticationstorage.orm_default');
-
+ return $serviceManager->get('doctrine.authenticationservice.orm_default');
+
// If you are using DoctrineODMModule:
- $authenticationAdapter = $serviceManager->get('doctrine.authenticationadapter.odm_default');
- $authenticationStorage = $serviceManager->get('doctrine.authenticationstorage.odm_default');
-
- // Return the fully constructed AuthenticationService
- return new AuthenticationService($authenticationStorage, $authenticationAdapter);
+ return $serviceManager->get('doctrine.authenticationservice.odm_default');
}
)
);
}
}
```
-Please note that Iam using here a ``Zend\Authentication\AuthenticationService`` name, but it can be anything else (``my_auth_service``…).
+Please note that Iam using here a ``Zend\Authentication\AuthenticationService`` name, but it can be anything else (``my_auth_service``…). However, using the name ``Zend\Authentication\AuthenticationService`` will allow it to be recognised by the ZF2 view helper.
#### Using the AuthenticationService
@@ -126,175 +121,53 @@ public function loginAction()
));
}
```
-
+
Of course, doing this in the controller is not the best practice, and you'd better move that kind of logic to a service layer. But this is how it works.
Note that when the authentication is valid, we first get the identity :
```php
$identity = $authenticationResult->getIdentity();
```
-
+
This will return the full entity (in our case, an `Application\Entity\User` instance). However, storing a full entity in session is not a recommended practice. That's why, when writing the identity :
```php
$authService->getStorage()->write($identity);
```
-
+
The storage automatically extracts ONLY the identifier values and only store this in session (this avoid to store in session a serialized entity, which is a bad practice). Later, when you want to retrieve the logged user :
```php
$authenticationService = $this->serviceLocator()->get('Zend\Authentication\AuthenticationService');
$loggedUser = $authenticationService->getIdentity();
```
-
+
The authentication storage will automatically handle the conversion from saved data to managed entity and the opposite. It will avoid serializing entities since that is a strongly discouraged practice.
#### View helper and controller helper
-You may also need to know if there is an authenticated user within your other controllers or in views. Here's examples of a controller plugin and a view helper you may use.
-
-Here is a sample code that shows you the Controller Plugin :
-
-```php
-<?php
-
-namespace Application\Controller\Plugin;
-
-use Zend\Authentication\AuthenticationService;
-use Zend\Mvc\Controller\Plugin\AbstractPlugin;
-
-class UserIdentity extends AbstractPlugin
-{
- /**
- * @var AuthenticationService
- */
- protected $authenticationService;
-
- /**
- * Constructor
- *
- * @param AuthenticationService $authenticationService
- */
- public function __construct(AuthenticationService $authenticationService)
- {
- $this->authenticationService = $authenticationService;
- }
-
- /**
- * @return \Application\Entity\User
- */
- public function __invoke()
- {
- if ($this->authenticationService->hasIdentity()) {
- return $this->authenticationService->getIdentity();
- }
-
- return null;
- }
-}
-```
-
-The View Helper is very similar :
-
-```php
-<?php
-
-namespace Application\View\Helper;
-
-use Zend\Authentication\AuthenticationService;
-use Zend\View\Helper\AbstractHelper;
-
-class UserIdentity extends AbstractHelper
-{
- /**
- * @var AuthenticationService
- */
- protected $authenticationService;
-
- /**
- * Constructor
- *
- * @param AuthenticationService $authenticationService
- */
- public function __construct(AuthenticationService $authenticationService)
- {
- $this->authenticationService = $authenticationService;
- }
-
- /**
- * @return \Application\Entity\User
- */
- public function __invoke()
- {
- if ($this->authenticationService->hasIdentity()) {
- return $this->authenticationService->getIdentity();
- }
-
- return null;
- }
-}
-```
-
-You now need to tell the ServiceManager how to find the Controller Plugin and the View Helper. Add the following code in your Module.php class :
-
-```php
-/**
- * @return array
- */
-public function getViewHelperConfig()
-{
- return array(
- 'factories' => array(
- 'userIdentity' => function ($serviceManager) {
- $authenticationService = $serviceManager->getServiceLocator()
- ->get('Zend\Authentication\AuthenticationService');
-
- return new \Application\View\Helper\UserIdentity($authenticationService);
- }
- )
- );
-}
-
-/**
- * @return array
- */
-public function getControllerPluginConfig()
-{
- return array(
- 'factories' => array(
- 'userIdentity' => function ($serviceManager) {
- $authenticationService = $serviceManager->getServiceLocator()
- ->get('Zend\Authentication\AuthenticationService');
-
- return new \Application\Controller\Plugin\UserIdentity($authenticationService);
- }
- )
- );
-}
-```
-
-This is very simple code. This code automatically handles the dependencies with the AuthenticationService.
+You may also need to know if there is an authenticated user within your other controllers or in views. ZF2 provides a controller plugin and a view helper you may use.
Here is how you use it in your controller :
```php
public function testAction()
{
- if ($user = $this->userIdentity()) {
+ if ($user = $this->identity()) {
// someone is logged !
} else {
// not logged in
}
}
```
-
+
And in your view :
```php
<?php
- if ($user = $this->userIdentity()) {
- echo 'Logged in as ' . $this->escapeHtml($user->getLogin());
+ if ($user = $this->identity()) {
+ echo 'Logged in as ' . $this->escapeHtml($user->getUsername());
} else {
echo 'Not logged in';
}
@@ -19,7 +19,7 @@
namespace DoctrineModule\Authentication\Adapter;
-use DoctrineModule\Options\AuthenticationAdapter as AuthenticationOptions;
+use DoctrineModule\Options\Authentication as AuthenticationOptions;
use Zend\Authentication\Adapter\AdapterInterface;
use Zend\Authentication\Adapter\Exception;
use Zend\Authentication\Result as AuthenticationResult;
@@ -19,8 +19,7 @@
namespace DoctrineModule\Authentication\Storage;
-use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
-use Doctrine\Common\Persistence\ObjectRepository as DoctrineRepository;
+use DoctrineModule\Options\Authentication as AuthenticationOptions;
use Zend\Authentication\Storage\StorageInterface;
/**
@@ -33,42 +32,43 @@
*/
class ObjectRepository implements StorageInterface
{
- /**
- * @var DoctrineRepository
- */
- protected $objectRepository;
/**
- * Metadata factory
*
- * @var ClassMetadataFactory
+ * @var \DoctrineModule\Options\Authentication
*/
- protected $metadataFactory;
+ protected $options;
/**
- * @var StorageInterface
+ * @param array | \DoctrineModule\Options\Authentication $options
+ * @return ObjectRepository
*/
- protected $storage;
-
+ public function setOptions($options)
+ {
+ if (!$options instanceof AuthenticationOptions) {
+ $options = new AuthenticationOptions($options);
+ }
+ $this->options = $options;
+ return $this;
+ }
+
/**
- * @param DoctrineRepository $objectRepository
- * @param ClassMetadataFactory $metadataFactory
- * @param StorageInterface $storage
+ * Constructor
+ *
+ * @param array | \DoctrineModule\Options\Authentication $options
*/
- public function __construct(DoctrineRepository $objectRepository, ClassMetadataFactory $metadataFactory, StorageInterface $storage)
+ public function __construct($options = array())
{
- $this->objectRepository = $objectRepository;
- $this->storage = $storage;
- $this->metadataFactory = $metadataFactory;
+ $this->setOptions($options);
}
/**
* @return bool
*/
public function isEmpty()
{
- return $this->storage->isEmpty();
+ return $this->options->getStorage()->isEmpty();
}
/**
@@ -79,30 +79,40 @@ public function isEmpty()
*/
public function read()
{
- if (($identity = $this->storage->read())) {
- return $this->objectRepository->find($identity);
+ if (($identity = $this->options->getStorage()->read())) {
+ return $this->options->getObjectRepository()->find($identity);
}
return null;
}
/**
+ * Will return the key of the identity. If only the key is needed, this avoids an
+ * unnessisary db call
+ *
+ * @return mixed
+ */
+ public function readKeyOnly(){
+ return $identity = $this->options->getStorage()->read();
+ }
+
+ /**
* @param object $identity
* @return void
*/
public function write($identity)
{
- $metadataInfo = $this->metadataFactory->getMetadataFor(get_class($identity));
+ $metadataInfo = $this->options->getClassMetadata();
$identifierValues = $metadataInfo->getIdentifierValues($identity);
- $this->storage->write($identifierValues);
+ $this->options->getStorage()->write($identifierValues);
}
/**
* @return void
*/
public function clear()
{
- $this->storage->clear();
+ $this->options->getStorage()->clear();
}
}
Oops, something went wrong.

0 comments on commit 185aa3b

Please sign in to comment.