Passed
Push — master ( caab97...76a5ed )
by Rutger
12:41
created

User::validatePassword()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace sample\models;
4
5
use League\OAuth2\Server\Entities\ClientEntityInterface;
6
use rhertogh\Yii2Oauth2Server\interfaces\models\Oauth2OidcUserInterface;
7
use rhertogh\Yii2Oauth2Server\interfaces\models\Oauth2PasswordGrantUserInterface;
8
use rhertogh\Yii2Oauth2Server\interfaces\models\Oauth2UserInterface;
9
use rhertogh\Yii2Oauth2Server\Oauth2Module;
10
use rhertogh\Yii2Oauth2Server\traits\models\Oauth2OidcUserIdentityTrait;
11
use rhertogh\Yii2Oauth2Server\traits\models\Oauth2UserIdentityTrait;
12
use Yii;
13
use yii\db\ActiveQuery;
14
use yii\db\ActiveRecord;
15
use yii\web\IdentityInterface;
16
17
/**
18
 * @property int $id
19
 * @property string $username
20
 * @property string $password_hash
21
 * @property string $email_address
22
 * @property string $latest_authenticated_at
23
 * @property boolean $enabled
24
 * @property int $created_at
25
 * @property int $updated_at
26
 *
27
 * @property-read User[] $linkedIdentities
28
 */
29
class User extends ActiveRecord implements
30
    IdentityInterface,
31
    Oauth2UserInterface,
32
    Oauth2OidcUserInterface, # Optional interface, only required when OpenID Connect support is enabled
33
    Oauth2PasswordGrantUserInterface # Optional interface, only required when `password` grant type is used
34
{
35
    // phpcs:disable Generic.Files.LineLength.TooLong, PSR12.Traits.UseDeclaration.NoBlankLineAfterUse -- Sample documentation
36
    use Oauth2UserIdentityTrait; # Helper trait for Oauth2UserInterface
37
    use Oauth2OidcUserIdentityTrait; # Optional helper trait for Oauth2OidcUserInterface, only required when OpenID Connect support is enabled
38
    // phpcs:enable Generic.Files.LineLength.TooLong, PSR12.Traits.UseDeclaration.NoBlankLineAfterUse
39
40
    # region IdentityInterface (Default Yii interface)
41
    /**
42
     * @inheritDoc
43
     */
44
    public static function findIdentity($id)
45
    {
46
        return static::findOne(['id' => $id]);
47
    }
48
49
    /**
50
     * @inheritDoc
51
     */
52
    public function getId()
53
    {
54
        return $this->id;
55
    }
56
57
    /**
58
     * @inheritDoc
59
     */
60
    public function getAuthKey()
61
    {
62
        // TODO: Implement getAuthKey() method.
63
    }
64
65
    /**
66
     * @inheritDoc
67
     */
68
    public function validateAuthKey($authKey)
69
    {
70
        // TODO: Implement getAuthKey() method.
71
    }
72
    # endregion IdentityInterface
73
74
    # region Oauth2UserInterface
75
    # Methods are implemented via Oauth2UserIdentityTrait
76
    # endregion Oauth2UserInterface
77
78
    # region Oauth2OidcUserInterface
79
    /**
80
     * @inheritDoc
81
     */
82
    public function getLatestAuthenticatedAt()
83
    {
84
        return new \DateTimeImmutable('@' . ($this->latest_authenticated_at ?? $this->created_at));
85
    }
86
87
    # Other methods are implemented via Oauth2OidcUserIdentityTrait
88
    # endregion Oauth2OidcUserInterface
89
90
    # region Oauth2PasswordGrantUserInterface (Optional interface, only required when `password` grant type is used)
91
    /**
92
     * @inheritDoc
93
     */
94
    public static function findByUsername($username)
95
    {
96
        return static::findOne(['username' => $username]);
97
    }
98
99
    /**
100
     * @inheritDoc
101
     */
102
    public function validatePassword($password)
103
    {
104
        return Yii::$app->security->validatePassword($password, $this->password_hash);
105
    }
106
    # endregion Oauth2PasswordGrantUserInterface
107
108
    # region Not Oauth specific but can be used with Oauth Scopes to hide/expose certain fields
109
    /**
110
     * @inheritDoc
111
     */
112
    public function fields()
113
    {
114
        /** @var Oauth2Module $oauth2Module */
115
        $oauth2Module = Yii::$app->getModule('oauth2');
116
        return [
117
            'id',
118
            ...($oauth2Module->requestHasScope('user.username.read') ? ['username'] : []),
119
            ...($oauth2Module->requestHasScope('user.email_address.read') ? ['email_address'] : []),
120
        ];
121
    }
122
    # endregion
123
124
    # region Application specific implementation for user identity selection
125
    /**
126
     * Checks if this user has another identity linked to their account
127
     * @param int $id
128
     * @return bool
129
     */
130
    public function hasLinkedIdentity($id)
131
    {
132
        if ($id == $this->id) {
133
            return true;
134
        }
135
        return $this->getUserIdentityLinks()
136
            ->andWhere(['linked_user_id' => $id])
137
            ->exists();
138
    }
139
140
    /**
141
     * Get an identity that is linked to this account
142
     * @param $id
143
     * @return User|null
144
     */
145
    public function getLinkedIdentity($id)
146
    {
147
        if ($id == $this->id) {
148
            return $this;
149
        }
150
151
        return $this->getLinkedIdentities()
152
            ->andWhere(['id' => $id])
153
            ->one();
154
    }
155
156
    /**
157
     * Get all available identities for this account (including itself)
158
     * @return User[]
159
     */
160
    public function getAvailableIdentities()
161
    {
162
        return [$this, ...$this->linkedIdentities];
163
    }
164
    # endregion
165
166
    # region ActiveRecord Relations
167
    /**
168
     * @return ActiveQuery
169
     */
170
    public function getUserIdentityLinks()
171
    {
172
        return $this->hasMany(UserIdentityLink::class, ['user_id' => 'id']);
173
    }
174
175
    /**
176
     * @return ActiveQuery
177
     */
178
    public function getLinkedIdentities()
179
    {
180
        return $this->hasMany(User::class, ['id' => 'linked_user_id'])->via('userIdentityLinks');
181
    }
182
    # endregion
183
}
184