Passed
Push — master ( 3c190c...2857c2 )
by Robbie
03:26
created

LDAPChangePasswordHandler::doChangePassword()   D

Complexity

Conditions 13
Paths 54

Size

Total Lines 119
Code Lines 70

Duplication

Lines 25
Ratio 21.01 %

Importance

Changes 0
Metric Value
dl 25
loc 119
rs 4.9922
c 0
b 0
f 0
cc 13
eloc 70
nc 54
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SilverStripe\LDAP\Authenticators;
4
5
use Exception;
6
use Psr\Log\LoggerInterface;
7
use SilverStripe\Control\Director;
8
use SilverStripe\Control\HTTP;
9
use SilverStripe\Control\HTTPResponse;
10
use SilverStripe\Core\Injector\Injector;
11
use SilverStripe\LDAP\Forms\LDAPChangePasswordForm;
12
use SilverStripe\LDAP\Services\LDAPService;
13
use SilverStripe\ORM\ValidationResult;
14
use SilverStripe\Security\Member;
15
use SilverStripe\Security\MemberAuthenticator\ChangePasswordHandler;
16
use SilverStripe\Security\Security;
17
18
class LDAPChangePasswordHandler extends ChangePasswordHandler
19
{
20
    /**
21
     * @var array Allowed Actions
22
     */
23
    private static $allowed_actions = [
0 ignored issues
show
Unused Code introduced by
The property $allowed_actions is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
24
        'changepassword',
25
        'changePasswordForm',
26
    ];
27
28
    /**
29
     * Factory method for the lost password form
30
     *
31
     * @return LDAPChangePasswordForm Returns the lost password form
32
     */
33
    public function changePasswordForm()
34
    {
35
        return LDAPChangePasswordForm::create($this, 'ChangePasswordForm');
0 ignored issues
show
Bug introduced by
'ChangePasswordForm' of type string is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

35
        return LDAPChangePasswordForm::create($this, /** @scrutinizer ignore-type */ 'ChangePasswordForm');
Loading history...
Bug introduced by
$this of type SilverStripe\LDAP\Authen...APChangePasswordHandler is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

35
        return LDAPChangePasswordForm::create(/** @scrutinizer ignore-type */ $this, 'ChangePasswordForm');
Loading history...
36
    }
37
38
    /**
39
     * Change the password
40
     *
41
     * @param array $data The user submitted data
42
     * @param LDAPChangePasswordForm $form
43
     * @return HTTPResponse
44
     */
45
    public function doChangePassword(array $data, $form)
46
    {
47
        /**
48
         * @var LDAPService $service
49
         */
50
        $service = Injector::inst()->get(LDAPService::class);
51
        $member = Security::getCurrentUser();
52
        if ($member) {
53
            try {
54
                $userData = $service->getUserByGUID($member->GUID);
55
            } catch (Exception $e) {
56
                Injector::inst()->get(LoggerInterface::class)->error($e->getMessage());
57
58
                $form->clearMessage();
59
                $form->sessionMessage(
60
                    _t(
61
                        __CLASS__ . '.NOUSER',
62
                        'Your account hasn\'t been setup properly, please contact an administrator.'
63
                    ),
64
                    'bad'
65
                );
66
                return $form->getController()->redirect($form->getController()->Link('changepassword'));
67
            }
68
            $loginResult = $service->authenticate($userData['samaccountname'], $data['OldPassword']);
69 View Code Duplication
            if (!$loginResult['success']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70
                $form->clearMessage();
71
                $form->sessionMessage(
72
                    _t(
73
                        'SilverStripe\\Security\\Member.ERRORPASSWORDNOTMATCH',
74
                        'Your current password does not match, please try again'
75
                    ),
76
                    'bad'
77
                );
78
                // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
79
                return $form->getController()->redirect($form->getController()->Link('changepassword'));
80
            }
81
        }
82
83
        if (!$member) {
84
            if ($this->getRequest()->getSession()->get('AutoLoginHash')) {
85
                $member = Member::member_from_autologinhash($this->getRequest()->getSession()->get('AutoLoginHash'));
0 ignored issues
show
Bug introduced by
It seems like $this->getRequest()->get...)->get('AutoLoginHash') can also be of type array; however, parameter $hash of SilverStripe\Security\Me...er_from_autologinhash() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

85
                $member = Member::member_from_autologinhash(/** @scrutinizer ignore-type */ $this->getRequest()->getSession()->get('AutoLoginHash'));
Loading history...
86
            }
87
88
            // The user is not logged in and no valid auto login hash is available
89
            if (!$member) {
90
                $this->getRequest()->getSession()->clear('AutoLoginHash');
91
                return $form->getController()->redirect($form->getController()->Link('login'));
92
            }
93
        }
94
95
        // Check the new password
96
        if (empty($data['NewPassword1'])) {
97
            $form->clearMessage();
98
            $form->sessionMessage(
99
                _t(
100
                    'SilverStripe\\Security\\Member.EMPTYNEWPASSWORD',
101
                    "The new password can't be empty, please try again"
102
                ),
103
                'bad'
104
            );
105
106
            // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
107
            return $form->getController()->redirect($form->getController()->Link('changepassword'));
108
        } elseif ($data['NewPassword1'] == $data['NewPassword2']) {
109
            // Providing OldPassword to perform password _change_ operation. This will respect the
110
            // password history policy. Unfortunately we cannot support password history policy on password _reset_
111
            // at the moment, which means it will not be enforced on SilverStripe-driven email password reset.
112
            $oldPassword = !empty($data['OldPassword']) ? $data['OldPassword']: null;
113
114
            /** @var ValidationResult $validationResult */
115
            $validationResult = $service->setPassword($member, $data['NewPassword1'], $oldPassword);
116
117
            // try to catch connection and other errors that the ldap service can through
118
            if ($validationResult->isValid()) {
119
                Security::setCurrentUser($member);
120
121
                $this->getRequest()->getSession()->clear('AutoLoginHash');
122
123
                // Clear locked out status
124
                $member->LockedOutUntil = null;
125
                $member->FailedLoginCount = null;
126
                $member->write();
127
128
                if (!empty($this->getRequest()->requestVar('BackURL'))
129
                    // absolute redirection URLs may cause spoofing
130
                    && Director::is_site_url($this->getRequest()->requestVar('BackURL'))
131
                ) {
132
                    $url = Director::absoluteURL($this->getRequest()->requestVar('BackURL'));
133
                    return $form->getController()->redirect($url);
134
                } else {
135
                    // Redirect to default location - the login form saying "You are logged in as..."
136
                    $redirectURL = HTTP::setGetVar(
137
                        'BackURL',
138
                        Director::absoluteBaseURL(),
139
                        $form->getController()->Link('login')
140
                    );
141
                    return $form->getController()->redirect($redirectURL);
142
                }
143
            } else {
144
                $form->clearMessage();
145
                $messages = implode('. ', array_column($validationResult->getMessages(), 'message'));
146
                $form->sessionMessage($messages, 'bad');
147
                // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
148
                return $form->getController()->redirect($form->getController()->Link('changepassword'));
149
            }
150 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
151
            $form->clearMessage();
152
            $form->sessionMessage(
153
                _t(
154
                    'SilverStripe\\Security\\Member.ERRORNEWPASSWORD',
155
                    'You have entered your new password differently, try again'
156
                ),
157
                'bad'
158
            );
159
160
            // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
161
            return $form->getController()->redirect($form->getController()->Link('changepassword'));
162
        }
163
    }
164
}
165