zendframework / zend-expressive-authentication

Authentication middleware for Expressive and PSR-7 applications
BSD 3-Clause "New" or "Revised" License
21 stars 15 forks source link

Unable to extend PdoDatabase user repository implementation #38

Closed marcguyer closed 6 years ago

marcguyer commented 6 years ago

Continued from slack...

I'd like to extend UserRepository\PdoDatabase since the password_verify function does not meet our needs for legacy password hash verification.

Additionally, we have a flag in the db for a user to indicate whether the user is "active". We'd like to return null in the event that the user is not "active".

Code to reproduce the issue

namespace MyNamespace;

use Zend\Expressive\Authentication\UserRepository\PdoDatabase;
use Zend\Expressive\Authentication\UserInterface;

class MyUserRepository extends PdoDatabase
{

    public function authenticate(string $credential, string $password = null): ?UserInterface
    {
        // do anything with $this->config
        var_dump($this->config);
    }
}

Expected results

I expect to be able to access $this->config property (as well as $this->pdo and $this->userFactory) in an extension.

Actual results

Undefined property: MyNamespace\MyUserRepository::$config

ezimuel commented 6 years ago

@marcguyer are you sure you need to extend PdoDatabase instead of proposing a custom UserRepositoryInterface implementation? If you have to change the authenticate() function logic and you have also extra attribute like active it sounds more likely a new repository implementation.

kachar commented 6 years ago

In similar use case we've implemented the UserRepositoryInterface and replaced in the configuration aliases as follows:

use Zend\Expressive\Authentication\UserInterface;
use Zend\Expressive\Authentication\UserRepositoryInterface;
use Zend\Expressive\Authentication\UserRepository\UserTrait;

class ApikeyRepository implements UserRepositoryInterface
{
    use UserTrait;

    public function authenticate(string $credential, string $password = null) : ?UserInterface
    {
    }

    public function getRolesFromUser(string $identity) : array;
    {
    }
}
'aliases' => [
    UserRepositoryInterface::class => ApikeyRepository::class,
],
ezimuel commented 6 years ago

@kachar the idea is good but be careful, we removed UserTrait starting from zend-expressive-authentication v. 0.5.0.

kachar commented 6 years ago

@ezimuel ah, yes indeed, thanks for the insight. Just updated the to latest implementation. In the 1.0.0 version the code is much more simpler and easy to use.

For the sake of the example..

use Zend\Expressive\Authentication\UserInterface;
use Zend\Expressive\Authentication\DefaultUser;
use Zend\Expressive\Authentication\UserRepositoryInterface;

class ApikeyRepository implements UserRepositoryInterface
{
    public function authenticate(string $credential, string $password = null): ?UserInterface
    {
        return new DefaultUser();
    }
}
marcguyer commented 6 years ago

are you sure you need to extend PdoDatabase instead of proposing a custom UserRepositoryInterface implementation?

No, I don't need to extend it, but since I can't, my concrete implementation of UserRepositoryInterface must also redefine the other methods of PdoDatabase. It's not a big deal, just an inconvenience.

In my particular case, it's really not a big deal since I need to implement several interfaces for the user repository anyway.

ezimuel commented 6 years ago

@marcguyer Ok, I'm closing the issue.