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