Issues (236)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

traits/RegistrationTrait.php (16 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 *  _   __ __ _____ _____ ___  ____  _____
5
 * | | / // // ___//_  _//   ||  __||_   _|
6
 * | |/ // /(__  )  / / / /| || |     | |
7
 * |___//_//____/  /_/ /_/ |_||_|     |_|
8
 * @link https://vistart.me/
9
 * @copyright Copyright (c) 2016 - 2017 vistart
10
 * @license https://vistart.me/license/
11
 */
12
13
namespace rhosocial\base\models\traits;
14
15
use Yii;
16
use yii\base\ModelEvent;
17
use yii\db\IntegrityException;
18
use yii\rbac\ManagerInterface;
19
use yii\rbac\Item;
20
21
/**
22
 * User features concerning registration.
23
 *
24
 * @property-read mixed $authManager
25
 * @property mixed $source
26
 * @property array $sourceRules rules associated with source attribute.
27
 * @version 1.0
28
 * @author vistart <[email protected]>
29
 */
30
trait RegistrationTrait
31
{
32
33
    /**
34
     * @event Event an event that is triggered after user is registered successfully.
35
     */
36
    public static $eventAfterRegister = "afterRegister";
37
38
    /**
39
     * @event Event an event that is triggered before registration.
40
     */
41
    public static $eventBeforeRegister = "beforeRegister";
42
43
    /**
44
     * @event Event an event that is triggered when registration failed.
45
     */
46
    public static $eventRegisterFailed = "registerFailed";
47
48
    /**
49
     * @event Event an event that is triggered after user is deregistered successfully.
50
     */
51
    public static $eventAfterDeregister = "afterDeregister";
52
53
    /**
54
     * @event Event an event that is triggered before deregistration.
55
     */
56
    public static $eventBeforeDeregister = "beforeDeregister";
57
58
    /**
59
     * @event Event an event that is triggered when deregistration failed.
60
     */
61
    public static $eventDeregisterFailed = "deregisterFailed";
62
63
    /**
64
     * @var string name of attribute which store the source. if you don't want to
65
     * record source, please assign false.
66
     */
67
    public $sourceAttribute = 'source';
68
    private $_sourceRules = [];
69
    public static $sourceSelf = '0';
70
71
    /**
72
     * @var string auth manager component id.
73
     */
74
    public $authManagerId = 'authManager';
75
76
    /**
77
     * Get auth manager. If auth manager not configured, Yii::$app->authManager
78
     * will be given.
79
     * @return ManagerInterface
80
     */
81 281
    public function getAuthManager()
82
    {
83 281
        $authManagerId = $this->authManagerId;
84 281
        return empty($authManagerId) ? Yii::$app->authManager : Yii::$app->$authManagerId;
85
    }
86
87
    /**
88
     * Register new user.
89
     * It is equivalent to store the current user and its associated models into
90
     * database synchronously. The registration will be terminated immediately
91
     * if any errors occur in the process, and all the earlier steps succeeded
92
     * are rolled back.
93
     * If auth manager configured, and auth role(s) provided, it(they) will be
94
     * assigned to user after registration.
95
     * If current user is not a new one(isNewRecord = false), the registration
96
     * will be skipped and return false.
97
     * The $eventBeforeRegister will be triggered before registration starts.
98
     * If registration finished, the $eventAfterRegister will be triggered. or
99
     * $eventRegisterFailed will be triggered when any errors occured.
100
     * @param array $associatedModels The models associated with user to be stored synchronously.
101
     * @param string|Item[] $authRoles auth name, auth instance, auth name array or auth instance array.
102
     * @return boolean Whether the registration succeeds or not.
103
     * @throws IntegrityException when inserting user and associated models failed.
104
     */
105 282
    public function register($associatedModels = [], $authRoles = [])
106
    {
107 282
        if (!$this->getIsNewRecord()) {
0 ignored issues
show
It seems like getIsNewRecord() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
108 3
            return false;
109
        }
110 282
        $this->trigger(static::$eventBeforeRegister);
0 ignored issues
show
It seems like trigger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
111 282
        $transaction = $this->getDb()->beginTransaction();
0 ignored issues
show
It seems like getDb() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
112
        try {
113 282
            if (!$this->save()) {
0 ignored issues
show
It seems like save() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
114 1
                throw new IntegrityException('Registration Error(s) Occured: User Save Failed.', $this->getErrors());
0 ignored issues
show
It seems like getErrors() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
115
            }
116 281
            if (($authManager = $this->getAuthManager()) && !empty($authRoles)) {
117
                if (is_string($authRoles) || $authRoles instanceof Item || !is_array($authRoles)) {
118
                    $authRoles = [$authRoles];
119
                }
120
                foreach ($authRoles as $role) {
121
                    if (is_string($role)) {
122
                        $role = $authManager->getRole($role);
123
                    }
124
                    if ($role instanceof Item) {
125
                        $authManager->assign($role, $this->getGUID());
0 ignored issues
show
It seems like getGUID() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
$role of type object<yii\rbac\Item> is not a sub-type of object<yii\rbac\Role>. It seems like you assume a child class of the class yii\rbac\Item to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
126
                    }
127
                }
128
            }
129 281
            if (!empty($associatedModels) && is_array($associatedModels)) {
130 131
                foreach ($associatedModels as $model) {
131 131
                    if (!$model->save()) {
132
                        throw new IntegrityException
133
                        ('Registration Error(s) Occured: Associated Models Save Failed.', $model->getErrors());
134
                    }
135
                }
136
            }
137 281
            $transaction->commit();
138 1
        } catch (\Exception $ex) {
139 1
            $transaction->rollBack();
140 1
            $this->trigger(static::$eventRegisterFailed);
0 ignored issues
show
It seems like trigger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
141 1
            if (YII_DEBUG || YII_ENV !== YII_ENV_PROD) {
142 1
                Yii::error($ex->getMessage(), __METHOD__);
143 1
                return $ex;
144
            }
145
            Yii::warning($ex->getMessage(), __METHOD__);
146
            return false;
147
        }
148 281
        $this->trigger(static::$eventAfterRegister);
0 ignored issues
show
It seems like trigger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
149 281
        return true;
150
    }
151
152
    /**
153
     * Deregister current user itself.
154
     * It is equivalent to delete current user and its associated models. BUT it
155
     * deletes current user ONLY, the associated models will not be deleted
156
     * forwardly. So you should set the foreign key of associated models' table
157
     * referenced from primary key of user table, and their association mode is
158
     * 'on update cascade' and 'on delete cascade'.
159
     * the $eventBeforeDeregister will be triggered before deregistration starts.
160
     * if deregistration finished, the $eventAfterDeregister will be triggered. or
161
     * $eventDeregisterFailed will be triggered when any errors occured.
162
     * @return boolean Whether deregistration succeeds or not.
163
     * @throws IntegrityException when deleting user failed.
164
     */
165 302
    public function deregister()
166
    {
167 302
        if ($this->getIsNewRecord()) {
0 ignored issues
show
It seems like getIsNewRecord() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
168 255
            return false;
169
        }
170 278
        $this->trigger(static::$eventBeforeDeregister);
0 ignored issues
show
It seems like trigger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
171 278
        $transaction = $this->getDb()->beginTransaction();
0 ignored issues
show
It seems like getDb() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
172
        try {
173 278
            $result = $this->delete();
0 ignored issues
show
It seems like delete() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
174 278
            if ($result == 0) {
175
                throw new IntegrityException('User has not existed.');
176
            }
177 278
            if ($result != 1) {
178
                throw new IntegrityException('Deregistration Error(s) Occured.', $this->getErrors());
0 ignored issues
show
It seems like getErrors() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
179
            }
180 278
            $transaction->commit();
181
        } catch (\Exception $ex) {
182
            $transaction->rollBack();
183
            $this->trigger(static::$eventDeregisterFailed);
0 ignored issues
show
It seems like trigger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
184
            if (YII_DEBUG || YII_ENV !== YII_ENV_PROD) {
185
                Yii::error($ex->getMessage(), __METHOD__);
186
                return $ex;
187
            }
188
            Yii::warning($ex->getMessage(), __METHOD__);
189
            return false;
190
        }
191 278
        $this->trigger(static::$eventAfterDeregister);
0 ignored issues
show
It seems like trigger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
192 278
        return $result == 1;
193
    }
194
195
    /**
196
     * Get source.
197
     * @return string
198
     */
199 1
    public function getSource()
200
    {
201 1
        $sourceAttribute = $this->sourceAttribute;
202 1
        return is_string($sourceAttribute) ? $this->$sourceAttribute : null;
203
    }
204
205
    /**
206
     * Set source.
207
     * @param string $source
208
     */
209 306
    public function setSource($source)
210
    {
211 306
        $sourceAttribute = $this->sourceAttribute;
212 306
        return (is_string($sourceAttribute) && !empty($sourceAttribute)) ? $this->$sourceAttribute = $source : null;
213
    }
214
215
    /**
216
     * Get the rules associated with source attribute.
217
     * @return array rules.
218
     */
219 292
    public function getSourceRules()
220
    {
221 292
        if (!is_string($this->sourceAttribute) || empty($this->sourceAttribute)) {
222
            return [];
223
        }
224 292
        if (empty($this->_sourceRules)) {
225 291
            $this->_sourceRules = [
226 291
                [[$this->sourceAttribute], 'required'],
227 291
                [[$this->sourceAttribute], 'string'],
228
            ];
229
        }
230 292
        return $this->_sourceRules;
231
    }
232
233
    /**
234
     * Set the rules associated with source attribute.
235
     * @param array $rules
236
     */
237 1
    public function setSourceRules($rules)
238
    {
239 1
        if (!empty($rules) && is_array($rules)) {
240 1
            $this->_sourceRules = $rules;
241
        }
242 1
    }
243
244
    /**
245
     * Initialize the source attribute with $sourceSelf.
246
     * This method is ONLY used for being triggered by event. DO NOT call,
247
     * override or modify it directly, unless you know the consequences.
248
     * @param ModelEvent $event
249
     */
250 306
    public function onInitSourceAttribute($event)
251
    {
252 306
        $sender = $event->sender;
253
        /* @var $sender static */
254 306
        return $sender->setSource(static::$sourceSelf);
255
    }
256
}
257