Completed
Push — master ( f9e78a...edb43e )
by Abdelrahman
09:22
created

GenericHandler::emailVerificationSuccess()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * NOTICE OF LICENSE
5
 *
6
 * Part of the Rinvex Fort Package.
7
 *
8
 * This source file is subject to The MIT License (MIT)
9
 * that is bundled with this package in the LICENSE file.
10
 *
11
 * Package: Rinvex Fort Package
12
 * License: The MIT License (MIT)
13
 * Link:    https://rinvex.com
14
 */
15
16
namespace Rinvex\Fort\Handlers;
17
18
use Illuminate\Http\Request;
19
use Rinvex\Fort\Models\Role;
20
use Rinvex\Fort\Models\User;
21
use Illuminate\Auth\Events\Lockout;
22
use Illuminate\Contracts\Events\Dispatcher;
23
use Illuminate\Contracts\Container\Container;
24
use Illuminate\Contracts\Auth\Authenticatable;
25
use Rinvex\Fort\Notifications\RegistrationSuccessNotification;
26
use Rinvex\Fort\Notifications\VerificationSuccessNotification;
27
use Rinvex\Fort\Notifications\AuthenticationLockoutNotification;
28
29
class GenericHandler
30
{
31
    /**
32
     * The container instance.
33
     *
34
     * @var \Illuminate\Container\Container
35
     */
36
    protected $app;
37
38
    /**
39
     * Create a new fort event listener instance.
40
     *
41
     * @param \Illuminate\Contracts\Container\Container $app
42
     */
43
    public function __construct(Container $app)
44
    {
45
        $this->app = $app;
0 ignored issues
show
Documentation Bug introduced by
$app is of type object<Illuminate\Contracts\Container\Container>, but the property $app was declared to be of type object<Illuminate\Container\Container>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
46
    }
47
48
    /**
49
     * Register the listeners for the subscriber.
50
     *
51
     * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher
52
     */
53
    public function subscribe(Dispatcher $dispatcher)
54
    {
55
        $dispatcher->listen(Lockout::class, __CLASS__.'@authLockout');
56
        $dispatcher->listen('rinvex.fort.register.success', __CLASS__.'@registerSuccess');
57
        $dispatcher->listen('rinvex.fort.register.social.success', __CLASS__.'@registerSocialSuccess');
58
        $dispatcher->listen('rinvex.fort.emailverification.success', __CLASS__.'@emailVerificationSuccess');
59
    }
60
61
    /**
62
     * Listen to the authentication lockout event.
63
     *
64
     * @param \Illuminate\Http\Request $request
65
     *
66
     * @return void
67
     */
68
    public function authLockout(Request $request)
69
    {
70
        if (config('rinvex.fort.throttle.lockout_email')) {
71
            $user = get_login_field($loginfield = $request->get('loginfield')) == 'email' ? User::where('email', $loginfield)->first() : User::where('username', $loginfield)->first();
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 183 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
72
73
            $user->notify(new AuthenticationLockoutNotification($request));
74
        }
75
    }
76
77
    /**
78
     * Listen to the register success event.
79
     *
80
     * @param \Illuminate\Contracts\Auth\Authenticatable $user
81
     *
82
     * @return void
83
     */
84
    public function registerSuccess(Authenticatable $user)
85
    {
86
        // Send welcome email
87
        if (config('rinvex.fort.registration.welcome_email')) {
88
            $user->notify(new RegistrationSuccessNotification());
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Illuminate\Contracts\Auth\Authenticatable as the method notify() does only exist in the following implementations of said interface: Rinvex\Fort\Models\User.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
89
        }
90
91
        // Attach default role to the registered user
92
        if ($default = $this->app['config']->get('rinvex.fort.registration.default_role')) {
93
            if ($role = Role::where('slug', $default)->first()) {
94
                $user->roles()->attach($role);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Illuminate\Contracts\Auth\Authenticatable as the method roles() does only exist in the following implementations of said interface: Rinvex\Fort\Models\User.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
95
            }
96
        }
97
    }
98
99
    /**
100
     * Listen to the register social success event.
101
     *
102
     * @param \Illuminate\Contracts\Auth\Authenticatable $user
103
     *
104
     * @return void
105
     */
106
    public function registerSocialSuccess(Authenticatable $user)
107
    {
108
        // Send welcome email
109
        if (config('rinvex.fort.registration.welcome_email')) {
110
            $user->notify(new RegistrationSuccessNotification(true));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Illuminate\Contracts\Auth\Authenticatable as the method notify() does only exist in the following implementations of said interface: Rinvex\Fort\Models\User.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
111
        }
112
113
        // Attach default role to the registered user
114
        if ($default = $this->app['config']->get('rinvex.fort.registration.default_role')) {
115
            if ($role = Role::where('slug', $default)->first()) {
116
                $user->roles()->attach($role);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Illuminate\Contracts\Auth\Authenticatable as the method roles() does only exist in the following implementations of said interface: Rinvex\Fort\Models\User.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
117
            }
118
        }
119
    }
120
121
    /**
122
     * Listen to the email verification success.
123
     *
124
     * @param \Illuminate\Contracts\Auth\Authenticatable $user
125
     *
126
     * @return void
127
     */
128
    public function emailVerificationSuccess(Authenticatable $user)
129
    {
130
        if (config('rinvex.fort.emailverification.success_notification')) {
131
            $user->notify(new VerificationSuccessNotification($user->active));
0 ignored issues
show
Bug introduced by
Accessing active on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface Illuminate\Contracts\Auth\Authenticatable as the method notify() does only exist in the following implementations of said interface: Rinvex\Fort\Models\User.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
132
        }
133
    }
134
}
135