Skip to content
This repository has been archived by the owner on Sep 9, 2019. It is now read-only.

Split IdentityInterface #87

Closed
samdark opened this issue Mar 22, 2017 · 17 comments
Closed

Split IdentityInterface #87

samdark opened this issue Mar 22, 2017 · 17 comments
Assignees

Comments

@samdark
Copy link
Member

samdark commented Mar 22, 2017

What's the problem?

Currently IdentityInterface contains both methods to get an identity and methods which belong to the identity instance. While it is OK in context of Active Record it is an obstacle for implementing repository and entity separated.

What is the expected result?

Being able to separately implement repository which responsibility is to get an instance of identity, and an entity which actually holds the data.

What do you get instead?

A single interface forces us to implement everything in a single class.

Additional info

That's how new interfaces would look like:

interface IdentityInterface
{
    public function getId();
    public function getAuthKey();
    public function validateAuthKey($authKey);
}

interface IndentityRepositoryInterface
{
    public static function findIdentity($id);
    public static function findIdentityByAccessToken($token, $type = null);
}
@samdark samdark self-assigned this Mar 22, 2017
@samdark
Copy link
Member Author

samdark commented Mar 22, 2017

@dynasource, @cebe, @klimov-paul, @SilverFire thoughts?

@klimov-paul
Copy link
Member

Such change seems to be logical, but it make implementation more complicated.

Keep in mind that identity is bound to yii\web\User. There is a single property yii\web\User::$identityClass at the moment. Spliting IdentityInterface into several ones will also make yii\web\User to be more complex.

Current Identity finding methods findIdentity() and findIdentityByAccessToken() are static. Thier notation was inspired by ActiveRecord paradigm.
Extracting IndentityRepositoryInterface with static methods looks odd - those methods should not be static then: identity repository should be an instance, which finds instances of identity. Such change eliminates the ability of usage same ActiveRecord class for IdentityInterface and IndentityRepositoryInterface.

Keeping 'find' methods as static already allows you to create separated implementation for finding - it just need to be encapsulated in those static methods of Identity class.

I am against such change.

@samdark
Copy link
Member Author

samdark commented Mar 22, 2017

Keeping 'find' methods as static already allows you to create separated implementation for finding - it just need to be encapsulated in those static methods of Identity class.

It will be in the same class. Thus not separate.

@klimov-paul
Copy link
Member

It will be in the same class. Thus not separate.

class MyIdentity implements IdentityInterface
{
    // ....

    public static function findIdentity($id)
    {
        return Yii::$app->identityRepository->find($id);
    }
}

@dynasource
Copy link
Member

I'm positive applying the interface-segregation principle. In the end this will result to less complex code which is more flexible and easier to extend.

@samdark
Copy link
Member Author

samdark commented Mar 22, 2017

@klimov-paul right but that's adding intermediate class. Feels hacky. I understand your concerns about complicating yii\web\User though...

@samdark
Copy link
Member Author

samdark commented Mar 22, 2017

I need to actually attempt it to say if it's possible to do it w/o much hassle.

@SilverFire
Copy link
Member

I'm all for it.

@lynicidn
Copy link
Contributor

Разделять надо, т.к. IdentityInterface не должен уметь и находить и быть идентификацией, но репозитори интерфейс не нужен со статикой, его надо вынести в yii\web\User::findIdentity (там есть identityClass)

@lynicidn
Copy link
Contributor

@samdark
Copy link
Member Author

samdark commented Mar 23, 2017

@lynicidn please use English in discussions which are conducted using English. Thanks.

@lynicidn
Copy link
Contributor

@samdark ok, sorry, no problem, wait pr, may be i have wrong opinion

@SamMousa
Copy link
Contributor

SamMousa commented Mar 30, 2017

This makes sense to me as well.
Note that yii\web\User::$identityClass would then become yii\web\User::$identityRepository.
It no longer needs to know the class for an identity.

The parameter would accept an object or a configuration array or closure (as normal for Yii).
A basic ActiveRecordUserRepository could be implemented and provided with core, configuration would then become:

'components' => [
    'user' => [
        'identityRepository' => [
            'modelClass' => 'app\models\User'
        ]

Note that the user component would have a default configuration for its repository which contains:

['class' => 'yii\db\ActiveRecordUserRepository']

@vercotux
Copy link

While at it, would it be possible to add another method to the new IdentityInterface: something that produces a human-readable string of the underlying identity (such as getName(), getUsername() or getLabel())? It makes sense to me at least. What else is an identity if not an abstraction of a person, and as far as I know all humans come with a name.

I guess the reason why it was originally omitted is things like oauth where you don't necessarily obtain a string name? Maybe introduce as separate identity (e.g. HumanIdentityInterface) instead? Just something to consider.

@samdark
Copy link
Member Author

samdark commented Mar 20, 2018

Identity doesn't necessary represent a human. It could be API client or another project or a service.

@samdark samdark transferred this issue from yiisoft/yii2 Nov 19, 2018
@samdark samdark added the type:enhancement Enhancement label Nov 19, 2018
@samdark samdark added the status:under development Someone is working on a pull request. label Aug 9, 2019
@samdark
Copy link
Member Author

samdark commented Aug 9, 2019

yiisoft/yii-web#101

@samdark
Copy link
Member Author

samdark commented Aug 9, 2019

Closing since the implementation has it split.

@samdark samdark closed this as completed Aug 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants